Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F91217595
misc.cpp
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Sat, Nov 9, 02:02
Size
7 KB
Mime Type
text/x-c++
Expires
Mon, Nov 11, 02:02 (2 d)
Engine
blob
Format
Raw Data
Handle
22222424
Attached To
rSPECMICP SpecMiCP / ReactMiCP
misc.cpp
View Options
#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
Log In to Comment