From c8fd237bbf48ecfe5b20e6d13d1b8976ca8d5374 Mon Sep 17 00:00:00 2001 From: NunoSempere Date: Sun, 23 Jul 2023 16:28:44 +0200 Subject: [PATCH] savepoint, rework tolerance values. --- test/makefile | 2 +- test/test | Bin 26608 -> 26640 bytes test/test.c | 70 ++++++++++++++++++++++++++++++++++++++++---------- 3 files changed, 57 insertions(+), 15 deletions(-) diff --git a/test/makefile b/test/makefile index 6865ee0..af3137a 100644 --- a/test/makefile +++ b/test/makefile @@ -37,7 +37,7 @@ run: $(SRC) $(OUTPUT) ./$(OUTPUT) verify: $(SRC) $(OUTPUT) - ./$(OUTPUT) | grep "NOT passed" -A 1 --group-separator='' || true + ./$(OUTPUT) | grep "NOT passed" -A 2 --group-separator='' || true time-linux: @echo "Requires /bin/time, found on GNU/Linux systems" && echo diff --git a/test/test b/test/test index cd8449dd8cb760a957ec5fc9c00bc2876868c425..d2f0a3465e48b439ada7f55c6272f5d4127535ba 100755 GIT binary patch delta 6591 zcma)B3sh9sxjq~i7y zoPY2C|M&mi|Jie9^i!YqexG(zXitQ|E*l5J{8!V?2QEtEvqfnn%*PT~6~w1iLES|@ z7N5yobNGBblzcc|BD=*;jjvrQ`Qbn6*G5j?`9u07?b(?b&56spH~Gf+MR!JWKHG8* zwHydlk==U(HU>IN-meD6zU8V({*|IA_O@AzGco^IkbMDMhviU;b&beh1Yq7a>uFHs z`#&hkuvQ;0Y#H`()Y-Rds;!iHq}Hx)Jc8+ROzF5sP7DKKyC#p*Z|XzyB(0lk8jw!T zc0W`QZt4xCAnG$eY}r$*Pd!5A=~F+HLt!%Xtltgomo0+843>XRP0-cq<6mSBxed8W zjUO{)5L2$CB(h2C5*-$c|ejNN^YTgod`Wu+&$GD`q6vvc)Mo7 zg9_Jq6q>ohtcNQUxx#BuczC=*{|P+8R9~g4&nd{QT;WMzygU>=3cK{o!*@A-yoVj2 z!oxdI_|bTUJG~4_q1qeJ=_3}I?7Zzv8CjG9rN%DP8jduUQpe-Milt@_m&7eKW;I2Yn_SC zLd*9}XzfpTYfXk$?kN<%<*k_NEz=3BsYR}bE1u!4_)Dlf%@p@OsJJiCtr#`++FcaS zmOfKf&$8vcwHEjO)yLaN=ETUwwFz*vEo5Xe1+#KsoDzQ1E(o{VF^wvuSWOrO)4z3u z!>|*e*?-yNn4k=(8?M*A@!Dn$QDWO;7wzPYiIc>4?Bu}2*z|XR6xL5!WZyFD1v<35 z1|7ln?X$LGBJciAQRHeU{Ydk?y~Akr*+jC8#q8q4HA-6`XOfb z0Pg}~16F=oo2$<}(h@{LkN#KTX!gafiw9}X&+37)2FV1+cBL|-DkQD^1PrIzPNxY@ zstyczf&zhuF_NH6KeKBe&Tof$2{2IHtdG zKPr#OC14&}r4VyOq%#Ms^EtMXI1mvdK0&}N8gkaB3y=OJ)ITkt~i)H88Ln8fwpklhjSQ{L7x1Lu5O zJpHTnS5Uu`5djF)d=FUc%8=}?JVa)@CMcDB6*1L#m3F%=eXEOIBg=T?*W4jeq(yx1 z4k?XHS+N=215R>z=MUaSQOM8VVNMiFTA1Z06}M^p;R9aZcGt%TD93xWbpA?5EbQ_J zU$X^9xl2$SQqI^-?#Bd837|HrVb~5)4~F46CR{zS5NmXl6E9kX7#l-A3R)q}S8s7! zr?9Wj4;_(iWYF;BFJ$|cUaf3%yIDB>-1>j=^uLV7-n__vQX;k6EBPn}ulygoNmn?> z#8ZFG@GO;jh6Ep_PFs=r3*11Ul5~jOO?_FP{H&Kg6i5!(4ly>9ywFWT{{cxg9;kS?Sc;s=+u3~N%Uk-TXXxu5c4Id(qCsxt#G}Y8kYGVb44NvuAz88zqtjyv zD?5pReu5qqQU?Z40x{^PLFEC#vlK4|r@rh%d9&MiT7lj+*Y2t}!L@f)o!c$!y^6O~wYQj7*coMmokQf*+#Km8Z zhWPY=UU18CL&TPtB&H0JxX=)hO- zbC$+)iHRIcik$TLzv$|*J|ibFgduiOB)O3kCx%Co(BuX27xBZJl^(hdn$T1D<&mdB#Qekl4EIaizhCSrgWEh zD~x=f{*2f>K%SbiOx!sDKf$qRWg8jN(V~kX#*kEb}j7P6)Z4xj(oi#4W%PLiSp%6aNs5 zF4CqU0L)1Fz*+LObwo6sCI8A=F762;`PobSs=iPZGMZHq@EwkU@@Lafl+OT#*hIw^;-Rd-R^K*@k zl^bz%!R1-Ea$Q}`I`gU;$4YZ`eY0a-{i^kj`n8SCq}MhhX<1TjhB>Krxp{qKeJ#Wb z9yO_)k|sFT5^HXp6ATUyms@x<>}hagn>{)=)K}O1JC;e{K6p5}0M#)Mwt?I1jh;ti zz_{Uz$H+02>XL_0{>^h19)#dSQS^c))XX+OGYaYqg=ZBd!&eY`z62hy>mT3;6tE*! zL!K3IlOKM{RAJB#L_gr$fWieu=>cp4{0y+`qN0ofj((*m!5Tqm$Ii6^j>?Ks1!zOx zY6a{9+(Gexe*kPkKm35=(PPg54xmp<{({hnu3iN=fH%$#e{|>`99aDD?r*|LG8NE_ z7r}hMcEDZaz?_umBPSIl6P5{i0ocQWAmM%#x8W0VcTRGx{E4D4Jf-0>;&$L30DhDr z)XNI^GH&}RMQK5ZgaVzRO`NSWz3iK-GjH|F(^dIS@d?zK3v{O0I>T(8_L-n!u=U{H z@fk_aFCzVUewy3JzzlLSKiaoRyheVLpH9sAT5;fi!SIZ~4QcsCAiv0;IKP#jR!m6R%ihK<*ybJipCiDQ;huqDhlF8hHsm=^=8j&&UF-7S>0)%{> zVXFw+w)ht6tiI3r=}dEUhFl#^tL&m7$OC^nGN0y!D+BJ&<8TeY9RY5Y%4Y&>1x`Y> zB+)9f>sFY>qk%f@+#rDpegnjubBgj)uLWJe?Eo%^FR+T|!Cx38P+`YG+mDhPPcwr? zzk8nhCwXRWoPRLd_}KsI1v8mmTDn^ zOInJm@L`Z%?(~1BlB-y=5QGfO>7_-%Q6rnC@wwYmlZqcmAjg(iqWjfA)Nn4LKqZ@F zNLZOAx+$<}DHw9Hb}p2f-C>gxAYW88m9s5Y^k#3Gi!8Qoj;_o}$gspM4I z<6?&&2`o<*SI;5Y<&|QWL^{d~vPWr8z~#2E6va$sb*lJ$P8O2gD2_rj&W@e6R^+<@aj_i$y6ModZ}3#%=G_UU{j^8ZqGf!O6s zPE}h%-KFb>5(%xz3_X*_dEIbZ_ktS5$0vs@sGBxn<5EuCPhQ2$x`NN5N$9Hh{{vp9 Bo2&o; delta 4756 zcmaJ_dsI|)9=~&8U>K2^fdR(hF(X`HcsL9wK2Es;A`LJazQqTb2XQm<71+yNX0=q- zDCE1_Y4?~1TiYJT?O5!V*~9TsQn4Euwx*O=s8>rtv?Q~B`}y5_r&#~!ch2Se`+eW9 z-(zU$(hYp1Yq428F@iD*RUmk_XP!15PgPgPQz=^KHp&s|QjTaZ*SU40+ltlotuRri z;uGmF;z!oz`^J`fwoaLSXx}pp6$kS&UNFDY*}fqpG1P9hs(gh@RA^9v&=u4EYWRc3 z#_&jWHG z5`=B~DwRHHvXn@MT2p^O;gp{R6{};lrrbm8qiapBjzNU2U0{S#?rw8|861k# zJ`tkOe?)#p;e=5qxL_1q(b+UGYE&93zyc3pgc`zEu(?=rLNz?&-*LqW_+8zN zSq*QxTq`_13^UN!nWfpy3&^&hT5ixMnL$1tBtv1)v%_(6{|`I}n1)_N!UL$uqNSta z<2&Vppm{ePDLlZp%#xzTMN2NYe<1&;crTCOF(_1AG{~F5$US!}$ys1^i{(}be;zSNT2>qKwndiIr@b0(1rv62$bM_n5ZFh?+Z%}AL#$B(V_u-$a@AQFdD5N~*h7v6b zg=j-1U$cIBCU44jy-i2o;2isTx!>V4B}a1I_lkfOJ!eKhz9uvjrX%|@>5mBs(g8@L z%TB^h3GXl0Vbn>#R>4+b<5%ndkx3sXWaRenR5ta)UynR6q&V*V#qlqIsjYQuTT{^T zQt&;`OV%9yusC>Ls$FVcP5}qJz22eJsry*EZ)t_Mj zY)t0?3@a*%JiM;oDFLA25da#2`wqWd+;5bzn+Jm}S=EijMfg64m%VDt+vzyK2Tcp! zl_OP)3Ldqe2tJ%1;IqkBRNa^=ZNdA6$FLxP?~we7O2wu`o*Ftkj;@e{(jz9T90k{R>|msUwW(o z7-)%<a)VL!7cB+OaWJ#`21x$@A8U2UZT9rRNGJzcF#sX?h)QAt;rmk^{vTN zmzgf^Poh6%jusus^m=BpiGfwlzoaU@kwkr&(#Rg*U>)rvmtCURtaQQL$v6rp1CjSrOR4ZN0C-LPN+B$YaqyfbB(QvsS%u42Qu~F0U zO3gdwYdVihZFUTe9akl;`I4R(mt@=(tz>-Ui_!G2aj%OV7Ft!XFY=rvsG!e6`Qtq? zW*~5t{9x9u4tY{9HH_~UpFT~s6PAb;Grc=uerWF(jM172v%~K;!SU|z>4OQg#(IFf zYD&IQG~d@e`4sMrqIqRapBBw6Yx=fmPEpg%x!&e6oj}j_W&Vgat3ht;X=f94;q8G4 zzrMBb2&EKF8r!hyo_Z(#)UIB4pRg#cHpiJ(yX0qtLR|&Y-E~6U>J{pY{6)!8>zA*4 z$az2Tbxsh-QXD&iPgIWksjhgO;pU51j!j=yIfeYiu`z{D7UFiq7?`3$YatC4w}ijB zaz(_fnMT?&bxb3Frej|T{(m!8iMjtjj6De00@%XWA2HUAmv&1RLmXIt%-9Qny`M1F z!}+=y%R$3;9cPR;zW-Ckx&T}L%a{bY!q0%`@+TP+LIoiJXayVqbcNz{UV4hL+kt55 zVQc}Q@Hu03fQ88PRzUx0#&!cb&oI`(*L{o)0d@h}aMc!~k8%M0fQ5jsX*WZ9YOb{yj8QT#S4*{GG0U-7Q%79LsJRbVEB*R{b*zu^xLpB_( zA_x+`arj)F6g@4yKtReAJf~rxPlbAXL!FEbaD+BIfRE$rg1RMi-?Vu9Ih`@eSsG<4 zjxrZV87fBLaV-S!-Tat#PMe`$e2lStx-ui!yH(E230NgT-&j#oOE)m5~<957J zPVs#s-Rq68-wwRz1Y`FOtNvgQ=&F?B(t-GaBmlb2OuT zWtbn+Jux2)pGL zJZ}b$?~0-F*`=b{O0Bc2#lA8coV{LbE2fomO2xofdXQE1r5fIxOU8vc^r{$b+@YablG;};{A*}?;Mpn5x #include -#define PERCENTAGE_TOLERANCE 1.0 / 1000.0 -#define PERCENTAGE_TOLERANCE_LOGNORMAL 5.0 / 1000.0 +#define TOLERANCE 5.0 / 1000.0 #define MAX_NAME_LENGTH 500 // Structs @@ -27,7 +26,7 @@ void test_array_expectations(struct array_expectations e) double std = array_std(e.array, e.n); double delta_std = std - e.expected_std; - if (fabs(delta_mean) / fabs(mean) > e.tolerance) { + if ((fabs(delta_mean) / fabs(mean) > e.tolerance) && (fabs(delta_mean) > e.tolerance)) { printf("[-] Mean test for %s NOT passed.\n", e.name); printf("Mean of %s: %f, vs expected mean: %f\n", e.name, mean, e.expected_mean); printf("delta: %f, relative delta: %f\n", delta_mean, delta_mean / fabs(mean)); @@ -35,7 +34,7 @@ void test_array_expectations(struct array_expectations e) printf("[x] Mean test for %s PASSED\n", e.name); } - if (fabs(delta_std) / fabs(std) > e.tolerance) { + if ((fabs(delta_std) / fabs(std) > e.tolerance) && (fabs(delta_std) > e.tolerance)) { printf("[-] Std test for %s NOT passed.\n", e.name); printf("Std of %s: %f, vs expected std: %f\n", e.name, std, e.expected_std); printf("delta: %f, relative delta: %f\n", delta_std, delta_std / fabs(std)); @@ -62,7 +61,7 @@ void test_unit_uniform(uint64_t* seed) .name = "unit uniform", .expected_mean = 0.5, .expected_std = sqrt(1.0 / 12.0), - .tolerance = 1 * PERCENTAGE_TOLERANCE, + .tolerance = TOLERANCE, }; test_array_expectations(expectations); @@ -87,7 +86,7 @@ void test_uniform(double start, double end, uint64_t* seed) .name = name, .expected_mean = (start + end) / 2, .expected_std = sqrt(1.0 / 12.0) * fabs(end - start), - .tolerance = fabs(end - start) * PERCENTAGE_TOLERANCE, + .tolerance = fabs(end - start) * TOLERANCE, }; test_array_expectations(expectations); @@ -111,7 +110,7 @@ void test_unit_normal(uint64_t* seed) .name = "unit normal", .expected_mean = 0, .expected_std = 1, - .tolerance = 1 * PERCENTAGE_TOLERANCE, + .tolerance = TOLERANCE, }; test_array_expectations(expectations); @@ -136,7 +135,7 @@ void test_normal(double mean, double std, uint64_t* seed) .name = name, .expected_mean = mean, .expected_std = std, - .tolerance = std * PERCENTAGE_TOLERANCE, + .tolerance = TOLERANCE, }; test_array_expectations(expectations); @@ -162,7 +161,41 @@ void test_lognormal(double logmean, double logstd, uint64_t* seed) .name = name, .expected_mean = exp(logmean + pow(logstd, 2) / 2), .expected_std = sqrt((exp(pow(logstd, 2)) - 1) * exp(2 * logmean + pow(logstd, 2))), - .tolerance = exp(logstd) * PERCENTAGE_TOLERANCE_LOGNORMAL, + .tolerance = TOLERANCE, + }; + + test_array_expectations(expectations); + free(name); + free(lognormal_array); +} + +// Test lognormal to +void test_to(double low, double high, uint64_t* seed) +{ + int n = 10 * 1000 * 1000; + double* lognormal_array = malloc(sizeof(double) * n); + + for (int i = 0; i < n; i++) { + lognormal_array[i] = sample_to(low, high, seed); + } + + + char* name = malloc(MAX_NAME_LENGTH * sizeof(char)); + snprintf(name, MAX_NAME_LENGTH, "to(%f, %f)", low, high); + + const double NORMAL95CONFIDENCE = 1.6448536269514722; + double loglow = logf(low); + double loghigh = logf(high); + double logmean = (loglow + loghigh) / 2; + double logstd = (loghigh - loglow) / (2.0 * NORMAL95CONFIDENCE); + + struct array_expectations expectations = { + .array = lognormal_array, + .n = n, + .name = name, + .expected_mean = exp(logmean + pow(logstd, 2) / 2), + .expected_std = sqrt((exp(pow(logstd, 2)) - 1) * exp(2 * logmean + pow(logstd, 2))), + .tolerance = TOLERANCE, }; test_array_expectations(expectations); @@ -189,7 +222,7 @@ void test_beta(double a, double b, uint64_t* seed) .name = name, .expected_mean = a / (a + b), .expected_std = sqrt((a * b) / (pow(a + b, 2) * (a + b + 1))), - .tolerance = PERCENTAGE_TOLERANCE, + .tolerance = TOLERANCE, }; test_array_expectations(expectations); @@ -244,8 +277,8 @@ int main() } } - printf("Testing very small lognormals\n"); - for (int i = 0; i < 10; i++) { + printf("Testing smaller lognormals\n"); + for (int i = 0; i < 100; i++) { double mean = sample_uniform(-1, 1, seed); double std = sample_uniform(0, 1, seed); if (std > 0) { @@ -253,8 +286,8 @@ int main() } } - printf("Testing small lognormals\n"); - for (int i = 0; i < 10; i++) { + printf("Testing larger lognormals\n"); + for (int i = 0; i < 100; i++) { double mean = sample_uniform(-1, 5, seed); double std = sample_uniform(0, 5, seed); if (std > 0) { @@ -262,6 +295,15 @@ int main() } } + printf("Testing lognormals — sample_to(low, high) syntax\n"); + for (int i = 0; i < 100; i++) { + double low = sample_uniform(0, 1000 * 1000, seed); + double high = sample_uniform(0, 1000 * 1000, seed); + if (low < high) { + test_to(low, high, seed); + } + } + printf("Testing beta distribution\n"); for (int i = 0; i < 100; i++) { double a = sample_uniform(0, 1000, seed);