Page MenuHomec4science

misc.cpp
No OneTemporary

File Metadata

Created
Sat, Nov 9, 02:02

misc.cpp

#include "catch.hpp"
#include "utils/log.hpp"
#include "utils/timer.hpp"
#include "physics/maths.hpp"
#include "utils/moving_average.hpp"
#include "utils/perfs_handler.hpp"
#include "utils/options_handler.hpp"
#include "utils/scope_guard.hpp"
#include <sstream>
using namespace specmicp;
// TOC
// =======================
//
// 1 - Logger
// 2 - Timer
// 3 - Average
// 4 - Moving Average
// 5 - Performance handler
// 6 - Options handler
// 7 - Scope guard
// Logger
// =======================
TEST_CASE("Logger", "[io],[log]") {
SECTION("Non init logging") {
init_logger(nullptr, logger::LogLevel::Warning);
// compilation test, and runtime test of not failling nullptr
SPAM << "Spam";
DEBUG << "Debug";
INFO << "Info";
WARNING << "Warning";
ERROR << "Error";
CRITICAL << "Critical";
}
SECTION("Level test") {
std::stringstream stream_log;
init_logger(&stream_log, logger::LogLevel::Warning);
SPAM << "Spam";
REQUIRE(stream_log.str().size() == 0);
DEBUG << "Debug";
REQUIRE(stream_log.str().size() == 0);
INFO << "Info";
REQUIRE(stream_log.str().size() == 0);
WARNING << "Warning";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
ERROR << "Error";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
CRITICAL << "Critical";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
init_logger(&stream_log, logger::LogLevel::Debug);
SPAM << "Spam";
REQUIRE(stream_log.str().size() == 0);
DEBUG << "Debug";
#ifdef NDEBUG
REQUIRE(stream_log.str().size() == 0);
#else
REQUIRE(stream_log.str().size() != 0);
#endif
stream_log.str("");
INFO << "Info";
#ifdef NDEBUG
REQUIRE(stream_log.str().size() == 0);
#else
REQUIRE(stream_log.str().size() != 0);
#endif
stream_log.str("");
WARNING << "Warning";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
ERROR << "Error";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
CRITICAL << "Critical";
REQUIRE(stream_log.str().size() != 0);
stream_log.str("");
}
}
// Timer
// =======================
TEST_CASE("Timer", "[time],[CPU]") {
SECTION("Timer test") {
Timer timer;
timer.stop();
CHECK(timer.elapsed_time() >= 0.0);
timer.start();
timer.stop();
CHECK(timer.elapsed_time() >= 0.0);
CHECK(timer.get_stop() >= timer.get_start());
CHECK(timer.get_ctime_start() != nullptr);
CHECK(timer.get_ctime_stop() != nullptr);
}
}
// Average
// ====================
#define test_average(method, a, b, sol) \
CHECK(average<method>(a, b) == Approx(sol).epsilon(1e-10));
#define test_average_vector(method, vector, sol) \
CHECK(average<method>(vector) == Approx(sol).epsilon(1e-10));
TEST_CASE("Average", "[average],[maths]") {
Vector test_vector(4);
test_vector << 1.0, 2.0, 3.0, 4.0;
SECTION("Arithmetic average") {
test_average(Average::arithmetic, 1.0, 1.0, 1.0);
test_average(Average::arithmetic, 2.0, 1.0, 1.5);
test_average(Average::arithmetic, -1.0, 1.0, 0.0);
test_average_vector(Average::arithmetic, test_vector, 10.0/4);
}
SECTION("Harmonic average") {
test_average(Average::harmonic, 1.0, 1.0, 1.0);
test_average(Average::harmonic, 2.0, 1.0, 2.0/(1+0.5));
test_average_vector(Average::harmonic, test_vector, 1.92);
}
SECTION("Geometric average") {
test_average(Average::geometric, 1.0, 1.0, 1.0);
test_average(Average::geometric, 1.0, 2.0, std::sqrt(2.0));
test_average_vector(Average::geometric, test_vector, std::pow(24.0, 1.0/4.0));
}
}
#undef test_average
#undef test_average_vector
// Moving Average
// =======================
TEST_CASE("Moving average", "[average],[timestep]") {
SECTION("Moving average test") {
utils::ExponentialMovingAverage moving_average(0.1, 1.0);
REQUIRE(moving_average.current_value() == 1.0);
CHECK(moving_average.add_point(1.0) == 1.0);
CHECK(moving_average.add_point(2.0) == 1.1);
REQUIRE(moving_average.add_point(3.0) == 0.9*1.1+0.3);
moving_average.reset(1.0);
REQUIRE(moving_average.current_value() == 1.0);
moving_average.set_alpha(0.2);
REQUIRE(moving_average.add_point(2.0) == Approx(0.8+0.4));
}
}
// Performance handler
// =======================
struct MockPerf
{
scalar_t residuals {-1};
index_t nb_iterations {-1};
};
class MockSolverPerf:
public PerformanceHandler<MockPerf>
{
public:
MockSolverPerf() {}
void do_stuff() {
get_perfs().residuals = 1e-6;
get_perfs().nb_iterations = 10;
}
void reset_solver() {
reset_perfs();
}
};
TEST_CASE("PerformanceHandler", "[performance],[base]") {
SECTION("Performance handler test") {
auto my_solver = MockSolverPerf();
const auto& perfs = my_solver.get_perfs();
CHECK(perfs.nb_iterations == -1);
CHECK(perfs.residuals == -1);
my_solver.do_stuff();
CHECK(perfs.nb_iterations == 10);
CHECK(perfs.residuals == 1e-6);
my_solver.reset_solver();
CHECK(perfs.nb_iterations == -1);
CHECK(perfs.residuals == -1);
}
}
// Options handler
// =======================
struct MockOptions
{
MockOptions()
{}
MockOptions(scalar_t res, index_t max_iter):
residuals(res),
max_iterations(max_iter)
{}
scalar_t residuals {1e-6};
index_t max_iterations {100};
};
class MockSolverOptions:
public OptionsHandler<MockOptions>
{
public:
MockSolverOptions() {}
MockSolverOptions(scalar_t res, index_t max_iter):
OptionsHandler(res, max_iter)
{}
};
TEST_CASE("Options handler", "[options],[base]") {
SECTION("Options handler test") {
auto my_solver_default = MockSolverOptions();
const auto& ro_options = my_solver_default.get_options();
CHECK(ro_options.max_iterations == 100);
CHECK(ro_options.residuals == 1e-6);
auto& rw_options = my_solver_default.get_options();
rw_options.max_iterations = 10;
rw_options.residuals = 1e-4;
CHECK(ro_options.max_iterations == 10);
CHECK(ro_options.residuals == 1e-4);
}
SECTION("Options handler - non default initialization") {
auto my_solver = MockSolverOptions(1e-4, 10);
const auto& ro_options = my_solver.get_options();
CHECK(ro_options.max_iterations == 10);
CHECK(ro_options.residuals == 1e-4);
}
}
// ScopeGuard
static void will_fail(bool& hop) {
auto guard = utils::make_scope_guard([&hop]{hop=true;});
throw std::runtime_error("fail on purpose");
guard.release();
}
static void dont_fail(bool& hop) {
auto guard = utils::make_scope_guard([&hop]{hop=true;});
hop = false;
guard.release();
}
TEST_CASE("Scope guard", "[utils]") {
SECTION("Catch error") {
bool hop = false;
REQUIRE_THROWS_AS(will_fail(hop), std::runtime_error);
CHECK(hop == true);
dont_fail(hop);
CHECK(hop == false);
}
}

Event Timeline