init
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
cmake_minimum_required(VERSION 3.28)
|
||||
|
||||
# define CXX interface library
|
||||
|
||||
# define target & alias (for other projects consuming the "source-tree")
|
||||
add_library(iue-num_num INTERFACE)
|
||||
|
||||
# define sources of target
|
||||
target_sources(iue-num_num
|
||||
INTERFACE FILE_SET public_headers TYPE HEADERS BASE_DIRS ${PROJECT_SOURCE_DIR} FILES numerics.hpp)
|
||||
|
||||
# define installation step
|
||||
install(TARGETS iue-num_num EXPORT iue-num-export
|
||||
FILE_SET public_headers DESTINATION "./")
|
||||
|
||||
# define test
|
||||
|
||||
if(BUILD_TESTING AND PROJECT_IS_TOP_LEVEL)
|
||||
add_executable(iue-num_num.test numerics.test.cpp)
|
||||
target_link_libraries(iue-num_num.test iue-num_num)
|
||||
add_test(NAME iue-num_num.test COMMAND iue-num_num.test)
|
||||
endif()
|
||||
|
||||
# export targets for consuming cmake projects
|
||||
|
||||
# generate and install a .cmake file to allow dependend projects consuming the "install-tree" to import all targets
|
||||
install(EXPORT iue-num-export DESTINATION "iue-num" )
|
||||
|
||||
# allow dependend projects consuming the "build-tree" to use all targets
|
||||
export(EXPORT iue-num-export)
|
||||
@@ -0,0 +1,26 @@
|
||||
/// @file
|
||||
/// @brief Supporting functionality for numeric calculations with floating point values
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cmath> // std::abs, std::max, std::min
|
||||
|
||||
namespace iue::num {
|
||||
|
||||
/// @brief Checks if two floating point values are close to each other
|
||||
/// @param a First value
|
||||
/// @param b Second value
|
||||
/// @param tabs Tolerance for the absolute difference:
|
||||
/// abs(a - b) < tabs
|
||||
/// @param trel Tolerance for the relative error (using the larger absolute value as reference):
|
||||
/// abs(a b) < trel * max(abs(a),abs(b))
|
||||
/// @return true if the stronger of the two tolerances is met, false otherwise
|
||||
inline bool isclose(double a, double b, double tabs = 0.0, double trel = 1e-9) {
|
||||
if (a == b) // for infinite values (which should be considered close to themselves)
|
||||
return true;
|
||||
auto abs_diff = std::abs(a - b); // absolte difference
|
||||
auto trel_ref = std::max(std::abs(a), std::abs(b)); // reference for the relative threshold
|
||||
return abs_diff < std::max(tabs, trel * trel_ref);
|
||||
}
|
||||
|
||||
} // namespace iue::num
|
||||
@@ -0,0 +1,69 @@
|
||||
/// @file
|
||||
/// @brief Test for iue::num::islcose
|
||||
|
||||
#include "iue-num/numerics.hpp" // iue::num::islcose
|
||||
|
||||
#include <cassert> // assert
|
||||
#include <cstdlib> // EXIT_SUCCESS
|
||||
#include <limits> // std::numeric_limits
|
||||
|
||||
int main() {
|
||||
|
||||
const double eps = std::numeric_limits<double>::epsilon();
|
||||
const double inf = std::numeric_limits<double>::infinity();
|
||||
const double nan = std::numeric_limits<double>::quiet_NaN();
|
||||
|
||||
{ // infinity
|
||||
|
||||
assert(iue::num::isclose(inf, inf, 0.0, 0.0));
|
||||
assert(iue::num::isclose(-inf, -inf, 0.0, 0.0));
|
||||
assert(!iue::num::isclose(-inf, inf, 0.0, 0.0));
|
||||
assert(!iue::num::isclose(inf, -inf, 0.0, 0.0));
|
||||
}
|
||||
|
||||
{ // nan
|
||||
assert(!iue::num::isclose(nan, nan, inf, inf));
|
||||
}
|
||||
|
||||
{ // around 1.0
|
||||
double a = 1.0;
|
||||
double b = 1.0 + eps;
|
||||
|
||||
// rel error
|
||||
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
|
||||
assert(!iue::num::isclose(a, b, 0.0, 0.0));
|
||||
|
||||
// abs error
|
||||
assert(iue::num::isclose(a, b, 2 * eps, 0.0));
|
||||
assert(!iue::num::isclose(a, b, 0.0, 0.0));
|
||||
}
|
||||
|
||||
{ // around 1e10
|
||||
double a = 1.0 * 1e10;
|
||||
double b = (1.0 + eps) * 1e10;
|
||||
|
||||
// rel error
|
||||
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
|
||||
assert(!iue::num::isclose(a, b, 0.0, 0.0));
|
||||
|
||||
// abs error
|
||||
assert(iue::num::isclose(a, b, 1e10 * 2 * eps, 0.0));
|
||||
assert(!iue::num::isclose(a, b, 1e9 * 2 * eps, 0.0));
|
||||
}
|
||||
|
||||
{ // around 1e-10
|
||||
|
||||
double a = 1.0 * 1e-10;
|
||||
double b = (1.0 + eps) * 1e-10;
|
||||
|
||||
// rel error
|
||||
assert(iue::num::isclose(a, b, 0.0, 2 * eps));
|
||||
assert(!iue::num::isclose(a, b, 0.0, 0.0));
|
||||
|
||||
// abs error
|
||||
assert(iue::num::isclose(a, b, 1e-10 * 2 * eps, 0.0));
|
||||
assert(!iue::num::isclose(a, b, 1e-11 * 2 * eps, 0.0));
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
Reference in New Issue
Block a user