Skip to content

Commit

Permalink
(chore): updating tests for quat_t (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
wpumacay committed Jul 23, 2023
1 parent 87cd7f1 commit ff9244e
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 57 deletions.
53 changes: 39 additions & 14 deletions tests/cpp/common_math_generators.hpp
Expand Up @@ -328,44 +328,69 @@ auto random_mat4(T val_range_min = static_cast<T>(-1.0),
//-------------------//

template <typename T>
class RandomQuaternion : public RandomValueBase<T, Quaternion<T>> {
class RandomQuaternion : public Catch::Generators::IGenerator<Quat<T>> {
public:
RandomQuaternion() : RandomValueBase<T, Quaternion<T>>(-1.0, 1.0) {}
RandomQuaternion()
// NOLINTNEXTLINE
: m_Gen(std::random_device{}()), m_Dist(-1.0, 1.0) {
static_cast<void>(next());
}

auto get() const -> const Quat<T>& override { return m_Value; }

auto next() -> bool override {
this->m_Value = {this->m_Dist(this->m_Gen), this->m_Dist(this->m_Gen),
this->m_Dist(this->m_Gen), this->m_Dist(this->m_Gen)};
m_Value = {m_Dist(m_Gen), m_Dist(m_Gen), m_Dist(m_Gen), m_Dist(m_Gen)};
return true;
}

private:
/// The method used to generate random numbers
std::minstd_rand m_Gen;
/// Distribution from which to generate random real values
std::uniform_real_distribution<T> m_Dist;
/// The random value to be exposed
Quat<T> m_Value;
};

template <typename T>
class RandomUnitQuaternion : public RandomValueBase<T, Quaternion<T>> {
class RandomUnitQuaternion : public Catch::Generators::IGenerator<Quat<T>> {
public:
RandomUnitQuaternion() : RandomValueBase<T, Quaternion<T>>(-1.0, 1.0) {}
RandomUnitQuaternion()
// NOLINTNEXTLINE
: m_Gen(std::random_device{}()), m_Dist(-1.0, 1.0) {
static_cast<void>(next());
}

auto get() const -> const Quat<T>& override { return m_Value; }

auto next() -> bool override {
this->m_Value = {this->m_Dist(this->m_Gen), this->m_Dist(this->m_Gen),
this->m_Dist(this->m_Gen), this->m_Dist(this->m_Gen)};
this->m_Value.normalize();
m_Value = {m_Dist(m_Gen), m_Dist(m_Gen), m_Dist(m_Gen), m_Dist(m_Gen)};
m_Value.normalize();
return true;
}

private:
/// The method used to generate random numbers
std::minstd_rand m_Gen;
/// Distribution from which to generate random real values
std::uniform_real_distribution<T> m_Dist;
/// The random value to be exposed
Quat<T> m_Value;
};

//--------------------//
// Generator wrappers //
//--------------------//

template <typename T>
auto random_quaternion() -> Catch::Generators::GeneratorWrapper<Quaternion<T>> {
return Catch::Generators::GeneratorWrapper<Quaternion<T>>(
auto random_quaternion() -> Catch::Generators::GeneratorWrapper<Quat<T>> {
return Catch::Generators::GeneratorWrapper<Quat<T>>(
Catch::Generators::pf::make_unique<RandomQuaternion<T>>());
}

template <typename T>
auto random_unit_quaternion()
-> Catch::Generators::GeneratorWrapper<Quaternion<T>> {
return Catch::Generators::GeneratorWrapper<Quaternion<T>>(
auto random_unit_quaternion() -> Catch::Generators::GeneratorWrapper<Quat<T>> {
return Catch::Generators::GeneratorWrapper<Quat<T>>(
Catch::Generators::pf::make_unique<RandomUnitQuaternion<T>>());
}

Expand Down
9 changes: 9 additions & 0 deletions tests/cpp/common_math_helpers.hpp
Expand Up @@ -100,4 +100,13 @@ constexpr auto func_all_close(const ::math::Matrix4<T>& mat,
}
// clang-format on

template <typename T>
constexpr auto func_all_close(const ::math::Quaternion<T>& quat, T w, T x, T y,
T z, T eps) -> bool {
return func_value_close<T>(quat.w(), w, eps) &&
func_value_close<T>(quat.x(), x, eps) &&
func_value_close<T>(quat.y(), y, eps) &&
func_value_close<T>(quat.z(), z, eps);
}

} // namespace math
83 changes: 40 additions & 43 deletions tests/cpp/test_quat_type.cpp
@@ -1,6 +1,9 @@
#include <catch2/catch.hpp>
#include <math/quat_t.hpp>

#include "./common_math_helpers.hpp"
#include "./common_math_generators.hpp"

#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wimplicit-float-conversion"
Expand All @@ -14,60 +17,48 @@
#pragma warning(disable : 4305)
#endif

constexpr double RANGE_MIN = -10.0;
constexpr double RANGE_MAX = 10.0;

// NOLINTNEXTLINE
#define GenRandomValue(Type, Nsamples) \
GENERATE(take(Nsamples, random(static_cast<Type>(RANGE_MIN), \
static_cast<Type>(RANGE_MAX))))

template <typename T>
constexpr auto FuncClose(T a, T b, T eps) -> bool {
return ((a - b) < eps) && ((a - b) > -eps);
}

template <typename T>
auto FuncAllClose(const math::Quaternion<T>& quat, T w, T x, T y, T z) -> bool {
constexpr T EPSILON = static_cast<T>(math::EPS);
return FuncClose<T>(quat.w(), w, EPSILON) &&
FuncClose<T>(quat.x(), x, EPSILON) &&
FuncClose<T>(quat.y(), y, EPSILON) &&
FuncClose<T>(quat.z(), z, EPSILON);
}
constexpr double USER_RANGE_MIN = -10.0;
constexpr double USER_RANGE_MAX = 10.0;
constexpr double USER_EPSILON = 1e-5;

// NOLINTNEXTLINE
TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
"[quat_t][template]", math::float32_t, math::float64_t) {
"[quat_t][template]", ::math::float32_t, ::math::float64_t) {
using T = TestType;
using Quat = math::Quaternion<T>;
using Euler = math::Euler<T>;
using Mat3 = math::Matrix3<T>;
using Quat = ::math::Quaternion<T>;
using Euler = ::math::Euler<T>;
using Mat3 = ::math::Matrix3<T>;

constexpr T EPSILON = static_cast<T>(USER_EPSILON);
constexpr T RANGE_MIN = static_cast<T>(USER_RANGE_MIN);
constexpr T RANGE_MAX = static_cast<T>(USER_RANGE_MAX);

SECTION("Default constructor") {
Quat q;
FuncAllClose<T>(q, 1.0, 0.0, 0.0, 0.0);
REQUIRE(::math::func_all_close<T>(q, 1.0, 0.0, 0.0, 0.0, EPSILON));
}

SECTION("From single scalar argument") {
constexpr int NUM_SAMPLES = 32;
auto val_w = GenRandomValue(T, NUM_SAMPLES);
constexpr auto NUM_SAMPLES = 32;
auto val_w = gen_random_value(T, RANGE_MIN, RANGE_MAX, NUM_SAMPLES);

Quat q(val_w); // Real valued quaternion
FuncAllClose<T>(q, val_w, 0.0, 0.0, 0.0);
REQUIRE(::math::func_all_close<T>(q, val_w, 0.0, 0.0, 0.0, EPSILON));
}

SECTION("From four scalar arguments, and from initializer_list") {
constexpr int NUM_SAMPLES = 4;
auto val_w = GenRandomValue(T, NUM_SAMPLES);
auto val_x = GenRandomValue(T, NUM_SAMPLES);
auto val_y = GenRandomValue(T, NUM_SAMPLES);
auto val_z = GenRandomValue(T, NUM_SAMPLES);
constexpr auto NUM_SAMPLES = 4;
auto val_w = gen_random_value(T, RANGE_MIN, RANGE_MAX, NUM_SAMPLES);
auto val_x = gen_random_value(T, RANGE_MIN, RANGE_MAX, NUM_SAMPLES);
auto val_y = gen_random_value(T, RANGE_MIN, RANGE_MAX, NUM_SAMPLES);
auto val_z = gen_random_value(T, RANGE_MIN, RANGE_MAX, NUM_SAMPLES);

Quat q_1(val_w, val_x, val_y, val_z);
Quat q_2 = {val_w, val_x, val_y, val_z};
FuncAllClose<T>(q_1, val_w, val_x, val_y, val_z);
FuncAllClose<T>(q_2, val_w, val_x, val_y, val_z);
REQUIRE(::math::func_all_close<T>(q_1, val_w, val_x, val_y, val_z,
EPSILON));
REQUIRE(::math::func_all_close<T>(q_2, val_w, val_x, val_y, val_z,
EPSILON));
}

SECTION("From rotation matrix") {
Expand All @@ -79,7 +70,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(rotmat);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, sin_half, 0.0, 0.0));
REQUIRE(::math::func_all_close<T>(q, cos_half, sin_half, 0.0, 0.0,
EPSILON));
}

// rot = Rot_y(t)
Expand All @@ -90,7 +82,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(rotmat);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, 0.0, sin_half, 0.0));
REQUIRE(::math::func_all_close<T>(q, cos_half, 0.0, sin_half, 0.0,
EPSILON));
}

// rot = Rot_z(t)
Expand All @@ -101,7 +94,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(rotmat);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, 0.0, 0.0, sin_half));
REQUIRE(::math::func_all_close<T>(q, cos_half, 0.0, 0.0, sin_half,
EPSILON));
}
}

Expand All @@ -112,7 +106,7 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Euler e(0.0, 0.0, 0.0, ::math::euler::Order::XYZ,
::math::euler::Convention::INTRINSIC);
Quat q(e);
REQUIRE(FuncAllClose<T>(q, 1.0, 0.0, 0.0, 0.0));
REQUIRE(::math::func_all_close<T>(q, 1.0, 0.0, 0.0, 0.0, EPSILON));
}

// ea = (t, 0.0, 0.0, XYZ, INTRINSIC)
Expand All @@ -123,7 +117,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(e);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, sin_half, 0.0, 0.0));
REQUIRE(::math::func_all_close<T>(q, cos_half, sin_half, 0.0, 0.0,
EPSILON));
}

// ea = (0.0, t, 0.0, XYZ, INTRINSIC)
Expand All @@ -134,7 +129,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(e);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, 0.0, sin_half, 0.0));
REQUIRE(::math::func_all_close<T>(q, cos_half, 0.0, sin_half, 0.0,
EPSILON));
}

// ea = (0.0, 0.0, t, XYZ, INTRINSIC)
Expand All @@ -145,7 +141,8 @@ TEMPLATE_TEST_CASE("Quaternion class (quat_t) constructors",
Quat q(e);
auto cos_half = std::cos(angle / 2.0);
auto sin_half = std::sin(angle / 2.0);
REQUIRE(FuncAllClose<T>(q, cos_half, 0.0, 0.0, sin_half));
REQUIRE(::math::func_all_close<T>(q, cos_half, 0.0, 0.0, sin_half,
EPSILON));
}
}
}
Expand Down

0 comments on commit ff9244e

Please sign in to comment.