#[cfg(target_arch = "wasm32")]
wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser);
use runmat_builtins::{Tensor, Value};
use runmat_runtime::{elementwise_pow, power};
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_scalar_power() {
let result = power(&Value::Num(2.0), &Value::Num(3.0)).unwrap();
assert_eq!(result, Value::Num(8.0));
let result = power(
&Value::Int(runmat_builtins::IntValue::I32(3)),
&Value::Int(runmat_builtins::IntValue::I32(2)),
)
.unwrap();
assert_eq!(result, Value::Num(9.0));
let result = power(
&Value::Num(2.5),
&Value::Int(runmat_builtins::IntValue::I32(2)),
)
.unwrap();
assert_eq!(result, Value::Num(6.25));
let result = power(&Value::Complex(2.0, 0.0), &Value::Num(3.0)).unwrap();
if let Value::Complex(re, im) = result {
assert!((re - 8.0).abs() < 1e-12 && im.abs() < 1e-12);
} else {
panic!();
}
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_matrix_power() {
let matrix = Tensor::new_2d(vec![2.0, 3.0, 4.0, 5.0], 2, 2).unwrap();
let result = power(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(0)),
)
.unwrap();
if let Value::Tensor(result_matrix) = result {
assert_eq!(result_matrix.data, vec![1.0, 0.0, 0.0, 1.0]);
assert_eq!(result_matrix.rows(), 2);
assert_eq!(result_matrix.cols(), 2);
} else {
panic!("Expected matrix result");
}
let matrix = Tensor::new_2d(vec![2.0, 3.0, 4.0, 5.0], 2, 2).unwrap();
let expected = matrix.clone();
let result = power(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(1)),
)
.unwrap();
if let Value::Tensor(result_matrix) = result {
assert_eq!(result_matrix.data, expected.data);
assert_eq!(result_matrix.rows(), expected.rows());
assert_eq!(result_matrix.cols(), expected.cols());
} else {
panic!("Expected matrix result");
}
let matrix = Tensor::new_2d(vec![1.0, 2.0, 3.0, 4.0], 2, 2).unwrap();
let result = power(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(2)),
)
.unwrap();
if let Value::Tensor(result_matrix) = result {
assert_eq!(result_matrix.data, vec![7.0, 10.0, 15.0, 22.0]);
} else {
panic!("Expected matrix result");
}
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_matrix_power_float_integer() {
let matrix = Tensor::new_2d(vec![2.0, 1.0, 1.0, 2.0], 2, 2).unwrap();
let result = power(&Value::Tensor(matrix), &Value::Num(2.0)).unwrap();
if let Value::Tensor(result_matrix) = result {
assert_eq!(result_matrix.data, vec![5.0, 4.0, 4.0, 5.0]);
} else {
panic!("Expected matrix result");
}
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_matrix_power_non_integer_fails() {
let matrix = Tensor::new_2d(vec![1.0, 2.0, 3.0, 4.0], 2, 2).unwrap();
let result = power(&Value::Tensor(matrix), &Value::Num(2.5));
assert!(result.is_err());
assert!(result.unwrap_err().contains("integer exponent"));
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_matrix_power_non_square_fails() {
let matrix = Tensor::new_2d(vec![1.0, 2.0, 3.0, 4.0, 5.0, 6.0], 2, 3).unwrap(); let result = power(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(2)),
);
assert!(result.is_err());
assert!(result.unwrap_err().contains("square"));
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_matrix_power_negative_fails() {
let matrix = Tensor::new_2d(vec![1.0, 2.0, 3.0, 4.0], 2, 2).unwrap();
let result = power(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(-1)),
);
assert!(result.is_err());
assert!(result.unwrap_err().contains("Negative"));
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_elementwise_vs_matrix_power() {
let matrix = Tensor::new_2d(vec![2.0, 3.0, 4.0, 5.0], 2, 2).unwrap();
let matrix_power_result = power(
&Value::Tensor(matrix.clone()),
&Value::Int(runmat_builtins::IntValue::I32(2)),
)
.unwrap();
let elementwise_result = elementwise_pow(
&Value::Tensor(matrix),
&Value::Int(runmat_builtins::IntValue::I32(2)),
)
.unwrap();
if let (Value::Tensor(m1), Value::Tensor(m2)) = (matrix_power_result, elementwise_result) {
assert_eq!(m1.data, vec![16.0, 21.0, 28.0, 37.0]);
assert_eq!(m2.data, vec![4.0, 9.0, 16.0, 25.0]);
} else {
panic!("Expected matrix results");
}
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen_test::wasm_bindgen_test)]
#[test]
fn test_unsupported_power_combinations() {
let matrix = Tensor::new_2d(vec![1.0, 2.0, 3.0, 4.0], 2, 2).unwrap();
let string_val = Value::String("test".to_string());
let result = power(&string_val, &Value::Tensor(matrix.clone()));
assert!(result.is_err());
let result = power(&Value::Tensor(matrix.clone()), &Value::Tensor(matrix));
assert!(result.is_err());
}