Skip to main content

RationalMatrix

Struct RationalMatrix 

Source
pub struct RationalMatrix<const D: usize> { /* private fields */ }
Available on crate feature exact only.
Expand description

Exact rational square matrix with compile-time dimension D.

Construction validates that every denominator is non-zero and canonicalizes every entry to lowest terms with a positive denominator. The private storage then carries those invariants, so determinant and solve methods do not repeat input validation. Unlike crate::Matrix, entries are already exact rational values rather than finite binary64 values interpreted exactly.

Direct field construction is intentionally unavailable:

use la_stack::{BigRational, RationalMatrix};

let _ = RationalMatrix::<1> {
    rows: [[BigRational::from_integer(1.into())]],
};

Implementations§

Source§

impl<const D: usize> RationalMatrix<D>

Source

pub fn try_from_rows(rows: [[BigRational; D]; D]) -> Result<Self, LaError>

Try to create an exact matrix from row-major rational storage.

Raw, non-reduced BigRational::new_raw values and negative denominators are accepted, interpreted as their mathematical quotient, and stored canonically. A raw zero denominator is not a rational value and is rejected at this construction boundary.

§Examples
use la_stack::prelude::*;

let matrix = RationalMatrix::<2>::try_from_rows([
    [
        BigRational::new(1.into(), 3.into()),
        BigRational::from_integer(2.into()),
    ],
    [
        BigRational::from_integer(1.into()),
        BigRational::new(5.into(), 2.into()),
    ],
])?;
assert_eq!(
    matrix.det(),
    BigRational::new((-7).into(), 6.into())
);
§Errors

Returns LaError::NonFinite at the first matrix cell whose raw rational denominator is zero.

Source

pub fn try_from_fn( make_entry: impl FnMut(usize, usize) -> BigRational, ) -> Result<Self, LaError>

Try to create an exact matrix by evaluating a function at every cell.

The function is evaluated once per cell in row-major order.

§Examples
use la_stack::prelude::*;

let diagonal = RationalMatrix::<3>::try_from_fn(|row, col| {
    BigRational::from_integer(u8::from(row == col).into())
})?;
assert_eq!(diagonal.det_sign(), DeterminantSign::Positive);
§Errors

Returns LaError::NonFinite at the first generated cell whose raw rational denominator is zero.

Source

pub fn zero() -> Self

Return the all-zero exact matrix.

Source

pub const fn as_rows(&self) -> &[[BigRational; D]; D]

Borrow the row-major exact storage.

Source

pub fn into_rows(self) -> [[BigRational; D]; D]

Consume the matrix and return its row-major exact storage.

Source

pub fn get(&self, row: usize, col: usize) -> Option<&BigRational>

Borrow one entry, returning None for an out-of-bounds index.

Source

pub fn set( &mut self, row: usize, col: usize, value: BigRational, ) -> Result<(), LaError>

Replace one exact entry while preserving the canonical non-zero- denominator invariant.

As with try_from_rows, non-reduced values and negative denominators are accepted and canonicalized. Rejected indices or denominators leave the matrix unchanged.

§Examples
use core::assert_matches;
use la_stack::prelude::*;

let mut matrix = RationalMatrix::<2>::zero();
matrix.set(0, 1, BigRational::new_raw((-2).into(), (-4).into()))?;
let half = BigRational::new(1.into(), 2.into());
assert_eq!(matrix.get(0, 1), Some(&half));

let before = matrix.clone();
assert_matches!(
    matrix.set(0, 1, BigRational::new_raw(1.into(), 0.into())),
    Err(LaError::NonFinite {
        location: NonFiniteLocation::MatrixCell { row: 0, col: 1, .. },
        origin: NonFiniteOrigin::Input,
        ..
    })
);
assert_eq!(matrix, before);
§Errors

Returns LaError::IndexOutOfBounds when (row, col) lies outside the matrix, or LaError::NonFinite when value has a raw zero denominator.

Source

pub fn det_sign(&self) -> DeterminantSign

Return the provably exact determinant sign.

This path clears denominators and reads the sign of the resulting integer determinant. It does not construct a rational determinant. For D=0, the empty-product determinant has positive sign. Use det when the determinant value is also needed.

§Examples
use la_stack::prelude::*;

let mut matrix = RationalMatrix::<2>::zero();
assert_eq!(matrix.det_sign(), DeterminantSign::Zero);
matrix.set(0, 1, BigRational::new(1.into(), 3.into()))?;
matrix.set(1, 0, BigRational::new(1.into(), 2.into()))?;
// The exact determinant is -1/6, so its sign is negative.
assert_eq!(matrix.det_sign(), DeterminantSign::Negative);
Source

pub fn det(&self) -> BigRational

Return the exact determinant.

Denominators are cleared independently per row. If row i uses positive scale sᵢ, the integer determinant is divided by ∏ᵢ sᵢ. For D=0, this returns the empty-product determinant 1. Use det_sign when only the sign is needed, or ExactF64Conversion to convert this result under an explicit strict or rounded binary64 contract.

§Examples
use la_stack::prelude::*;

let mut matrix = RationalMatrix::<2>::zero();
matrix.set(0, 0, BigRational::new(1.into(), 3.into()))?;
matrix.set(1, 1, BigRational::from_integer(2.into()))?;
let determinant = matrix.det();
assert_eq!(determinant, BigRational::new(2.into(), 3.into()));
// Conversion rounds only after the exact determinant has been computed.
assert_eq!(determinant.to_rounded_f64()?, 2.0 / 3.0);
Source

pub fn solve( &self, rhs: &RationalVector<D>, ) -> Result<RationalVector<D>, LaError>

Solve A x = b exactly.

Each augmented row is multiplied by one positive common denominator, then fraction-free Bareiss forward elimination runs in BigInt. Only the O(D²) back-substitution phase constructs BigRational values. For D=0, the empty matrix and vector have the unique empty solution.

§Examples
use la_stack::prelude::*;

let zero = BigRational::from_integer(0.into());
let one = BigRational::from_integer(1.into());
let matrix = RationalMatrix::<2>::try_from_rows([
    [BigRational::new(1.into(), 2.into()), zero.clone()],
    [zero, BigRational::new(1.into(), 3.into())],
])?;
let rhs = RationalVector::try_new([one.clone(), one])?;

let solution = matrix.solve(&rhs)?.try_to_f64()?.into_array();
assert_eq!(solution, [2.0, 3.0]);
§Errors

Returns LaError::Singular with exact-singularity metadata when a pivot column contains no non-zero entry.

Trait Implementations§

Source§

impl<const D: usize> Clone for RationalMatrix<D>

Source§

fn clone(&self) -> RationalMatrix<D>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
Source§

impl<const D: usize> Debug for RationalMatrix<D>

Source§

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

Formats the value using the given formatter. Read more
Source§

impl<const D: usize> Eq for RationalMatrix<D>

Source§

impl<const D: usize> PartialEq for RationalMatrix<D>

Source§

fn eq(&self, other: &RationalMatrix<D>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<const D: usize> StructuralPartialEq for RationalMatrix<D>

Auto Trait Implementations§

§

impl<const D: usize> Freeze for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: Freeze,

§

impl<const D: usize> RefUnwindSafe for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: RefUnwindSafe,

§

impl<const D: usize> Send for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: Send,

§

impl<const D: usize> Sync for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: Sync,

§

impl<const D: usize> Unpin for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: Unpin,

§

impl<const D: usize> UnsafeUnpin for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: UnsafeUnpin,

§

impl<const D: usize> UnwindSafe for RationalMatrix<D>
where [[Ratio<BigInt>; D]; D]: 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
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
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
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> 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 = !

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

fn try_from(value: U) -> Result<T, !>

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.