From 797db3e021a702cb575ac06a788d121d44d6817d Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Mon, 23 Oct 2023 15:54:57 -0400 Subject: [PATCH] compile fixes + unit tests --- CMakeLists.txt | 4 ++-- cmake/xo_distributionConfig.cmake.in | 2 ++ include/xo/distribution/Normal.hpp | 5 ++++- include/xo/distribution/Uniform.hpp | 22 ++++++++++++++++------ src/distribution/CMakeLists.txt | 5 +++++ src/distribution/Normal.cpp | 9 +++++++++ utest/CMakeLists.txt | 19 +++++++++++++++++++ utest/Normal.test.cpp | 24 ++++++++++++++++++++++++ utest/Uniform.test.cpp | 27 +++++++++++++++++++++++++++ utest/distribution_utest_main.cpp | 6 ++++++ 10 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 src/distribution/CMakeLists.txt create mode 100644 src/distribution/Normal.cpp create mode 100644 utest/CMakeLists.txt create mode 100644 utest/Normal.test.cpp create mode 100644 utest/Uniform.test.cpp create mode 100644 utest/distribution_utest_main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 467f52cc..153acdac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,9 @@ include(xo_macros/xo-project-macros) xo_cxx_toplevel_options() #add_subdirectory(example) -#add_subdirectory(uteest) +add_subdirectory(src/distribution) # note refcnt dep -> not header-only +add_subdirectory(utest) -xo_add_headeronly_library4(xo_distribution ${PROJECT_NAME}Targets) xo_export_cmake_config(${PROJECT_NAME} ${PROJECT_VERSION} ${PROJECT_NAME}Targets) # ---------------------------------------------------------------- diff --git a/cmake/xo_distributionConfig.cmake.in b/cmake/xo_distributionConfig.cmake.in index 3c6c4bd4..d906d196 100644 --- a/cmake/xo_distributionConfig.cmake.in +++ b/cmake/xo_distributionConfig.cmake.in @@ -1,4 +1,6 @@ @PACKAGE_INIT@ +include(CMakeFindDependencyMacro) +find_dependency(refcnt) include("${CMAKE_CURRENT_LIST_DIR}/xo_distributionTargets.cmake") check_required_components("@PROJECT_NAME@") diff --git a/include/xo/distribution/Normal.hpp b/include/xo/distribution/Normal.hpp index 5cef9ed1..6d4d88e1 100644 --- a/include/xo/distribution/Normal.hpp +++ b/include/xo/distribution/Normal.hpp @@ -2,7 +2,7 @@ #pragma once -#include "distribution/Distribution.hpp" +#include "Distribution.hpp" #include namespace xo { @@ -13,6 +13,9 @@ namespace xo { public: Normal() = default; + /* N(0,1): mean 0, sdev 1 */ + static ref::rp unit() { return new Normal(); } + /* normal probability density: * * x^2 diff --git a/include/xo/distribution/Uniform.hpp b/include/xo/distribution/Uniform.hpp index d1bc8668..e40c62a6 100644 --- a/include/xo/distribution/Uniform.hpp +++ b/include/xo/distribution/Uniform.hpp @@ -11,21 +11,31 @@ namespace xo { public: Uniform(double lo, double hi) : lo_(lo), hi_(hi) {} - static Uniform unit() { return Uniform(0.0, 1.0); } + static ref::rp unit() { return new Uniform(0.0, 1.0); } + + static double density_impl(double lo, double hi, double x) { + if (x <= lo) + return 0.0; + if (x >= hi) + return 0.0; - static double density_impl(double lo, double hi) { return 1.0 / (hi - lo); } /*density_impl*/ static double distr_impl(double lo, double hi, double x) { + if (x <= lo) + return 0.0; + if (x >= hi) + return 1.0; + return (x - lo) / (hi - lo); } /*distr_impl*/ double lo() const { return lo_; } double hi() const { return hi_; } - double density(double /*x*/) const { - return density_impl(this->lo_, this->hi_); + double density(double x) const { + return density_impl(this->lo_, this->hi_, x); } /*density*/ double distribution(double x) const { @@ -40,8 +50,8 @@ namespace xo { private: /* Invariant: .lo < .hi */ - double lo_; - double hi_; + double lo_ = 0.0; + double hi_ = 1.0; }; /*Uniform*/ } /*namespace distribution*/ } /*namespace xo*/ diff --git a/src/distribution/CMakeLists.txt b/src/distribution/CMakeLists.txt new file mode 100644 index 00000000..56ce881e --- /dev/null +++ b/src/distribution/CMakeLists.txt @@ -0,0 +1,5 @@ +set(SELF_LIB distribution) +set(SELF_SRCS Normal.cpp) + +xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS}) +xo_dependency(${SELF_LIB} refcnt) diff --git a/src/distribution/Normal.cpp b/src/distribution/Normal.cpp new file mode 100644 index 00000000..f1a0f9ca --- /dev/null +++ b/src/distribution/Normal.cpp @@ -0,0 +1,9 @@ +/* @file Normal.cpp */ + +#include "Normal.hpp" + +namespace xo { + +} /*namespace xo*/ + +/* end Normal.cpp */ diff --git a/utest/CMakeLists.txt b/utest/CMakeLists.txt new file mode 100644 index 00000000..27b1a78b --- /dev/null +++ b/utest/CMakeLists.txt @@ -0,0 +1,19 @@ +# build unittest distribution/utest + +set(SELF_EXE utest.distribution) +set(SELF_SRCS + distribution_utest_main.cpp + Normal.test.cpp + Uniform.test.cpp) + +add_executable(${SELF_EXE} ${SELF_SRCS}) +xo_include_options2(${SELF_EXE}) + +add_test(NAME ${SELF_EXE} COMMAND ${SELF_EXE}) +target_code_coverage(${SELF_EXE} AUTO ALL) + +xo_self_dependency(${SELF_EXE} distribution) + +xo_external_target_dependency(${SELF_EXE} Catch2 Catch2::Catch2) + +# end CMakeLists.txt diff --git a/utest/Normal.test.cpp b/utest/Normal.test.cpp new file mode 100644 index 00000000..70f0a7ad --- /dev/null +++ b/utest/Normal.test.cpp @@ -0,0 +1,24 @@ +/* @file Normal.test.cpp */ + +#include "xo/distribution/Normal.hpp" +#include + +namespace xo { + using xo::distribution::Normal; + + namespace ut { + TEST_CASE("normal", "[distribution]") { + auto n01 = Normal::unit(); + + CHECK(n01->cdf(-3.0) == Approx(0.001349898).margin(1e-9)); + CHECK(n01->cdf(-2.0) == Approx(0.0227501319).margin(1e-9)); + CHECK(n01->cdf(-1.0) == Approx(0.1586552539).margin(1e-9)); + CHECK(n01->cdf(0.0) == 0.5); + CHECK(n01->cdf(1.0) == 1.0 - n01->cdf(-1.0)); + CHECK(n01->cdf(2.0) == 1.0 - n01->cdf(-2.0)); + CHECK(n01->cdf(3.0) == 1.0 - n01->cdf(-3.0)); + } /*TEST_CASE(normal)*/ + } /*namespace ut*/ +} /*namespace xo*/ + +/* end Normal.test.cpp */ diff --git a/utest/Uniform.test.cpp b/utest/Uniform.test.cpp new file mode 100644 index 00000000..10153d66 --- /dev/null +++ b/utest/Uniform.test.cpp @@ -0,0 +1,27 @@ +/* @file Uniform.test.cpp */ + +#include "xo/distribution/Uniform.hpp" +#include + +namespace xo { + using xo::distribution::Uniform; + + namespace ut { + TEST_CASE("uniform", "[distribution]") { + auto u = Uniform::unit(); + + CHECK(u->cdf(-3.0) == 0.0); + CHECK(u->cdf(-2.0) == 0.0); + CHECK(u->cdf(-1.0) == 0.0); + CHECK(u->cdf(0.0) == 0.0); + CHECK(u->cdf(0.05) == 0.05); + CHECK(u->cdf(0.5) == 0.5); + CHECK(u->cdf(0.95) == 0.95); + CHECK(u->cdf(1.0) == 1.0); + CHECK(u->cdf(2.0) == 1.0); + CHECK(u->cdf(3.0) == 1.0); + } /*TEST_CASE(uniform)*/ + } /*namespace ut*/ +} /*namespace xo*/ + +/* end Uniform.test.cpp */ diff --git a/utest/distribution_utest_main.cpp b/utest/distribution_utest_main.cpp new file mode 100644 index 00000000..b5e05a73 --- /dev/null +++ b/utest/distribution_utest_main.cpp @@ -0,0 +1,6 @@ +/* file distribution_utest_main.cpp */ + +#define CATCH_CONFIG_MAIN +#include "catch2/catch.hpp" + +/* end distribution_utest_main.cpp */