#include #include "gtest/gtest.h" namespace mm { TEST(Utils, NumSignumZero) { assert(signum(0.0f) == 0); assert(signum(0l) == 0); assert(signum(0ull) == 0); assert(signum(0.0l) == 0); assert(signum(0) == 0); assert(signum(0.0) == 0); } TEST(Utils, NumSignumInfNan) { // just to define behaviour double nan = std::numeric_limits::quiet_NaN(); double inf = std::numeric_limits::infinity(); assert(signum(nan) == 0); assert(signum(inf) == 1); assert(signum(-inf) == -1); } TEST(Utils, NumSignumPositive) { assert(signum('a') == 1); assert(signum(5.4) == 1); assert(signum(1e-7) == 1); assert(signum(23452345ull) == 1); assert(signum(1e20f) == 1); assert(signum(-23452345ull) == 1); } TEST(Utils, NumSignumNegative) { assert(signum(-5.4) == -1); assert(signum(-1e-7) == -1); assert(signum(-1e20f) == -1); assert(signum(-23452345ll) == -1); } TEST(Utils, NumFloorCeil) { EXPECT_EQ(1, ifloor(1.3)); EXPECT_EQ(-2, ifloor(-1.3)); EXPECT_EQ(2, iceil(1.3)); EXPECT_EQ(-1, iceil(-1.3)); } TEST(Utils, NumIPowCompileTime) { EXPECT_EQ(1, ipow<0>(3.4)); EXPECT_EQ(1, ipow<0>(-1.4)); EXPECT_EQ(3.4, ipow<1>(3.4)); EXPECT_EQ(-1.4, ipow<1>(-1.4)); EXPECT_EQ(3.4*3.4*3.4, ipow<3>(3.4)); EXPECT_EQ(1.4*1.4, ipow<2>(-1.4)); } TEST(Utils, NumIPow) { EXPECT_EQ(1, ipow(3.4, 0)); EXPECT_EQ(1, ipow(-1.4, 0)); EXPECT_EQ(3.4, ipow(3.4, 1)); EXPECT_EQ(-1.4, ipow(-1.4, 1)); EXPECT_EQ(3.4*3.4*3.4, ipow(3.4, 3)); EXPECT_EQ(1.4*1.4, ipow(-1.4, 2)); float x = 1.4f; float r = 1.0f; for (int i = 0; i < 10; ++i) { EXPECT_FLOAT_EQ(r, ipow(x, i)); r *= x; } } TEST(Utils, IncrementCounter) { /// [Increment counter usage] Vec limit = {1, 2, 3}; Vec cnt; cnt.setZero(); std::vector> result; do { result.push_back(cnt); } while (incrementCounter(cnt, limit)); /// [Increment counter usage] std::vector> expected = { {0, 0, 0}, {0, 0, 1}, {0, 0, 2}, {0, 1, 0}, {0, 1, 1}, {0, 1, 2}}; EXPECT_EQ(expected, result); } TEST(Utils, IncrementCounterBothLimits) { Vec low = {-3, 2, 0}; Vec high = {-2, 4, 3}; Vec cnt = low; std::vector> result; do { result.push_back(cnt); } while (incrementCounter(cnt, low, high)); std::vector> expected = { {-3, 2, 0}, {-3, 2, 1}, {-3, 2, 2}, {-3, 3, 0}, {-3, 3, 1}, {-3, 3, 2}}; EXPECT_EQ(expected, result); } TEST(Utils, IncrementCounterCyclic) { /// [Cyclic counter usage] Vec low = {1, 0, 2}; Vec high = {0, 2, 1}; Vec size = {3, 3, 3}; Vec cnt = low; std::vector> result; do { result.push_back(cnt); } while (incrementCyclicCounter(cnt, low, high, size)); /// [Cyclic counter usage] std::vector> expected = { {1, 0, 2}, {1, 0, 0}, {1, 1, 2}, {1, 1, 0}, {2, 0, 2}, {2, 0, 0}, {2, 1, 2}, {2, 1, 0}}; EXPECT_EQ(expected, result); } TEST(Utils, NumLinspace1DBorder) { Range expected = {1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2}; Range result = linspace(Vec1d(1.0), Vec1d(2.0), 11); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i], result[i][0]);; } } TEST(Utils, NumLinspace1DBorderReversed) { Range expected = {2, 1.9, 1.8, 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, 1.1, 1}; Rangeresult = linspace(Vec1d(2.0), {1.0}, 11); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i], result[i][0]);; } } TEST(Utils, NumLinspaceDoubleBorder) { Range expected = {1, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2}; Range resultint = linspace(1.0, 2.0, 11); ASSERT_EQ(expected.size(), resultint.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i], resultint[i]);; } } TEST(Utils, NumLinspace1DNoBorder) { Range expected = {1.9, 1.8, 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, 1.1}; Range result = linspace(Vec1d(2.0), {1.0}, 9, false); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i], result[i][0]);; } } TEST(Utils, NumLinspaceDoubleNoBroder) { Range expected = {1.9, 1.8, 1.7, 1.6, 1.5, 1.4, 1.3, 1.2, 1.1}; Range resultint = linspace(2.0, 1.0, 9, false); ASSERT_EQ(expected.size(), resultint.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i], resultint[i]);; } } TEST(Utils, NumLinspace2DBorder) { Range> expected = { { 1, 3}, { 1, 3.1}, { 1, 3.2}, { 1, 3.3}, { 1, 3.4}, { 1, 3.5}, {1.1, 3}, {1.1, 3.1}, {1.1, 3.2}, {1.1, 3.3}, {1.1, 3.4}, {1.1, 3.5}, {1.2, 3}, {1.2, 3.1}, {1.2, 3.2}, {1.2, 3.3}, {1.2, 3.4}, {1.2, 3.5}}; Range result = linspace(Vec2d{1, 3}, {1.2, 3.5}, {3, 6}); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; } } TEST(Utils, NumLinspace2DNoBorder) { Range> expected = { {1.1, 3.1}, {1.1, 3.2}, {1.1, 3.3}, {1.1, 3.4}}; Range result = linspace(Vec2d{1, 3}, {1.2, 3.5}, {1, 4}, false); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; } } TEST(Utils, NumLinspace2DHalfBorder) { Range> expected = { { 1, 3.1}, { 1, 3.2}, { 1, 3.3}, { 1, 3.4}, {1.1, 3.1}, {1.1, 3.2}, {1.1, 3.3}, {1.1, 3.4}, {1.2, 3.1}, {1.2, 3.2}, {1.2, 3.3}, {1.2, 3.4}}; Range result = linspace(Vec2d{1, 3}, {1.2, 3.5}, {3, 4}, {true, false}); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; } } TEST(Utils, NumLinspace3DBorder) { Range> expected = { { 0, 1, 2}, { 0, 1, 2.5}, { 0, 1, 3}, { 0, 1.5, 2}, { 0, 1.5, 2.5}, { 0, 1.5, 3}, { 0, 2, 2}, { 0, 2, 2.5}, { 0, 2, 3}, {-0.5, 1, 2}, {-0.5, 1, 2.5}, {-0.5, 1, 3}, {-0.5, 1.5, 2}, {-0.5, 1.5, 2.5}, {-0.5, 1.5, 3}, {-0.5, 2, 2}, {-0.5, 2, 2.5}, {-0.5, 2, 3}, { -1, 1, 2}, { -1, 1, 2.5}, { -1, 1, 3}, { -1, 1.5, 2}, { -1, 1.5, 2.5}, { -1, 1.5, 3}, { -1, 2, 2}, { -1, 2, 2.5}, { -1, 2, 3}}; Range result = linspace(Vec3d{0, 1, 2}, {-1, 2, 3}, {3, 3, 3}); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; EXPECT_DOUBLE_EQ(expected[i][2], result[i][2]);; } } TEST(Utils, NumLinspace3DNoBorder) { Range> expected = {{-0.5, 1.5, 2.5}}; Range result = linspace(Vec3d{0, 1, 2}, {-1, 2, 3}, {1, 1, 1}, false); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; EXPECT_DOUBLE_EQ(expected[i][2], result[i][2]);; } } TEST(Utils, NumLinspace3DHalfBorder) { Range> expected = { {-0.5, 1, 2.5}, {-0.5, 1.5, 2.5}, {-0.5, 2, 2.5}}; Range result = linspace(Vec3d{0, 1, 2}, {-1, 2, 3}, {1, 3, 1}, {false, true, false}); ASSERT_EQ(expected.size(), result.size()); for (int i = 0; i < expected.size(); ++i) { EXPECT_DOUBLE_EQ(expected[i][0], result[i][0]);; EXPECT_DOUBLE_EQ(expected[i][1], result[i][1]);; EXPECT_DOUBLE_EQ(expected[i][2], result[i][2]);; } } TEST(Utils, NumBisectionSolve) { auto func = [](double x) -> double { return (3*std::sin(x*x + 0.4) + 0.1);}; double target = 2.35; double a = bisection(func, 0.0, 1.0, target, 1e-6, 20); EXPECT_NEAR(target, func(a), 1e-5); } TEST(Utils, NumBisectionHitMaxIterations) { auto func = [](double x) -> double { return (3*std::sin(x*x + 0.4) + 0.1);}; double target = 2.35; double a = bisection(func, 0.0, 1.0, target, 1e-6, 5); // must print error message EXPECT_NEAR(target, func(a), 1e-2); } } // namespace mm