use scirs2_core::ndarray::array;
use scirs2_linalg::structured::{
solve_circulant, solve_toeplitz, structured_to_operator, CirculantMatrix, HankelMatrix,
StructuredMatrix, ToeplitzMatrix,
};
use scirs2_linalg::MatrixFreeOp;
#[allow(dead_code)]
fn main() {
println!("Structured Matrices Example\n");
println!("=== Toeplitz Matrix ===");
let first_row = array![1.0, 2.0, 3.0, 4.0];
let first_col = array![1.0, 5.0, 6.0, 7.0];
let toeplitz =
ToeplitzMatrix::new(first_row.view(), first_col.view()).expect("Operation failed");
let dense_toeplitz = toeplitz.to_dense().expect("Operation failed");
println!("Toeplitz matrix:");
println!("{}", dense_toeplitz);
let x = array![1.0, 2.0, 3.0, 4.0];
let y = toeplitz.matvec(&x.view()).expect("Operation failed");
println!("\nMatrix-vector product:");
println!("x = {:?}", x);
println!("Tx = {:?}", y);
let first_row_sym = array![1.0, 2.0, 3.0];
let toeplitz_sym =
ToeplitzMatrix::new_symmetric(first_row_sym.view()).expect("Operation failed");
println!("\nSymmetric Toeplitz matrix:");
println!("{}", toeplitz_sym.to_dense().expect("Operation failed"));
println!("\n=== Circulant Matrix ===");
let first_row = array![1.0, 2.0, 3.0, 4.0];
let circulant = CirculantMatrix::new(first_row.view()).expect("Operation failed");
let dense_circulant = circulant.to_dense().expect("Operation failed");
println!("Circulant matrix:");
println!("{}", dense_circulant);
let y = circulant.matvec(&x.view()).expect("Operation failed");
println!("\nMatrix-vector product:");
println!("x = {:?}", x);
println!("Cx = {:?}", y);
println!("\n=== Hankel Matrix ===");
let first_col = array![1.0, 2.0, 3.0];
let last_row = array![3.0, 4.0, 5.0];
let hankel = HankelMatrix::new(first_col.view(), last_row.view()).expect("Operation failed");
let dense_hankel = hankel.to_dense().expect("Operation failed");
println!("Hankel matrix:");
println!("{}", dense_hankel);
let x_hankel = array![1.0, 2.0, 3.0];
let y = hankel.matvec(&x_hankel.view()).expect("Operation failed");
println!("\nMatrix-vector product:");
println!("x = {:?}", x_hankel);
println!("Hx = {:?}", y);
let sequence = array![1.0, 2.0, 3.0, 4.0, 5.0];
let hankel_seq = HankelMatrix::from_sequence(sequence.view(), 3, 3).expect("Operation failed");
println!("\nHankel matrix from sequence:");
println!("{}", hankel_seq.to_dense().expect("Operation failed"));
println!("\n=== Matrix-free operations ===");
let toeplitz_op = structured_to_operator(&toeplitz);
let y_op = toeplitz_op.apply(&x.view()).expect("Operation failed");
println!("Matrix-free operator result:");
println!("x = {:?}", x);
println!("Op(x) = {:?}", y_op);
let direct_y = toeplitz.matvec(&x.view()).expect("Operation failed");
println!("\nCompare with direct matrix-vector product:");
println!("Direct Tx = {:?}", direct_y);
println!("\n=== Solving Toeplitz systems ===");
let c = array![1.0, 0.5, 0.3]; let r = array![1.0, 0.7, 0.2]; let b = array![1.0, 2.0, 3.0];
let x = solve_toeplitz(c.view(), r.view(), b.view()).expect("Operation failed");
println!("Toeplitz system:");
println!("First column = {:?}", c);
println!("First row = {:?}", r);
println!("Right-hand side = {:?}", b);
println!("Solution = {:?}", x);
let toeplitz = ToeplitzMatrix::new(c.view(), r.view()).expect("Operation failed");
let tx = toeplitz.matvec(&x.view()).expect("Operation failed");
println!("\nVerification (Tx should equal b):");
println!("Tx = {:?}", tx);
println!("b = {:?}", b);
println!("\n=== Solving Circulant systems ===");
let c = array![1.0, 2.0, 3.0]; let b = array![14.0, 10.0, 12.0];
let x = solve_circulant(c.view(), b.view()).expect("Operation failed");
println!("Circulant system:");
println!("First row = {:?}", c);
println!("Right-hand side = {:?}", b);
println!("Solution = {:?}", x);
let circulant = CirculantMatrix::new(c.view()).expect("Operation failed");
let cx = circulant.matvec(&x.view()).expect("Operation failed");
println!("\nVerification (Cx should equal b):");
println!("Cx = {:?}", cx);
println!("b = {:?}", b);
}