savepoint, rework tolerance values.

This commit is contained in:
NunoSempere 2023-07-23 16:28:44 +02:00
parent 88e998edce
commit c8fd237bbf
3 changed files with 57 additions and 15 deletions

View File

@ -37,7 +37,7 @@ run: $(SRC) $(OUTPUT)
./$(OUTPUT) ./$(OUTPUT)
verify: $(SRC) $(OUTPUT) verify: $(SRC) $(OUTPUT)
./$(OUTPUT) | grep "NOT passed" -A 1 --group-separator='' || true ./$(OUTPUT) | grep "NOT passed" -A 2 --group-separator='' || true
time-linux: time-linux:
@echo "Requires /bin/time, found on GNU/Linux systems" && echo @echo "Requires /bin/time, found on GNU/Linux systems" && echo

BIN
test/test

Binary file not shown.

View File

@ -4,8 +4,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#define PERCENTAGE_TOLERANCE 1.0 / 1000.0 #define TOLERANCE 5.0 / 1000.0
#define PERCENTAGE_TOLERANCE_LOGNORMAL 5.0 / 1000.0
#define MAX_NAME_LENGTH 500 #define MAX_NAME_LENGTH 500
// Structs // Structs
@ -27,7 +26,7 @@ void test_array_expectations(struct array_expectations e)
double std = array_std(e.array, e.n); double std = array_std(e.array, e.n);
double delta_std = std - e.expected_std; 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 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("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)); 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); 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 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("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)); 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", .name = "unit uniform",
.expected_mean = 0.5, .expected_mean = 0.5,
.expected_std = sqrt(1.0 / 12.0), .expected_std = sqrt(1.0 / 12.0),
.tolerance = 1 * PERCENTAGE_TOLERANCE, .tolerance = TOLERANCE,
}; };
test_array_expectations(expectations); test_array_expectations(expectations);
@ -87,7 +86,7 @@ void test_uniform(double start, double end, uint64_t* seed)
.name = name, .name = name,
.expected_mean = (start + end) / 2, .expected_mean = (start + end) / 2,
.expected_std = sqrt(1.0 / 12.0) * fabs(end - start), .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); test_array_expectations(expectations);
@ -111,7 +110,7 @@ void test_unit_normal(uint64_t* seed)
.name = "unit normal", .name = "unit normal",
.expected_mean = 0, .expected_mean = 0,
.expected_std = 1, .expected_std = 1,
.tolerance = 1 * PERCENTAGE_TOLERANCE, .tolerance = TOLERANCE,
}; };
test_array_expectations(expectations); test_array_expectations(expectations);
@ -136,7 +135,7 @@ void test_normal(double mean, double std, uint64_t* seed)
.name = name, .name = name,
.expected_mean = mean, .expected_mean = mean,
.expected_std = std, .expected_std = std,
.tolerance = std * PERCENTAGE_TOLERANCE, .tolerance = TOLERANCE,
}; };
test_array_expectations(expectations); test_array_expectations(expectations);
@ -162,7 +161,41 @@ void test_lognormal(double logmean, double logstd, uint64_t* seed)
.name = name, .name = name,
.expected_mean = exp(logmean + pow(logstd, 2) / 2), .expected_mean = exp(logmean + pow(logstd, 2) / 2),
.expected_std = sqrt((exp(pow(logstd, 2)) - 1) * exp(2 * logmean + pow(logstd, 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); test_array_expectations(expectations);
@ -189,7 +222,7 @@ void test_beta(double a, double b, uint64_t* seed)
.name = name, .name = name,
.expected_mean = a / (a + b), .expected_mean = a / (a + b),
.expected_std = sqrt((a * b) / (pow(a + b, 2) * (a + b + 1))), .expected_std = sqrt((a * b) / (pow(a + b, 2) * (a + b + 1))),
.tolerance = PERCENTAGE_TOLERANCE, .tolerance = TOLERANCE,
}; };
test_array_expectations(expectations); test_array_expectations(expectations);
@ -244,8 +277,8 @@ int main()
} }
} }
printf("Testing very small lognormals\n"); printf("Testing smaller lognormals\n");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 100; i++) {
double mean = sample_uniform(-1, 1, seed); double mean = sample_uniform(-1, 1, seed);
double std = sample_uniform(0, 1, seed); double std = sample_uniform(0, 1, seed);
if (std > 0) { if (std > 0) {
@ -253,8 +286,8 @@ int main()
} }
} }
printf("Testing small lognormals\n"); printf("Testing larger lognormals\n");
for (int i = 0; i < 10; i++) { for (int i = 0; i < 100; i++) {
double mean = sample_uniform(-1, 5, seed); double mean = sample_uniform(-1, 5, seed);
double std = sample_uniform(0, 5, seed); double std = sample_uniform(0, 5, seed);
if (std > 0) { 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"); printf("Testing beta distribution\n");
for (int i = 0; i < 100; i++) { for (int i = 0; i < 100; i++) {
double a = sample_uniform(0, 1000, seed); double a = sample_uniform(0, 1000, seed);