conspire 0.7.1

The Rust interface to conspire.
Documentation
use crate::math::{
    Rank2, Tensor, TensorArray, TensorRank0, TensorRank2,
    test::{TestError, assert_eq, assert_eq_within_tols},
};
use std::cmp::Ordering;

fn get_array_dim_2() -> [[TensorRank0; 2]; 2] {
    [[1.0, 2.0], [3.0, 4.0]]
}

fn get_array_dim_3() -> [[TensorRank0; 3]; 3] {
    [[1.0, 4.0, 6.0], [7.0, 2.0, 5.0], [9.0, 8.0, 3.0]]
}

fn get_array_dim_4() -> [[TensorRank0; 4]; 4] {
    [
        [1.0, 4.0, 6.0, 6.0],
        [1.0, 5.0, 1.0, 0.0],
        [1.0, 3.0, 5.0, 0.0],
        [1.0, 4.0, 6.0, 0.0],
    ]
}

fn get_array_dim_9() -> [[TensorRank0; 9]; 9] {
    [
        [2.0, 2.0, 4.0, 0.0, 0.0, 1.0, 1.0, 3.0, 3.0],
        [0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 4.0, 2.0, 1.0],
        [3.0, 0.0, 1.0, 2.0, 0.0, 3.0, 4.0, 4.0, 2.0],
        [4.0, 4.0, 0.0, 2.0, 1.0, 1.0, 0.0, 0.0, 4.0],
        [0.0, 1.0, 0.0, 1.0, 0.0, 3.0, 0.0, 1.0, 1.0],
        [4.0, 2.0, 3.0, 4.0, 2.0, 4.0, 3.0, 0.0, 4.0],
        [1.0, 3.0, 2.0, 0.0, 0.0, 0.0, 2.0, 4.0, 2.0],
        [2.0, 2.0, 2.0, 4.0, 1.0, 2.0, 4.0, 2.0, 2.0],
        [1.0, 2.0, 3.0, 4.0, 0.0, 1.0, 4.0, 2.0, 1.0],
    ]
}

fn get_tensor_rank_2_dim_2() -> TensorRank2<2, 1, 1> {
    TensorRank2::from(get_array_dim_2())
}

fn get_tensor_rank_2_dim_3() -> TensorRank2<3, 1, 1> {
    TensorRank2::from(get_array_dim_3())
}

fn get_tensor_rank_2_dim_4() -> TensorRank2<4, 1, 1> {
    TensorRank2::from(get_array_dim_4())
}

fn get_tensor_rank_2_dim_9() -> TensorRank2<9, 1, 1> {
    TensorRank2::from(get_array_dim_9())
}

#[test]
fn determinant_dim_2() -> Result<(), TestError> {
    assert_eq(&get_tensor_rank_2_dim_2().determinant(), &-2.0)
}

#[test]
fn determinant_dim_3() -> Result<(), TestError> {
    assert_eq(&get_tensor_rank_2_dim_3().determinant(), &290.0)
}

#[test]
fn determinant_dim_4() -> Result<(), TestError> {
    assert_eq_within_tols(&get_tensor_rank_2_dim_4().determinant(), &36.0)
}

#[test]
fn determinant_dim_9() -> Result<(), TestError> {
    assert_eq_within_tols(&get_tensor_rank_2_dim_9().determinant(), &5297.0)
}

#[test]
fn inverse_dim_2() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_2() * get_tensor_rank_2_dim_2().inverse()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_dim_3() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_3() * get_tensor_rank_2_dim_3().inverse()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_dim_4() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_4() * get_tensor_rank_2_dim_4().inverse()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_dim_9() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_9() * get_tensor_rank_2_dim_9().inverse()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_and_determinant_dim_2() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_2();
    let (inverse, determinant) = tensor_rank_2.inverse_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse, &tensor_rank_2.inverse())
}

#[test]
fn inverse_and_determinant_dim_3() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_3();
    let (inverse, determinant) = tensor_rank_2.inverse_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse, &tensor_rank_2.inverse())
}

#[test]
fn inverse_and_determinant_dim_4() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_4();
    let (inverse, determinant) = tensor_rank_2.inverse_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse, &tensor_rank_2.inverse())
}

#[test]
fn inverse_and_determinant_dim_9() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_9();
    let (inverse, determinant) = tensor_rank_2.inverse_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse, &tensor_rank_2.inverse())
}

#[test]
fn inverse_transpose_dim_2() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_2().transpose() * get_tensor_rank_2_dim_2().inverse_transpose()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_transpose_dim_3() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_3().transpose() * get_tensor_rank_2_dim_3().inverse_transpose()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_transpose_dim_4() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_4().transpose() * get_tensor_rank_2_dim_4().inverse_transpose()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_transpose_9() -> Result<(), TestError> {
    assert_eq_within_tols(
        &(get_tensor_rank_2_dim_9().transpose() * get_tensor_rank_2_dim_9().inverse_transpose()),
        &TensorRank2::identity(),
    )
}

#[test]
fn inverse_transpose_and_determinant_dim_2() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_2();
    let (inverse_transpose, determinant) = tensor_rank_2.inverse_transpose_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse_transpose, &tensor_rank_2.inverse_transpose())
}

#[test]
fn inverse_transpose_and_determinant_dim_3() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_3();
    let (inverse_transpose, determinant) = tensor_rank_2.inverse_transpose_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse_transpose, &tensor_rank_2.inverse_transpose())
}

#[test]
fn inverse_transpose_and_determinant_dim_4() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_4();
    let (inverse_transpose, determinant) = tensor_rank_2.inverse_transpose_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse_transpose, &tensor_rank_2.inverse_transpose())
}

#[test]
fn inverse_transpose_and_determinant_dim_9() -> Result<(), TestError> {
    let tensor_rank_2 = get_tensor_rank_2_dim_9();
    let (inverse_transpose, determinant) = tensor_rank_2.inverse_transpose_and_determinant();
    assert_eq(&determinant, &tensor_rank_2.determinant())?;
    assert_eq(&inverse_transpose, &tensor_rank_2.inverse_transpose())
}

#[test]
fn lu_decomposition() -> Result<(), TestError> {
    let (l, u, p) = get_tensor_rank_2_dim_9().lu_decomposition();
    l.iter()
        .enumerate()
        .zip(u.iter())
        .for_each(|((i, l_i), u_i)| {
            l_i.iter()
                .enumerate()
                .zip(u_i.iter())
                .for_each(|((j, l_ij), u_ij)| match i.cmp(&j) {
                    Ordering::Equal => assert_eq!(l_ij, &1.0),
                    Ordering::Greater => assert_eq!(u_ij, &0.0),
                    Ordering::Less => assert_eq!(l_ij, &0.0),
                })
        });
    assert_eq_within_tols(
        &(l * u),
        &p.iter()
            .map(|&p_i| get_tensor_rank_2_dim_9()[p_i].clone())
            .collect(),
    )
}