determinant.rs - source
Description: Source of the Rust file `/Users/erlendbasso/.cargo/registry/src/github.com-1ecc6299db9ec823/nalgebra-0.32.1/src/linalg/determinant.rs`.
Keywords: rust, rustlang, rust-lang

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61

    use simba::scalar::ComplexField;

    use crate::base::allocator::Allocator;
    use crate::base::dimension::DimMin;
    use crate::base::storage::Storage;
    use crate::base::{DefaultAllocator, SquareMatrix};

    use crate::linalg::LU;

    impl<T: ComplexField, D: DimMin<D, Output = D>, S: Storage<T, D, D>> SquareMatrix<T, D, S> {
        /// Computes the matrix determinant.
        ///
        /// If the matrix has a dimension larger than 3, an LU decomposition is used.
        #[inline]
        #[must_use]
        pub fn determinant(&self) -> T
        where
            DefaultAllocator: Allocator<T, D, D> + Allocator<(usize, usize), D>,
        {
            assert!(
                self.is_square(),
                "Unable to compute the determinant of a non-square matrix."
            );
            let dim = self.shape().0;

            unsafe {
                match dim {
                    0 => T::one(),
                    1 => self.get_unchecked((0, 0)).clone(),
                    2 => {
                        let m11 = self.get_unchecked((0, 0)).clone();
                        let m12 = self.get_unchecked((0, 1)).clone();
                        let m21 = self.get_unchecked((1, 0)).clone();
                        let m22 = self.get_unchecked((1, 1)).clone();

                        m11 * m22 - m21 * m12
                    }
                    3 => {
                        let m11 = self.get_unchecked((0, 0)).clone();
                        let m12 = self.get_unchecked((0, 1)).clone();
                        let m13 = self.get_unchecked((0, 2)).clone();

                        let m21 = self.get_unchecked((1, 0)).clone();
                        let m22 = self.get_unchecked((1, 1)).clone();
                        let m23 = self.get_unchecked((1, 2)).clone();

                        let m31 = self.get_unchecked((2, 0)).clone();
                        let m32 = self.get_unchecked((2, 1)).clone();
                        let m33 = self.get_unchecked((2, 2)).clone();

                        let minor_m12_m23 = m22.clone() * m33.clone() - m32.clone() * m23.clone();
                        let minor_m11_m23 = m21.clone() * m33 - m31.clone() * m23;
                        let minor_m11_m22 = m21 * m32 - m31 * m22;

                        m11 * minor_m12_m23 - m12 * minor_m11_m23 + m13 * minor_m11_m22
                    }
                    _ => LU::new(self.clone_owned()).determinant(),
                }
            }
        }
    }