Skip to main content

RrLU

Struct RrLU 

Source
pub struct RrLU<T: Scalar> { /* private fields */ }
Expand description

Rank-Revealing LU decomposition.

Represents a matrix A as P_row * A * P_col = L * U, where P_row and P_col are permutation matrices, L is lower-triangular, and U is upper-triangular. One of L or U has unit diagonal, controlled by the left_orthogonal option.

§Examples

use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, matrix::mat_mul};

let m = from_vec2d(vec![
    vec![1.0_f64, 2.0, 3.0],
    vec![4.0, 5.0, 6.0],
    vec![7.0, 8.0, 10.0],
]);

let lu = rrlu(&m, None).unwrap();
assert_eq!(lu.npivots(), 3);

// Verify L * U reconstructs the permuted matrix
let l = lu.left(false);
let u = lu.right(false);
let reconstructed = mat_mul(&l, &u);

// Check reconstruction matches the permuted matrix
for i in 0..3 {
    for j in 0..3 {
        let orig_row = lu.row_permutation()[i];
        let orig_col = lu.col_permutation()[j];
        assert!((reconstructed[[i, j]] - m[[orig_row, orig_col]]).abs() < 1e-10);
    }
}

Implementations§

Source§

impl<T: Scalar> RrLU<T>

Source

pub fn new(nr: usize, nc: usize, left_orthogonal: bool) -> Self

Create an empty rrLU for a matrix of given size.

Used internally. Most users should call rrlu or rrlu_inplace instead.

§Examples
use tensor4all_tcicore::RrLU;

let lu = RrLU::<f64>::new(3, 4, true);
assert_eq!(lu.nrows(), 3);
assert_eq!(lu.ncols(), 4);
assert_eq!(lu.npivots(), 0);
assert!(lu.is_left_orthogonal());
Source

pub fn nrows(&self) -> usize

Number of rows

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0], vec![5.0, 6.0]]);
let lu = rrlu(&m, None).unwrap();
assert_eq!(lu.nrows(), 3);
Source

pub fn ncols(&self) -> usize

Number of columns

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0, 3.0], vec![4.0, 5.0, 6.0]]);
let lu = rrlu(&m, None).unwrap();
assert_eq!(lu.ncols(), 3);
Source

pub fn npivots(&self) -> usize

Number of pivots

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
assert_eq!(lu.npivots(), 2);
Source

pub fn row_permutation(&self) -> &[usize]

Row permutation

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let perm = lu.row_permutation();
assert_eq!(perm.len(), 2);
// Permutation is a rearrangement of 0..nrows
let mut sorted = perm.to_vec();
sorted.sort();
assert_eq!(sorted, vec![0, 1]);
Source

pub fn col_permutation(&self) -> &[usize]

Column permutation

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let perm = lu.col_permutation();
assert_eq!(perm.len(), 2);
let mut sorted = perm.to_vec();
sorted.sort();
assert_eq!(sorted, vec![0, 1]);
Source

pub fn row_indices(&self) -> Vec<usize>

Get row indices (selected pivots)

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, RrLUOptions};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, Some(RrLUOptions { max_rank: 1, ..Default::default() })).unwrap();
let rows = lu.row_indices();
assert_eq!(rows.len(), 1);
assert!(rows[0] < 2);
Source

pub fn col_indices(&self) -> Vec<usize>

Get column indices (selected pivots)

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, RrLUOptions};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, Some(RrLUOptions { max_rank: 1, ..Default::default() })).unwrap();
let cols = lu.col_indices();
assert_eq!(cols.len(), 1);
assert!(cols[0] < 2);
Source

pub fn left(&self, permute: bool) -> Matrix<T>

Get left matrix (optionally permuted)

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, matrix::mat_mul};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();

// Unpermuted: L * U reconstructs the row/col-permuted matrix
let l = lu.left(false);
let u = lu.right(false);
let prod = mat_mul(&l, &u);
for i in 0..2 {
    for j in 0..2 {
        let ri = lu.row_permutation()[i];
        let cj = lu.col_permutation()[j];
        assert!((prod[[i, j]] - m[[ri, cj]]).abs() < 1e-10);
    }
}
Source

pub fn right(&self, permute: bool) -> Matrix<T>

Get right matrix (optionally permuted)

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, matrix::mat_mul};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let l = lu.left(false);
let u = lu.right(false);
assert_eq!(u.nrows(), lu.npivots());
assert_eq!(u.ncols(), lu.ncols());
// L * U reconstructs the permuted matrix
let prod = mat_mul(&l, &u);
assert!((prod[[0, 0]] - m[[lu.row_permutation()[0], lu.col_permutation()[0]]]).abs() < 1e-10);
Source

pub fn diag(&self) -> Vec<T>

Get diagonal elements

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let d = lu.diag();
assert_eq!(d.len(), lu.npivots());
// Diagonal elements are non-zero for full-rank matrices
for &val in &d {
    assert!(val.abs() > 1e-14);
}
Source

pub fn pivot_errors(&self) -> Vec<f64>

Get pivot errors

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let errs = lu.pivot_errors();
// One entry per pivot plus the final residual
assert_eq!(errs.len(), lu.npivots() + 1);
// Errors are non-negative
for &e in &errs {
    assert!(e >= 0.0);
}
Source

pub fn last_pivot_error(&self) -> f64

Get last pivot error

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
// Full-rank decomposition has zero residual
assert_eq!(lu.last_pivot_error(), 0.0);
Source

pub fn transpose(&self) -> RrLU<T>

Transpose the decomposition

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);
let lu = rrlu(&m, None).unwrap();
let lu_t = lu.transpose();
assert_eq!(lu_t.nrows(), lu.ncols());
assert_eq!(lu_t.ncols(), lu.nrows());
assert_eq!(lu_t.npivots(), lu.npivots());
assert_eq!(lu_t.is_left_orthogonal(), !lu.is_left_orthogonal());
Source

pub fn is_left_orthogonal(&self) -> bool

Check if left-orthogonal (L has 1s on diagonal)

§Examples
use tensor4all_tcicore::{from_vec2d, matrixlu::rrlu, RrLUOptions};

let m = from_vec2d(vec![vec![1.0_f64, 2.0], vec![3.0, 4.0]]);

let lu = rrlu(&m, None).unwrap();
assert!(lu.is_left_orthogonal()); // default

let lu2 = rrlu(&m, Some(RrLUOptions {
    left_orthogonal: false, ..Default::default()
})).unwrap();
assert!(!lu2.is_left_orthogonal());

Trait Implementations§

Source§

impl<T: Clone + Scalar> Clone for RrLU<T>

Source§

fn clone(&self) -> RrLU<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug + Scalar> Debug for RrLU<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<T> Freeze for RrLU<T>

§

impl<T> RefUnwindSafe for RrLU<T>
where T: RefUnwindSafe,

§

impl<T> Send for RrLU<T>

§

impl<T> Sync for RrLU<T>

§

impl<T> Unpin for RrLU<T>
where T: Unpin,

§

impl<T> UnsafeUnpin for RrLU<T>

§

impl<T> UnwindSafe for RrLU<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
§

impl<U> As for U

§

fn as_<T>(self) -> T
where T: CastFrom<U>,

Casts self to type T. The semantics of numeric casting with the as operator are followed, so <T as As>::as_::<U> can be used in the same way as T as U for numeric conversions. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> DistributionExt for T
where T: ?Sized,

§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

§

impl<T> DistributionExt for T
where T: ?Sized,

§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

§

impl<T> MaybeSend for T

§

impl<T> MaybeSendSync for T

§

impl<T> MaybeSync for T