Function russell_lab::eigen_decomp_lr[][src]

pub fn eigen_decomp_lr(
    l_real: &mut [f64],
    l_imag: &mut [f64],
    u_real: &mut Matrix,
    u_imag: &mut Matrix,
    v_real: &mut Matrix,
    v_imag: &mut Matrix,
    a: &mut Matrix
) -> Result<(), &'static str>
Expand description

Performs the eigen-decomposition of a square matrix (left and right)

Computes the eigenvalues l and left eigenvectors u, such that:

ujᴴ ⋅ a = lj ⋅ ujᴴ

where lj is the component j of l and ujᴴ is the column j of uᴴ, with uᴴ being the conjugate-transpose of u.

Also, computes the right eigenvectors v, such that:

a ⋅ vj = lj ⋅ vj

where vj is the column j of v.

Output

  • l_real – (m) eigenvalues; real part
  • l_imag – (m) eigenvalues; imaginary part
  • u_real – (m,m) left eigenvectors (as columns); real part
  • u_imag – (m,m) left eigenvectors (as columns); imaginary part
  • v_real – (m,m) right eigenvectors (as columns); real part
  • v_imag – (m,m) right eigenvectors (as columns); imaginary part

Input

  • a – (m,m) general matrix [will be modified]

Note

  • The matrix a will be modified

Example

// import
use russell_lab::*;

// set matrix
let data: &[&[f64]] = &[
    &[0.0, 1.0, 0.0],
    &[0.0, 0.0, 1.0],
    &[1.0, 0.0, 0.0],
];
let mut a = Matrix::from(data)?;

// allocate output arrays
let m = a.nrow();
let mut l_real = vec![0.0; m];
let mut l_imag = vec![0.0; m];
let mut u_real = Matrix::new(m, m);
let mut u_imag = Matrix::new(m, m);
let mut v_real = Matrix::new(m, m);
let mut v_imag = Matrix::new(m, m);

// perform the eigen-decomposition
eigen_decomp_lr(
    &mut l_real,
    &mut l_imag,
    &mut u_real,
    &mut u_imag,
    &mut v_real,
    &mut v_imag,
    &mut a,
)?;

// check results
let l_real_correct = "[-0.5, -0.5, 0.9999999999999998]";
let l_imag_correct = "[0.8660254037844389, -0.8660254037844389, 0.0]";
let u_real_correct = "┌                      ┐\n\
                      │ -0.289 -0.289 -0.577 │\n\
                      │  0.577  0.577 -0.577 │\n\
                      │ -0.289 -0.289 -0.577 │\n\
                      └                      ┘";
let u_imag_correct = "┌                      ┐\n\
                      │ -0.500  0.500  0.000 │\n\
                      │  0.000 -0.000  0.000 │\n\
                      │  0.500 -0.500  0.000 │\n\
                      └                      ┘";
let v_real_correct = "┌                      ┐\n\
                      │  0.577  0.577 -0.577 │\n\
                      │ -0.289 -0.289 -0.577 │\n\
                      │ -0.289 -0.289 -0.577 │\n\
                      └                      ┘";
let v_imag_correct = "┌                      ┐\n\
                      │  0.000 -0.000  0.000 │\n\
                      │  0.500 -0.500  0.000 │\n\
                      │ -0.500  0.500  0.000 │\n\
                      └                      ┘";
assert_eq!(format!("{:?}", l_real), l_real_correct);
assert_eq!(format!("{:?}", l_imag), l_imag_correct);
assert_eq!(format!("{:.3}", u_real), u_real_correct);
assert_eq!(format!("{:.3}", u_imag), u_imag_correct);
assert_eq!(format!("{:.3}", v_real), v_real_correct);
assert_eq!(format!("{:.3}", v_imag), v_imag_correct);