Skip to content
Snippets Groups Projects

Jschakib

Merged Julian Schakib requested to merge jschakib into develop
All threads resolved!
+ 155
0
#include "test.hh"
static tg::mat3 rndMat3(tg::rng& rng)
{
auto b = 5.0f;
auto dBox = tg::box3(-tg::pos3(b), tg::pos3(b));
auto mat = tg::mat3();
for (auto c = 0; c < 3; c++)
mat.col(c) = tg::vec3(uniform(rng, dBox));
return mat;
}
static tg::mat2 rndMat2(tg::rng& rng)
{
auto b = 5.0f;
auto dBox = tg::box2(-tg::pos2(b), tg::pos2(b));
auto mat = tg::mat2();
for (auto c = 0; c < 2; c++)
mat.col(c) = tg::vec2(uniform(rng, dBox));
return mat;
}
static tg::mat3 rndInvertibleMat3(tg::rng& rng)
{
// build matrix from random transformations (invertible)
auto rd1 = tg::box1(-1.0f, 1.0f);
auto a = uniform(rng, rd1).x;
auto b = uniform(rng, rd1).x;
auto c = uniform(rng, rd1).x;
auto mat = tg::scaling(tg::size2(b, c));
mat = tg::rotation_around(tg::pos2(a, c), tg::degree(b * 360.0f)) * mat;
mat = tg::translation(tg::vec2(a, b) * 10.0f) * mat;
return mat;
}
static tg::mat2 rndInvertibleMat2(tg::rng& rng)
{
auto rd1 = tg::box1(-1.0f, 1.0f);
auto a = uniform(rng, rd1).x;
auto b = uniform(rng, rd1).x;
auto mat = tg::scaling(tg::size1(b));
mat = tg::translation(tg::vec1(a) * 10.0f) * mat;
return mat;
}
TG_FUZZ_TEST(TypedGeometry, Determinant)
{
auto rd1 = tg::box1(0.0f, 1.0f);
// matrices with obvious determinants
{
// 1D
const auto D = 1;
auto mat = tg::mat<D, D, tg::f32>::zero;
CHECK(determinant(mat) == 0.0f);
mat = tg::mat<D, D, tg::f32>::identity;
CHECK(determinant(mat) == doctest::Approx(1.0f).epsilon(1e-5));
auto rf = uniform(rng, rd1).x;
mat = tg::mat<D, D, tg::f32>::diag(rf);
auto res = tg::pow(rf, D);
CHECK(determinant(mat) == doctest::Approx(res).epsilon(1e-5));
}
{
// 2D
const auto D = 2;
auto mat = tg::mat<D, D, tg::f32>::zero;
CHECK(determinant(mat) == 0.0f);
mat = tg::mat<D, D, tg::f32>::identity;
CHECK(determinant(mat) == doctest::Approx(1.0f).epsilon(1e-5));
auto rf = uniform(rng, rd1).x;
mat = tg::mat<D, D, tg::f32>::diag(rf);
auto res = tg::pow(rf, D);
CHECK(determinant(mat) == doctest::Approx(res).epsilon(1e-5));
}
{
// 3D
const auto D = 3;
auto mat = tg::mat<D, D, tg::f32>::zero;
CHECK(determinant(mat) == 0.0f);
mat = tg::mat<D, D, tg::f32>::identity;
CHECK(determinant(mat) == doctest::Approx(1.0f).epsilon(1e-5));
auto rf = uniform(rng, rd1).x;
mat = tg::mat<D, D, tg::f32>::diag(rf);
auto res = tg::pow(rf, D);
CHECK(determinant(mat) == doctest::Approx(res).epsilon(1e-5));
}
// random DxD matrices for 3D
{
auto matA = rndMat3(rng);
auto matB = rndMat3(rng);
// confirm multiplicativity
CHECK(determinant(matA * matB) == doctest::Approx(determinant(matA) * determinant(matB)).epsilon(1e-5));
matA = rndInvertibleMat3(rng);
matB = rndInvertibleMat3(rng);
// if invertible det != 0
CHECK(determinant(matA) != doctest::Approx(0.0f).epsilon(1e-5));
// CHECK(determinant(matB) != doctest::Approx(0.0f).epsilon(1e-5));
// confirm multiplicativity
auto detA = determinant(matA);
auto detB = determinant(matB);
CHECK(determinant(matA * matB) == doctest::Approx(detA * detB).epsilon(1e-5));
auto invA = inverse(matA);
auto invB = inverse(matB);
CHECK(determinant(invA) == doctest::Approx(1.0f / detA).epsilon(1e-5));
CHECK(determinant(invB) == doctest::Approx(1.0f / detB).epsilon(1e-5));
}
// random DxD matrices for 2D
{
auto matA = rndMat2(rng);
auto matB = rndMat2(rng);
// confirm multiplicativity
CHECK(determinant(matA * matB) == doctest::Approx(determinant(matA) * determinant(matB)).epsilon(1e-5));
matA = rndInvertibleMat2(rng);
matB = rndInvertibleMat2(rng);
// if invertible det != 0
CHECK(determinant(matA) != doctest::Approx(0.0f).epsilon(1e-5));
CHECK(determinant(matB) != doctest::Approx(0.0f).epsilon(1e-5));
// confirm multiplicativity
auto detA = determinant(matA);
auto detB = determinant(matB);
CHECK(determinant(matA * matB) == doctest::Approx(detA * detB).epsilon(1e-5));
auto invA = inverse(matA);
auto invB = inverse(matB);
CHECK(determinant(invA) == doctest::Approx(1.0f / detA).epsilon(1e-5));
CHECK(determinant(invB) == doctest::Approx(1.0f / detB).epsilon(1e-5));
}
}
Loading