diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ca37570 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# ---> Vim +# Swap +[._]*.s[a-v][a-z] +!*.svg # comment out if you don't need vector files +[._]*.sw[a-p] +[._]s[a-rt-v][a-z] +[._]ss[a-gi-z] +[._]sw[a-p] + +# Session +Session.vim +Sessionx.vim + +# Temporary +.netrwhist +*~ +# Auto-generated tag files +tags +# Persistent undo +[._]*.un~ + +subprojects +builddir +ttassets +backup +*.exe +*.dll +*.world +coverage +coverage/* +.venv diff --git a/cpp/src/stats.hpp b/cpp/include/stats.hpp similarity index 85% rename from cpp/src/stats.hpp rename to cpp/include/stats.hpp index a0687e1..82c4616 100644 --- a/cpp/src/stats.hpp +++ b/cpp/include/stats.hpp @@ -1,6 +1,7 @@ #pragma once #include #include +#include struct TTest { double t_stat = 0.0; @@ -64,6 +65,11 @@ struct Stats { auto end = std::chrono::high_resolution_clock::now(); auto elapsed = std::chrono::duration(end - start); + auto as_ms = std::chrono::duration_cast(elapsed); + + fmt::println("sample time: {} vs. my calc: {}; as_ms: {}", + elapsed.count(), 1.0/elapsed.count(), as_ms.count()); + if(elapsed.count() > 0.0) { sample(1.0/elapsed.count()); } diff --git a/cpp/include/welford.hpp b/cpp/include/welford.hpp new file mode 100644 index 0000000..0349aa7 --- /dev/null +++ b/cpp/include/welford.hpp @@ -0,0 +1,55 @@ +#pragma once +#include +#include +#include "stats.hpp" + +struct WelfordStats { + double Mean = 0.0; // LOL + double n = 0.0; + double M2 = 0.0; + + double min = 0.0; + double max = 0.0; + + inline void reset() { + Mean = 0.0; + n = 0.0; + M2 = 0.0; + + min = 0.0; + max = 0.0; + } + + inline double mean() { + return Mean; + } + + inline double stddev() { + return std::sqrt(variance()); + } + + inline double variance() { + return M2 / n; + } + + inline double sample_variance() { + return M2 / (n - 1); + } + + inline void sample(double s) { + n += 1; + double old_mean = Mean; + Mean += (s - Mean) / n; + M2 += (s - old_mean) * (s - Mean); + + if (n == 0) { + min = s; + max = s; + } else { + if (min > s) min = s; + if (max < s) max = s; + } + } + + TTest t_test(WelfordStats& other); +}; diff --git a/cpp/meson.build b/cpp/meson.build index 9e17ab8..2eb7328 100644 --- a/cpp/meson.build +++ b/cpp/meson.build @@ -1,4 +1,4 @@ -project('sol2_test', 'cpp', +project('magic_stats', 'cpp', version: '0.1.0', default_options: [ 'cpp_std=c++23', @@ -33,6 +33,6 @@ executable('fuc2it', [ ], cpp_args: cpp_args, link_args: link_args, - include_directories: include_directories('src'), + include_directories: include_directories('include'), override_options: exe_defaults, dependencies: dependencies) diff --git a/cpp/tests/confirm.r b/cpp/tests/confirm.r new file mode 100644 index 0000000..84e70a3 --- /dev/null +++ b/cpp/tests/confirm.r @@ -0,0 +1,7 @@ +samples <- read.table("bad_samples.txt") +t.test(samples$V1, samples$V2) + + +samples <- read.table("samples.txt") +print(samples) +t.test(samples$V1, samples$V2) diff --git a/cpp/tests/stats_tests.cpp b/cpp/tests/stats_tests.cpp index 2109dfa..cbb5c05 100644 --- a/cpp/tests/stats_tests.cpp +++ b/cpp/tests/stats_tests.cpp @@ -81,9 +81,9 @@ namespace stats_tests { welf.sample(num); } - ALMOST_EQUAL(stats.mean(), welf.mean(), 5); - ALMOST_EQUAL(stats.variance(), welf.variance(), 5); - ALMOST_EQUAL(stats.stddev(), welf.stddev(), 5); + ALMOST_EQUAL(stats.mean(), welf.mean(), 7); + ALMOST_EQUAL(stats.variance(), welf.variance(), 7); + ALMOST_EQUAL(stats.stddev(), welf.stddev(), 7); } void test_timing_stats() { @@ -91,11 +91,6 @@ namespace stats_tests { // need to find something to time... } - double round_to(double value, int decimal_places) { - double multiplier = std::pow(10.0, decimal_places); - return std::round(value * multiplier) / multiplier; - } - void test_t_test() { Stats stats; Stats stats2; @@ -169,6 +164,13 @@ namespace stats_tests { ALMOST_EQUAL(stats_test.p_val, welf_test.p_val, 5); } + void test_time_sampling() { + Stats stats; + auto start = stats.time_start(); + test_welford(); + stats.sample_time(start); + } + fuc2::Set TESTS{ .name="stats", .tests={ @@ -177,6 +179,7 @@ namespace stats_tests { TEST(test_timing_stats), TEST(test_t_test), TEST(test_welford), + TEST(test_time_sampling), } }; }