Initial commit of the C++ version.

master
Zed A. Shaw 17 hours ago
parent 497d34a4af
commit c81720e7a9
  1. 2
      README.md
  2. 1
      cpp/.vimrc_proj
  3. 42
      cpp/Makefile
  4. 38
      cpp/meson.build
  5. 7
      cpp/scripts/reset_build.ps1
  6. 10
      cpp/scripts/reset_build.sh
  7. 41
      cpp/src/stats.cpp
  8. 65
      cpp/src/stats.hpp
  9. 13
      cpp/tests/main.cpp
  10. 20
      cpp/tests/stats_tests.cpp
  11. 13
      cpp/wraps/fmt.wrap
  12. 9
      cpp/wraps/fuc2.wrap

@ -1,3 +1,5 @@
# magic_stats
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…
Cancel
Save