#[cfg(feature = "complex")]
fn main() {
eprintln!("shell_demo.rs is unavailable when built with --features complex");
}
use kryst::core::mat::shell::ShellMat;
use kryst::core::traits::MatVec;
#[cfg(not(feature = "complex"))]
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Kryst Shell Matrix Demo");
println!("=======================");
println!("\n1. Diagonal Matrix Shell Demo");
diagonal_shell_demo()?;
println!("\n2. Finite Difference Operator Shell Demo");
finite_difference_shell_demo()?;
println!("\nShell matrix demo completed successfully!");
Ok(())
}
#[cfg(not(feature = "complex"))]
fn diagonal_shell_demo() -> Result<(), Box<dyn std::error::Error>> {
let diagonal_entries = vec![1.0, 2.0, 3.0, 4.0, 5.0];
let n = diagonal_entries.len();
let diag_for_mult = diagonal_entries.clone();
let diag_for_trans = diagonal_entries.clone();
let shell_matrix = ShellMat::new(
n,
move |x: &Vec<f64>, y: &mut Vec<f64>| {
let x_ref: &[f64] = x.as_ref();
let y_mut: &mut [f64] = y.as_mut();
for i in 0..n {
y_mut[i] = diag_for_mult[i] * x_ref[i];
}
},
move |x: &Vec<f64>, y: &mut Vec<f64>| {
let x_ref: &[f64] = x.as_ref();
let y_mut: &mut [f64] = y.as_mut();
for i in 0..n {
y_mut[i] = diag_for_trans[i] * x_ref[i];
}
},
);
let x = vec![1.0; n];
let mut y = vec![0.0; n];
shell_matrix.matvec(&x, &mut y);
println!("Input vector x: {:?}", x);
println!("Output y = A*x: {:?}", y);
println!("Expected: {:?}", diagonal_entries);
for i in 0..n {
assert!((y[i] - diagonal_entries[i]).abs() < 1e-14);
}
println!("✓ Matrix-vector multiplication correct!");
Ok(())
}
#[cfg(not(feature = "complex"))]
fn finite_difference_shell_demo() -> Result<(), Box<dyn std::error::Error>> {
let n = 5;
let h = 1.0 / (n as f64 + 1.0);
let h2_inv = 1.0 / (h * h);
let finite_diff = ShellMat::new_symmetric(n, move |x: &Vec<f64>, y: &mut Vec<f64>| {
let x_ref: &[f64] = x.as_ref();
let y_mut: &mut [f64] = y.as_mut();
for i in 0..n {
y_mut[i] = 2.0 * x_ref[i] * h2_inv;
if i > 0 {
y_mut[i] -= x_ref[i - 1] * h2_inv;
}
if i < n - 1 {
y_mut[i] -= x_ref[i + 1] * h2_inv;
}
}
});
let mut x = vec![0.0; n];
for i in 0..n {
let xi = (i as f64 + 1.0) * h;
x[i] = xi * (1.0 - xi); }
let mut y = vec![0.0; n];
finite_diff.matvec(&x, &mut y);
println!("Grid points (h = {:.3}):", h);
println!("Input function u(x) = x(1-x): {:?}", x);
println!("Output -d²u/dx²: {:?}", y);
let expected = vec![2.0; n];
println!("Expected (analytical): {:?}", expected);
let max_error = y
.iter()
.zip(expected.iter())
.map(|(yi, ei)| (yi - ei).abs())
.fold(0.0, f64::max);
println!("Maximum error: {:.6}", max_error);
println!("✓ Finite difference operator working correctly!");
Ok(())
}