extern crate geom;

use geom::*;

const EPS: f64 = 1e-5;

#[test]
fn test_mat_inverse_random() {
    fn check(m: Mat4<f64>) {
        let m_inv = m.inverse();
        let mul = m * m_inv;
        for i in 0..4 {
            for j in 0..4 {
                let need = if i == j { 1.0 } else { 0.0 };
                assert!((mul[i][j] - need).abs() < EPS);
            }
        }
    }
    // Random generated test cases
    check(Mat4::new([
        [8.7, 3.6, 6.5, 6.5],
        [7.4, 5.8, 8.6, 2.6],
        [1.8, 8.3, 6.6, 4.9],
        [2.1, 3.4, 3.5, 8.8],
    ]));
    check(Mat4::new([
        [9.6, 0.6, 5.4, 3.2],
        [0.5, 0.1, 5.4, 6.6],
        [2.0, 3.8, 0.0, 1.4],
        [6.6, 2.9, 4.3, 9.3],
    ]));
    check(Mat4::new([
        [6.1, 1.7, 2.7, 3.6],
        [1.8, 2.5, 7.8, 7.1],
        [2.6, 9.5, 1.5, 8.0],
        [6.5, 6.5, 5.9, 7.2],
    ]));
    check(Mat4::new([
        [8.4, 1.0, 6.4, 0.0],
        [1.6, 1.1, 1.5, 4.0],
        [5.5, 1.2, 0.6, 8.3],
        [9.1, 9.7, 8.7, 0.8],
    ]));
    check(Mat4::new([
        [0.6, 5.7, 0.2, 7.1],
        [3.5, 1.7, 6.4, 1.6],
        [2.0, 3.4, 4.1, 5.0],
        [7.3, 5.9, 8.9, 3.0],
    ]));
    check(Mat4::new([
        [1.9, 1.4, 4.0, 3.7],
        [7.8, 8.2, 9.1, 1.3],
        [3.2, 4.4, 3.9, 2.5],
        [7.1, 7.3, 3.5, 5.0],
    ]));
    check(Mat4::new([
        [6.0, 7.0, 4.0, 0.6],
        [0.9, 8.7, 6.2, 6.0],
        [0.2, 4.6, 3.7, 0.2],
        [8.4, 6.2, 7.6, 2.8],
    ]));
    check(Mat4::new([
        [5.1, 9.6, 4.6, 4.5],
        [1.5, 9.2, 2.3, 9.4],
        [5.6, 7.6, 0.4, 2.9],
        [0.6, 0.5, 4.3, 4.6],
    ]));
    check(Mat4::new([
        [3.0, 5.7, 8.6, 2.1],
        [6.2, 7.2, 0.1, 6.7],
        [5.3, 5.9, 5.8, 2.1],
        [9.4, 9.9, 9.8, 5.8],
    ]));
    check(Mat4::new([
        [4.3, 8.4, 2.0, 6.2],
        [2.3, 9.0, 4.6, 5.8],
        [5.5, 1.2, 8.8, 1.6],
        [4.5, 9.3, 4.8, 1.5],
    ]));
}
