<commit_before>use super::Matrix;
use ::vector::ArrayLen;

use typenum;
use typenum::consts::*;
use typenum::uint::UInt;
use typenum::operator_aliases::{Diff, Prod};
use num;
use arrayvec::ArrayVec;

use std::ops::{Add, Mul, Sub};

pub trait Determinant {
    type Item;

    /// Computes determinant of the matrix.
    fn determinant(&self) -> Self::Item;
}

pub trait Cofactor {
    type Item;

    /// Computes cofactor of the matrix.
    fn cofactor(&self, i: usize, j: usize) -> Self::Item;
}

impl<T> Determinant for Matrix<T, U1, U1> where T: Clone {
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone()
    }
}

impl<T> Determinant for Matrix<T, U2, U2>
    where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone() * self[(1,1)].clone()
            - self[(1, 0)].clone() * self[(0, 1)].clone()
    }
}

impl<T> Determinant for Matrix<T, U3, U3>
    where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone() * self[(1, 1)].clone() * self[(2, 2)].clone() +
            self[(0, 1)].clone() * self[(1, 2)].clone() * self[(2, 0)].clone() +
            self[(0, 2)].clone() * self[(1, 0)].clone() * self[(2, 1)].clone() -
            self[(0, 2)].clone() * self[(1, 1)].clone() * self[(2, 0)].clone() -
            self[(0, 1)].clone() * self[(1, 0)].clone() * self[(2, 2)].clone() -
            self[(0, 0)].clone() * self[(1, 2)].clone() * self[(2, 1)].clone()
    }
}

// Determinant for Matrix<T, N, N> where N > U3
// Note: U3 = UInt<UInt<UTerm, B1>, B1>
impl<T, U, Ba, Bb, Bc> Determinant for Matrix<T, UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>
    where
        U: typenum::Unsigned,
        Ba: typenum::Bit,
        Bb: typenum::Bit,
        Bc: typenum::Bit,
        T: num::Signed + Clone,
        UInt<UInt<UInt<U, Ba>, Bb>, Bc>: Mul + typenum::Unsigned + Sub<U1> + for<'a> ArrayLen<&'a T>,
        Prod<UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>: ArrayLen<T>,
        Matrix<T, UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>: Cofactor<Item = T>,
{
    type Item = T;

    fn determinant(&self) -> T {
        (0 .. <UInt<UInt<UInt<U, Ba>, Bb>, Bc> as typenum::Unsigned>::to_usize())
            .map(|i| self[(i, 0)].clone() * self.cofactor(i, 0))
            .fold(T::zero(), Add::add)
    }
}

impl<T> Cofactor for Matrix<T, U2, U2> where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn cofactor(&self, i: usize, j: usize) -> T {
        assert!(i < 2);
        assert!(j < 2);

        let sgn = num::pow::pow(-T::one(), i + j);
<commit_msg>Fix build on stable<commit_after>use super::Matrix;
use ::vector::ArrayLen;

use typenum;
use typenum::consts::*;
use typenum::uint::UInt;
use typenum::operator_aliases::{Diff, Prod};
use num;
use arrayvec::ArrayVec;

use std::ops::{Add, Mul, Sub};

pub trait Determinant {
    type Item;

    /// Computes determinant of the matrix.
    fn determinant(&self) -> Self::Item;
}

pub trait Cofactor {
    type Item;

    /// Computes cofactor of the matrix.
    fn cofactor(&self, i: usize, j: usize) -> Self::Item;
}

impl<T> Determinant for Matrix<T, U1, U1> where T: Clone {
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone()
    }
}

impl<T> Determinant for Matrix<T, U2, U2>
    where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone() * self[(1,1)].clone()
            - self[(1, 0)].clone() * self[(0, 1)].clone()
    }
}

impl<T> Determinant for Matrix<T, U3, U3>
    where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn determinant(&self) -> T {
        self[(0, 0)].clone() * self[(1, 1)].clone() * self[(2, 2)].clone() +
            self[(0, 1)].clone() * self[(1, 2)].clone() * self[(2, 0)].clone() +
            self[(0, 2)].clone() * self[(1, 0)].clone() * self[(2, 1)].clone() -
            self[(0, 2)].clone() * self[(1, 1)].clone() * self[(2, 0)].clone() -
            self[(0, 1)].clone() * self[(1, 0)].clone() * self[(2, 2)].clone() -
            self[(0, 0)].clone() * self[(1, 2)].clone() * self[(2, 1)].clone()
    }
}

// Determinant for Matrix<T, N, N> where N > U3
// Note: U3 = UInt<UInt<UTerm, B1>, B1>
impl<T, U, Ba, Bb, Bc> Determinant for Matrix<T, UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>
    where
        U: typenum::Unsigned,
        Ba: typenum::Bit,
        Bb: typenum::Bit,
        Bc: typenum::Bit,
        T: num::Signed + Clone,
        UInt<UInt<UInt<U, Ba>, Bb>, Bc>: Mul + typenum::Unsigned + Sub<U1> + for<'a> ArrayLen<&'a T>,
        Prod<UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>: ArrayLen<T>,
        Matrix<T, UInt<UInt<UInt<U, Ba>, Bb>, Bc>, UInt<UInt<UInt<U, Ba>, Bb>, Bc>>: Cofactor<Item = T>,
{
    type Item = T;

    fn determinant(&self) -> T {
        let n = <UInt<UInt<UInt<U, Ba>, Bb>, Bc> as typenum::Unsigned>::to_usize();
        (0 .. n)
            .map(|i| self[(i, 0)].clone() * self.cofactor(i, 0))
            .fold(T::zero(), Add::add)
    }
}

impl<T> Cofactor for Matrix<T, U2, U2> where T: num::Signed + Clone
{
    type Item = T;

    #[inline]
    fn cofactor(&self, i: usize, j: usize) -> T {
        assert!(i < 2);
        assert!(j < 2);

        let sgn = num::pow::pow(-T::one(), i + j);

{'fraction_non_alphanumeric': 0.22120824968059866, 'fraction_numerical': 0.023361927359007117, 'mean_word_length': 2.6877523553162854, 'pattern_counts': {'":': 0, '<': 97, '<?xml version=': 0, '>': 109, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5411949', 'n_tokens_mistral': 2257, 'n_tokens_neox': 2136, 'n_words': 540}