use scirs2_core::random::prelude::*;
use scirs2_core::ChaCha8Rng;
use scirs2_linalg::error::LinalgResult;
use scirs2_linalg::random_matrices::{
random_complexmatrix, random_hermitian, randommatrix, Distribution1D, MatrixType,
};
#[allow(dead_code)]
fn main() -> LinalgResult<()> {
println!("SciRS2 Random Matrix Generation Examples");
println!("======================================\n");
let mut rng = ChaCha8Rng::seed_from_u64(42);
demo_generalmatrix(&mut rng)?;
demo_symmetricmatrix(&mut rng)?;
demo_positive_definite(&mut rng)?;
demo_orthogonalmatrix(&mut rng)?;
demo_correlationmatrix(&mut rng)?;
demo_sparsematrix(&mut rng)?;
demo_complex_matrices(&mut rng)?;
Ok(())
}
#[allow(dead_code)]
fn demo_generalmatrix<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("1. General Random Matrix");
println!("----------------------");
let uniformmatrix = randommatrix(
3,
4,
MatrixType::General(Distribution1D::Uniform { a: -1.0, b: 1.0 }),
rng,
)?;
println!("Uniform[-1, 1] (3x4):");
printmatrix(&uniformmatrix);
let normalmatrix = randommatrix(
4,
3,
MatrixType::General(Distribution1D::StandardNormal),
rng,
)?;
println!("\nStandard Normal (4x3):");
printmatrix(&normalmatrix);
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_symmetricmatrix<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("2. Symmetric Random Matrix");
println!("------------------------");
let symmatrix = randommatrix(
4,
4,
MatrixType::Symmetric(Distribution1D::Normal {
mean: 0.0,
std_dev: 2.0,
}),
rng,
)?;
println!("Symmetric matrix (4x4):");
printmatrix(&symmatrix);
let mut max_diff: f64 = 0.0;
for i in 0..4 {
for j in i + 1..4 {
let diff = (symmatrix[[i, j]] - symmatrix[[j, i]]).abs();
max_diff = max_diff.max(diff);
}
}
println!("Maximum asymmetry: {:.2e}", max_diff);
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_positive_definite<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("3. Positive Definite Matrix");
println!("--------------------------");
let pdmatrix = randommatrix(
3,
3,
MatrixType::PositiveDefinite {
eigenvalue_min: 0.5,
eigenvalue_max: 5.0,
},
rng,
)?;
println!("Positive definite matrix (3x3):");
printmatrix(&pdmatrix);
use scirs2_linalg::cholesky;
match cholesky(&pdmatrix.view(), None) {
Ok(_) => println!("✓ Cholesky decomposition successful (matrix is positive definite)"),
Err(_) => println!("✗ Cholesky decomposition failed"),
}
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_orthogonalmatrix<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("4. Orthogonal Matrix");
println!("-------------------");
let orthomatrix = randommatrix(3, 3, MatrixType::Orthogonal, rng)?;
println!("Orthogonal matrix Q (3x3):");
printmatrix(&orthomatrix);
let qt = orthomatrix.t();
let qtq = qt.dot(&orthomatrix);
println!("\nQ^T * Q (should be identity):");
printmatrix(&qtq);
let mut max_error: f64 = 0.0;
for i in 0..3 {
for j in 0..3 {
let expected = if i == j { 1.0 } else { 0.0 };
let error = (qtq[[i, j]] - expected).abs();
max_error = max_error.max(error);
}
}
println!("Maximum deviation from identity: {:.2e}", max_error);
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_correlationmatrix<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("5. Correlation Matrix");
println!("--------------------");
let corrmatrix = randommatrix(5, 5, MatrixType::Correlation, rng)?;
println!("Correlation matrix (5x5):");
printmatrix(&corrmatrix);
println!("\nVerifying correlation matrix properties:");
let mut diag_ok = true;
for i in 0..5 {
if (corrmatrix[[i, i]] - 1.0).abs() > 1e-10 {
diag_ok = false;
break;
}
}
println!("✓ Diagonal elements = 1: {}", diag_ok);
let mut sym_ok = true;
for i in 0..5 {
for j in i + 1..5 {
if (corrmatrix[[i, j]] - corrmatrix[[j, i]]).abs() > 1e-10 {
sym_ok = false;
break;
}
}
}
println!("✓ Symmetric: {}", sym_ok);
let mut range_ok = true;
for &val in corrmatrix.iter() {
if !(-1.0..=1.0).contains(&val) {
range_ok = false;
break;
}
}
println!("✓ All values in [-1, 1]: {}", range_ok);
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_sparsematrix<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("6. Sparse Matrix");
println!("---------------");
let sparsematrix = randommatrix(
6,
8,
MatrixType::Sparse {
density: 0.2,
distribution: Distribution1D::Normal {
mean: 0.0,
std_dev: 1.0,
},
},
rng,
)?;
println!("Sparse matrix (6x8, density=0.2):");
print_sparsematrix(&sparsematrix);
let nnz = sparsematrix.iter().filter(|&&x| x.abs() > 1e-10).count();
let total = sparsematrix.nrows() * sparsematrix.ncols();
let actual_density = nnz as f64 / total as f64;
println!(
"\nNon-zero elements: {} / {} (density: {:.3})",
nnz, total, actual_density
);
println!();
Ok(())
}
#[allow(dead_code)]
fn demo_complex_matrices<R: scirs2_core::random::Rng>(rng: &mut R) -> LinalgResult<()> {
println!("7. Complex Matrices");
println!("------------------");
let complexmatrix = random_complexmatrix(
3,
3,
Distribution1D::StandardNormal,
Distribution1D::StandardNormal,
rng,
)?;
println!("Complex matrix (3x3):");
print_complexmatrix(&complexmatrix);
let hermitian = random_hermitian(
4,
Distribution1D::StandardNormal,
Distribution1D::Uniform { a: -0.5, b: 0.5 },
rng,
)?;
println!("\nHermitian matrix (4x4):");
print_complexmatrix(&hermitian);
let mut max_error: f64 = 0.0;
for i in 0..4 {
for j in 0..4 {
let diff = (hermitian[[i, j]] - hermitian[[j, i]].conj()).norm();
max_error = max_error.max(diff);
}
}
println!("Maximum deviation from Hermitian: {:.2e}", max_error);
println!();
Ok(())
}
#[allow(dead_code)]
fn printmatrix(matrix: &scirs2_core::ndarray::Array2<f64>) {
for row in matrix.rows() {
print!("[");
for (i, &val) in row.iter().enumerate() {
if i > 0 {
print!(", ");
}
print!("{:7.3}", val);
}
println!("]");
}
}
#[allow(dead_code)]
fn print_sparsematrix(matrix: &scirs2_core::ndarray::Array2<f64>) {
for row in matrix.rows() {
print!("[");
for (i, &val) in row.iter().enumerate() {
if i > 0 {
print!(", ");
}
if val.abs() < 1e-10 {
print!(" .");
} else {
print!("{:7.3}", val);
}
}
println!("]");
}
}
#[allow(dead_code)]
fn print_complexmatrix(matrix: &scirs2_core::ndarray::Array2<scirs2_core::Complex<f64>>) {
for row in matrix.rows() {
print!("[");
for (i, &val) in row.iter().enumerate() {
if i > 0 {
print!(", ");
}
print!("{:6.2}{:+.2}i", val.re, val.im);
}
println!("]");
}
}