use numrs2::nn::normalization::*;
use scirs2_core::ndarray::{array, Array1, Array2};
const EPSILON: f64 = 1e-5;
#[test]
fn test_batch_norm_1d_basic() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![1.0, 1.0, 1.0];
let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
assert_eq!(y.shape(), x.shape());
for j in 0..y.ncols() {
let col = y.column(j);
let mean: f64 = col.iter().sum::<f64>() / col.len() as f64;
assert!(mean.abs() < EPSILON * 10.0_f64); }
}
#[test]
fn test_batch_norm_1d_with_scale_shift() {
let x = array![[0.0, 1.0], [2.0, 3.0]];
let gamma = array![2.0, 2.0]; let beta = array![1.0, 1.0]; let epsilon = 1e-5_f64;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
assert_eq!(y.shape(), x.shape());
for &val in y.iter() {
let val: f64 = val;
assert!(val.is_finite());
}
}
#[test]
fn test_batch_norm_1d_dimension_mismatch() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![1.0, 1.0]; let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let result = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon);
assert!(result.is_err());
}
#[test]
fn test_layer_norm_basic() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![1.0, 1.0, 1.0];
let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let y = layer_norm(&x.view(), &gamma.view(), &beta.view(), epsilon).expect("layer_norm failed");
assert_eq!(y.shape(), x.shape());
for i in 0..y.nrows() {
let row = y.row(i);
let mean: f64 = row.iter().sum::<f64>() / row.len() as f64;
assert!(mean.abs() < EPSILON * 10.0_f64); }
}
#[test]
fn test_layer_norm_with_scale_shift() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![2.0, 2.0, 2.0];
let beta = array![1.0, 1.0, 1.0];
let epsilon = 1e-5_f64;
let y = layer_norm(&x.view(), &gamma.view(), &beta.view(), epsilon).expect("layer_norm failed");
assert_eq!(y.shape(), x.shape());
for &val in y.iter() {
let val: f64 = val;
assert!(val.is_finite());
}
}
#[test]
fn test_layer_norm_dimension_mismatch() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![1.0, 1.0]; let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let result = layer_norm(&x.view(), &gamma.view(), &beta.view(), epsilon);
assert!(result.is_err());
}
#[test]
fn test_dropout_basic() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let p = 0.5_f64;
let y = dropout_2d(&x.view(), p, true).expect("dropout failed");
assert_eq!(y.shape(), x.shape());
let num_zeros = y.iter().filter(|&&v| {
let v: f64 = v;
v.abs() < EPSILON
}).count();
assert!(num_zeros <= y.len());
}
#[test]
fn test_dropout_p_zero() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let p = 0.0_f64;
let y = dropout_2d(&x.view(), p, true).expect("dropout failed");
for (&actual, &expected) in y.iter().zip(x.iter()) {
let actual: f64 = actual;
let expected: f64 = expected;
assert!((actual - expected).abs() < EPSILON);
}
}
#[test]
fn test_dropout_p_high() {
let x = array![[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]];
let p = 0.9999_f64;
let y = dropout_2d(&x.view(), p, true).expect("dropout failed");
let num_zeros = y.iter().filter(|&&v| {
let v: f64 = v;
v.abs() < EPSILON
}).count();
assert!(num_zeros >= 1);
}
#[test]
fn test_dropout_invalid_probability() {
let x = array![[1.0, 2.0, 3.0]];
let result = dropout_2d(&x.view(), -0.1_f64, true);
assert!(result.is_err());
let result = dropout_2d(&x.view(), 1.0_f64, true);
assert!(result.is_err());
let result = dropout_2d(&x.view(), 1.5_f64, true);
assert!(result.is_err());
}
#[test]
fn test_batch_norm_single_sample() {
let x = array![[1.0, 2.0, 3.0]];
let gamma = array![1.0, 1.0, 1.0];
let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
assert_eq!(y.shape(), x.shape());
}
#[test]
fn test_layer_norm_single_feature() {
let x = array![[1.0], [2.0], [3.0]];
let gamma = array![1.0];
let beta = array![0.0];
let epsilon = 1e-5_f64;
let y = layer_norm(&x.view(), &gamma.view(), &beta.view(), epsilon).expect("layer_norm failed");
assert_eq!(y.shape(), x.shape());
}
#[test]
fn test_normalization_large_values() {
let x = array![[1000.0, 2000.0, 3000.0], [4000.0, 5000.0, 6000.0]];
let gamma = array![1.0, 1.0, 1.0];
let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
for &val in y.iter() {
let val: f64 = val;
assert!(val.is_finite());
}
}
#[test]
fn test_normalization_negative_values() {
let x = array![[-3.0, -2.0, -1.0], [1.0, 2.0, 3.0]];
let gamma = array![1.0, 1.0, 1.0];
let beta = array![0.0, 0.0, 0.0];
let epsilon = 1e-5_f64;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
for &val in y.iter() {
let val: f64 = val;
assert!(val.is_finite());
}
}
#[test]
fn test_normalization_f32() {
let x = array![[1.0f32, 2.0, 3.0], [4.0, 5.0, 6.0]];
let gamma = array![1.0f32, 1.0, 1.0];
let beta = array![0.0f32, 0.0, 0.0];
let epsilon = 1e-5f32;
let y = batch_norm_1d(&x.view(), &gamma.view(), &beta.view(), epsilon)
.expect("batch_norm_1d failed");
assert_eq!(y.shape(), x.shape());
}