parent
497d34a4af
commit
c81720e7a9
@ -1,3 +1,5 @@ |
|||||||
# magic_stats |
# magic_stats |
||||||
|
|
||||||
A simple bit of code in multiple languages that lets you calculate useful statistics without storing every sample. |
A simple bit of code in multiple languages that lets you calculate useful statistics without storing every sample. |
||||||
|
|
||||||
|
Look in cpp/ for a C++ version. More to come. |
||||||
|
|||||||
@ -0,0 +1 @@ |
|||||||
|
set makeprg=meson\ compile\ -C\ . |
||||||
@ -0,0 +1,42 @@ |
|||||||
|
all: build |
||||||
|
|
||||||
|
reset: |
||||||
|
ifeq '$(OS)' 'Windows_NT' |
||||||
|
powershell -executionpolicy bypass .\scripts\reset_build.ps1
|
||||||
|
else |
||||||
|
sh -x ./scripts/reset_build.sh
|
||||||
|
endif |
||||||
|
|
||||||
|
build: |
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
release_build: |
||||||
|
meson --wipe builddir -Db_ndebug=true --buildtype release
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
debug_build: |
||||||
|
meson setup --wipe builddir -Db_ndebug=true --buildtype debugoptimized
|
||||||
|
meson compile -j 10 -C builddir
|
||||||
|
|
||||||
|
test: build |
||||||
|
./builddir/fuc2it
|
||||||
|
|
||||||
|
run: build test |
||||||
|
ifeq '$(OS)' 'Windows_NT' |
||||||
|
powershell "cp ./builddir/fuc2it.exe ."
|
||||||
|
./fuc2it
|
||||||
|
else |
||||||
|
./builddir/fuc2it
|
||||||
|
endif |
||||||
|
|
||||||
|
debug: build |
||||||
|
gdb --nx -x .gdbinit --ex run --args builddir/fuc2it
|
||||||
|
|
||||||
|
debug_run: build |
||||||
|
gdb --nx -x .gdbinit --batch --ex run --ex bt --ex q --args builddir/fuc2it
|
||||||
|
|
||||||
|
clean: |
||||||
|
meson compile --clean -C builddir
|
||||||
|
|
||||||
|
debug_test: build |
||||||
|
gdb --nx -x .gdbinit --ex run --args builddir/fuc2it -e
|
||||||
@ -0,0 +1,38 @@ |
|||||||
|
project('sol2_test', 'cpp', |
||||||
|
version: '0.1.0', |
||||||
|
default_options: [ |
||||||
|
'cpp_std=c++23', |
||||||
|
# 'cpp_args=-D_GLIBCXX_DEBUG=1 -D_GLIBCXX_DEBUG_PEDANTIC=1', |
||||||
|
]) |
||||||
|
|
||||||
|
# use this for common options only for our executables |
||||||
|
cpp_args=[ |
||||||
|
'-Wno-unused-parameter', |
||||||
|
'-Wno-unused-function', |
||||||
|
'-Wno-unused-variable', |
||||||
|
'-Wno-unused-but-set-variable', |
||||||
|
'-Wno-deprecated-declarations', |
||||||
|
'-Wno-maybe-uninitialized', # only because of error in release_build |
||||||
|
] |
||||||
|
link_args=[] |
||||||
|
# these are passed as override_defaults |
||||||
|
exe_defaults = [ 'warning_level=2', 'werror=false'] |
||||||
|
|
||||||
|
fmt = subproject('fmt').get_variable('fmt_dep') |
||||||
|
fuc2 = subproject('fuc2').get_variable('fuc2_dep') |
||||||
|
|
||||||
|
dependencies = [fmt, fuc2] |
||||||
|
|
||||||
|
sources = [ |
||||||
|
] |
||||||
|
|
||||||
|
executable('fuc2it', [ |
||||||
|
'src/stats.cpp', |
||||||
|
'tests/stats_tests.cpp', |
||||||
|
'tests/main.cpp', |
||||||
|
], |
||||||
|
cpp_args: cpp_args, |
||||||
|
link_args: link_args, |
||||||
|
include_directories: include_directories('src'), |
||||||
|
override_options: exe_defaults, |
||||||
|
dependencies: dependencies) |
||||||
@ -0,0 +1,7 @@ |
|||||||
|
mv .\subprojects\packagecache . |
||||||
|
rm -recurse -force .\subprojects\,.\builddir\ |
||||||
|
mkdir subprojects |
||||||
|
mv .\packagecache .\subprojects\ |
||||||
|
mkdir builddir |
||||||
|
cp wraps\*.wrap subprojects\ |
||||||
|
meson setup --default-library=static --prefer-static builddir |
||||||
@ -0,0 +1,10 @@ |
|||||||
|
#!/usr/bin/env bash |
||||||
|
|
||||||
|
mv -f ./subprojects/packagecache . |
||||||
|
rm -rf subprojects builddir |
||||||
|
mkdir subprojects |
||||||
|
mv -f packagecache ./subprojects/ && true |
||||||
|
mkdir builddir |
||||||
|
cp wraps/*.wrap subprojects/ |
||||||
|
# on OSX you can't do this with static |
||||||
|
meson setup --default-library=static --prefer-static builddir |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
#include "stats.hpp" |
||||||
|
#include <fmt/core.h> |
||||||
|
#include <numeric> |
||||||
|
#include <numbers> |
||||||
|
|
||||||
|
void Stats::dump(std::string msg) |
||||||
|
{ |
||||||
|
fmt::println("{}: sum: {}, sumsq: {}, n: {}, " |
||||||
|
"min: {}, max: {}, mean: {}, stddev: {}", |
||||||
|
msg, sum, sumsq, n, min, max, mean(), |
||||||
|
stddev()); |
||||||
|
} |
||||||
|
|
||||||
|
// WARNING: got this code from google AI. PROBABLY BULLSHIT
|
||||||
|
void Stats::t_test(Stats& other) { |
||||||
|
double n1 = this->n; |
||||||
|
double n2 = other.n; |
||||||
|
|
||||||
|
double mean1 = this->mean(); |
||||||
|
double mean2 = other.mean(); |
||||||
|
|
||||||
|
double var1 = this->variance(); |
||||||
|
double var2 = other.variance(); |
||||||
|
|
||||||
|
// calculate t-stat
|
||||||
|
double delta_mean = mean1 - mean2; |
||||||
|
double pooled_se = std::sqrt((var1 / n1) + (var2 / n2)); |
||||||
|
double t_stat = delta_mean / pooled_se; |
||||||
|
|
||||||
|
// calculate degrees of freedom
|
||||||
|
double num = std::pow((var1 / n1) + (var2 / n2), 2); |
||||||
|
double den = (std::pow(var1 / n1, 2) / (n1 - 1)) + (std::pow(var2 / n2, 2) / (n2 - 1)); |
||||||
|
double df = num / den; |
||||||
|
|
||||||
|
double x = df / (df + t_stat * t_stat); |
||||||
|
|
||||||
|
double p_val = std::tgamma((df + 1.0) / 2.0) / (std::sqrt(df * std::numbers::pi) * std::tgamma(df / 2.0)) * std::pow(1.0 + (t_stat * t_stat) / df, -(df + 1.0) / 2.0); |
||||||
|
|
||||||
|
fmt::println("t_stat={}, df={}, p_val={}", |
||||||
|
t_stat, df, p_val); |
||||||
|
} |
||||||
@ -0,0 +1,65 @@ |
|||||||
|
#pragma once |
||||||
|
#include <cmath> |
||||||
|
#include <chrono> |
||||||
|
|
||||||
|
struct Stats { |
||||||
|
using TimeBullshit = std::chrono::time_point<std::chrono::high_resolution_clock>; |
||||||
|
|
||||||
|
double sum = 0.0; |
||||||
|
double sumsq = 0.0; |
||||||
|
double n = 0.0; |
||||||
|
double min = 0.0; |
||||||
|
double max = 0.0; |
||||||
|
|
||||||
|
inline void reset() { |
||||||
|
sum = 0.0; |
||||||
|
sumsq = 0.0; |
||||||
|
n = 0.0; |
||||||
|
min = 0.0; |
||||||
|
max = 0.0; |
||||||
|
} |
||||||
|
|
||||||
|
inline double mean() { |
||||||
|
return sum / n; |
||||||
|
} |
||||||
|
|
||||||
|
inline double stddev() { |
||||||
|
return std::sqrt(variance()); |
||||||
|
} |
||||||
|
|
||||||
|
inline double variance() { |
||||||
|
return (sumsq - (sum * sum / n)) / (n - 1); |
||||||
|
} |
||||||
|
|
||||||
|
inline void sample(double s) { |
||||||
|
sum += s; |
||||||
|
sumsq += s * s; |
||||||
|
|
||||||
|
if (n == 0) { |
||||||
|
min = s; |
||||||
|
max = s; |
||||||
|
} else { |
||||||
|
if (min > s) min = s; |
||||||
|
if (max < s) max = s; |
||||||
|
} |
||||||
|
|
||||||
|
n += 1; |
||||||
|
} |
||||||
|
|
||||||
|
inline TimeBullshit time_start() { |
||||||
|
return std::chrono::high_resolution_clock::now(); |
||||||
|
} |
||||||
|
|
||||||
|
inline void sample_time(TimeBullshit start) { |
||||||
|
auto end = std::chrono::high_resolution_clock::now(); |
||||||
|
auto elapsed = std::chrono::duration<double>(end - start); |
||||||
|
|
||||||
|
if(elapsed.count() > 0.0) { |
||||||
|
sample(1.0/elapsed.count()); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void dump(std::string msg=""); |
||||||
|
|
||||||
|
void t_test(Stats& other); |
||||||
|
}; |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
#include <fuc2/run.hpp> |
||||||
|
|
||||||
|
TEST_SET(stats_tests); |
||||||
|
|
||||||
|
using namespace fuc2; |
||||||
|
|
||||||
|
int main(int argc, char* argv[]) { |
||||||
|
std::vector<fuc2::Set> tests{ |
||||||
|
stats_tests::TESTS, |
||||||
|
}; |
||||||
|
|
||||||
|
return run_tests(tests, argc, argv); |
||||||
|
} |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
#include <fmt/core.h> |
||||||
|
#include <deque> |
||||||
|
#include <string> |
||||||
|
#include <fuc2/testing.hpp> |
||||||
|
|
||||||
|
using namespace fuc2; |
||||||
|
|
||||||
|
namespace stats_tests { |
||||||
|
|
||||||
|
void test_stats_stuff() { |
||||||
|
CHECK(1 == 1); |
||||||
|
} |
||||||
|
|
||||||
|
fuc2::Set TESTS{ |
||||||
|
.name="stats", |
||||||
|
.tests={ |
||||||
|
TEST(test_stats_stuff), |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
@ -0,0 +1,13 @@ |
|||||||
|
[wrap-file] |
||||||
|
directory = fmt-12.0.0 |
||||||
|
source_url = https://github.com/fmtlib/fmt/archive/12.0.0.tar.gz |
||||||
|
source_filename = fmt-12.0.0.tar.gz |
||||||
|
source_hash = aa3e8fbb6a0066c03454434add1f1fc23299e85758ceec0d7d2d974431481e40 |
||||||
|
source_fallback_url = https://github.com/mesonbuild/wrapdb/releases/download/fmt_12.0.0-1/fmt-12.0.0.tar.gz |
||||||
|
patch_filename = fmt_12.0.0-1_patch.zip |
||||||
|
patch_url = https://wrapdb.mesonbuild.com/v2/fmt_12.0.0-1/get_patch |
||||||
|
patch_hash = 307f288ebf3850abf2f0c50ac1fb07de97df9538d39146d802f3c0d6cada8998 |
||||||
|
wrapdb_version = 12.0.0-1 |
||||||
|
|
||||||
|
[provide] |
||||||
|
dependency_names = fmt |
||||||
@ -0,0 +1,9 @@ |
|||||||
|
[wrap-git] |
||||||
|
directory=fuc2-0.1.0 |
||||||
|
url=https://lcthw.dev/cpp/fuc2.git |
||||||
|
revision=HEAD |
||||||
|
depth=1 |
||||||
|
method=meson |
||||||
|
|
||||||
|
[provide] |
||||||
|
fuc2 = fuc2_dep |
||||||
Loading…
Reference in new issue