/// Returns the sign and natural log of the determinant.
Returns the sign and natural log of the determinant.
Returns the sign and natural log of the determinant .
fn bk_sln_det<P, S, A>(uplo: UPLO, ipiv_iter: P, a: &ArrayBase<S, Ix2>) -> (A::Real, A::Real)
where
    P: Iterator<Item = i32>,
    S: Data<Elem = A>,
    A: Scalar + Lapack,
{
    let layout = a.layout().unwrap();
    let mut sign = A::Real::one();
    let mut ln_det = A::Real::zero();
    let mut ipiv_enum = ipiv_iter.enumerate();
    while let Some((k, ipiv_k)) = ipiv_enum.next() {
        debug_assert!(k < a.nrows() && k < a.ncols());
        if ipiv_k > 0 {
            // 1x1 block at k, must be real.
            let elem = unsafe { a.uget((k, k)) }.re();
            debug_assert_eq!(elem.im(), Zero::zero());
            sign *= elem.signum();
            ln_det += Float::ln(Float::abs(elem));
        } else {
            // 2x2 block at k..k+2.
            // Upper left diagonal elem, must be real.
            let upper_diag = unsafe { a.uget((k, k)) }.re();
            debug_assert_eq!(upper_diag.im(), Zero::zero());
            // Lower right diagonal elem, must be real.
            let lower_diag = unsafe { a.uget((k + 1, k + 1)) }.re();
            debug_assert_eq!(lower_diag.im(), Zero::zero());
            // Off-diagonal elements, can be complex.
            let off_diag = match layout {
                MatrixLayout::C { .. } => match uplo {
                    UPLO::Upper => unsafe { a.uget((k + 1, k)) },
                    UPLO::Lower => unsafe { a.uget((k, k + 1)) },
                },
                MatrixLayout::F { .. } => match uplo {
                    UPLO::Upper => unsafe { a.uget((k, k + 1)) },
                    UPLO::Lower => unsafe { a.uget((k + 1, k)) },
                },
            };
            // Determinant of 2x2 block.
            let block_det = upper_diag * lower_diag - off_diag.square();
            sign *= block_det.signum();
            ln_det += Float::ln(Float::abs(block_det));
            // Skip the k+1 ipiv value.
            ipiv_enum.next();
        }
    }
    (sign, ln_det)
}
fn bk_sln_det < P , S , A > ( uplo : UPLO , ipiv_iter : P , a : & ArrayBase < S , Ix2 > ) -> ( A :: Real , A :: Real ) where P : Iterator < Item = i32 > , S : Data < Elem = A > , A : Scalar + Lapack , { let layout = a . layout ( ) . unwrap ( ) ; let mut sign = A :: Real :: one ( ) ; let mut ln_det = A :: Real :: zero ( ) ; let mut ipiv_enum = ipiv_iter . enumerate ( ) ; while let Some ( ( k , ipiv_k ) ) = ipiv_enum . next ( ) { debug_assert ! ( k a nrows ( ) k a ncols ( ) ) ; if ipiv_k > 0 { // 1x1 block at k, must be real. let elem = unsafe { a . uget ( ( k , k ) ) } . re ( ) ; debug_assert_eq ! ( elem im ( ) Zero zero ( ) ) ; sign *= elem . signum ( ) ; ln_det += Float :: ln ( Float :: abs ( elem ) ) ; } else { // 2x2 block at k..k+2. // Upper left diagonal elem, must be real. let upper_diag = unsafe { a . uget ( ( k , k ) ) } . re ( ) ; debug_assert_eq ! ( upper_diag im ( ) Zero zero ( ) ) ; // Lower right diagonal elem, must be real. let lower_diag = unsafe { a . uget ( ( k + 1 , k + 1 ) ) } . re ( ) ; debug_assert_eq ! ( lower_diag im ( ) Zero zero ( ) ) ; // Off-diagonal elements, can be complex. let off_diag = match layout { MatrixLayout :: C { .. } => match uplo { UPLO :: Upper => unsafe { a . uget ( ( k + 1 , k ) ) } , UPLO :: Lower => unsafe { a . uget ( ( k , k + 1 ) ) } , } , MatrixLayout :: F { .. } => match uplo { UPLO :: Upper => unsafe { a . uget ( ( k , k + 1 ) ) } , UPLO :: Lower => unsafe { a . uget ( ( k + 1 , k ) ) } , } , } ; // Determinant of 2x2 block. let block_det = upper_diag * lower_diag - off_diag . square ( ) ; sign *= block_det . signum ( ) ; ln_det += Float :: ln ( Float :: abs ( block_det ) ) ; // Skip the k+1 ipiv value. ipiv_enum . next ( ) ; } } ( sign , ln_det ) }
Returns the sign and natural log of the determinant.
Returns the sign and natural log of the determinant .
uplo
UPLO
ipiv_iter
P
a
&ArrayBase<S, Ix2>