mod support;
use gspx::kernel::{ChebyKernel, VfKernel, estimate_spectral_bound, impulse, impulse_1d};
use ndarray::Array1;
#[test]
fn vfkernel_parsing() {
let d = r#"{
"poles":[
{"q":1.0, "r":[0.1,0.2]},
{"q":2.0, "r":[0.3,0.4]}
],
"d":[0.5,0.6]
}"#;
let k = VfKernel::from_json_str(d).expect("vfkernel json should parse");
assert_eq!(k.poles.to_vec(), vec![1.0, 2.0]);
assert_eq!(k.residues.shape(), &[2, 2]);
assert_eq!(k.direct.to_vec(), vec![0.5, 0.6]);
}
#[test]
fn chebykernel_parsing_and_eval() {
let d = r#"{
"spectrum_bound":2.0,
"approximations":[
{"coeffs":[1.0,2.0,3.0]},
{"coeffs":[4.0,5.0,6.0]}
]
}"#;
let k = ChebyKernel::from_json_str(d).expect("chebykernel json should parse");
assert_eq!(k.coefficients.shape(), &[3, 2]);
let y = k
.evaluate(Array1::from(vec![0.0, 1.0, 2.0]).view())
.expect("cheby evaluate should work");
assert_eq!(y.shape(), &[3, 2]);
}
#[test]
fn impulse_defaults_and_shape() {
let l = support::path_laplacian(10);
let x = impulse(&l, 3, 1).expect("impulse should build");
assert_eq!(x.shape(), &[10, 1]);
assert_eq!(x[[3, 0]], 1.0);
let x2 = impulse(&l, 3, 2).expect("multi-step impulse should build");
assert_eq!(x2.shape(), &[10, 2]);
assert_eq!(x2[[3, 0]], 1.0);
assert_eq!(x2[[3, 1]], 1.0);
}
#[test]
fn impulse_1d_shape_and_value() {
let l = support::path_laplacian(10);
let x = impulse_1d(&l, 4).expect("1d impulse should build");
assert_eq!(x.len(), 10);
assert_eq!(x[4], 1.0);
assert_eq!(x.sum(), 1.0);
}
#[test]
fn spectral_bound_positive() {
let l = support::path_laplacian(40);
let ub = estimate_spectral_bound(&l).expect("spectral bound estimation should work");
assert!(ub > 0.01);
}
#[test]
fn chebykernel_mismatch_coeffs_fails() {
let d = r#"{
"spectrum_bound":1.0,
"approximations":[{"coeffs":[1.0,2.0]},{"coeffs":[3.0,4.0,5.0]}]
}"#;
let err = ChebyKernel::from_json_str(d).expect_err("mismatch coeff lengths should fail");
assert!(format!("{err}").contains("same length"));
}
#[test]
fn chebykernel_empty_approximations() {
let d = r#"{"spectrum_bound":2.0,"approximations":[]}"#;
let k = ChebyKernel::from_json_str(d).expect("empty approximations should parse");
assert_eq!(k.coefficients.shape(), &[0, 0]);
let y = k
.evaluate(Array1::from_vec(vec![0.5]).view())
.expect("evaluation should succeed for empty kernel");
assert_eq!(y.shape(), &[1, 0]);
}
#[test]
fn impulse_out_of_bounds_fails() {
let l = support::path_laplacian(10);
assert!(impulse(&l, 100, 1).is_err());
}