3 * Author : Chris Koeritz
5 * Copyright (c) 1992-$now By Author. This program is free software; you can *
6 * redistribute it and/or modify it under the terms of the GNU General Public *
7 * License as published by the Free Software Foundation; either version 2 of *
8 * the License or (at your option) any later version. This is online at: *
9 * http://www.fsf.org/copyleft/gpl.html *
10 * Please send any updates to: fred@gruntose.com *
15 #include <application/hoople_main.h>
16 #include <basis/astring.h>
17 #include <basis/functions.h>
18 #include <basis/guards.h>
19 #include <loggers/console_logger.h>
20 #include <mathematics/chaos.h>
21 #include <structures/static_memory_gremlin.h>
22 #include <unit_test/unit_base.h>
24 using namespace application;
25 using namespace basis;
26 using namespace mathematics;
27 using namespace filesystem;
28 using namespace loggers;
29 using namespace structures;
30 using namespace textual;
31 using namespace timely;
32 using namespace unit_test;
34 #define MAX_RANDOM_BINS 40
35 #define MAX_TEST_CYCLES 10008
36 #define AVG_EXPECTED_PER_BIN (double(MAX_TEST_CYCLES) / double(MAX_RANDOM_BINS))
37 #define VARIATION_ALLOWED (AVG_EXPECTED_PER_BIN * 0.1)
38 #define ANOMALIES_ALLOWED (MAX_RANDOM_BINS / 4)
40 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), astring(to_print))
42 class test_chaos : virtual public unit_base, virtual public application_shell
45 test_chaos() : application_shell() {}
46 DEFINE_CLASS_NAME("test_chaos");
47 virtual int execute();
50 int test_chaos::execute()
54 LOG(a_sprintf("average expected=%f, variation allowed=%f",
55 AVG_EXPECTED_PER_BIN, VARIATION_ALLOWED));
57 int results[MAX_RANDOM_BINS];
58 for (int k = 0; k < MAX_RANDOM_BINS; k++) results[k] = 0;
61 for (int i = 0; i < MAX_TEST_CYCLES; i++) {
62 // first test if exclusivity is ensured...
63 int res = randomizer.exclusive(0, MAX_RANDOM_BINS - 1);
64 ASSERT_FALSE( (res <= 0) || (res >= MAX_RANDOM_BINS - 1),
65 "exclusive test should not go out of bounds");
66 // then test for our statistics.
67 int base = randomizer.inclusive(-1000, 1000);
68 // pick a base for the number below.
69 res = randomizer.inclusive(base, base + MAX_RANDOM_BINS - 1);
70 ASSERT_FALSE( (res < base) || (res > base + MAX_RANDOM_BINS - 1),
71 "inclusive test should not go out of bounds");
72 //LOG(a_sprintf("adding it to %d bin", res - base));
73 results[res - base]++;
78 int failed_any = false;
79 for (int j = 0; j < MAX_RANDOM_BINS; j++) {
80 if (absolute_value(results[j] - AVG_EXPECTED_PER_BIN) > VARIATION_ALLOWED) {
83 LOG(astring(astring::SPRINTF, "%d: difference=%f",
84 j, double(results[j] - AVG_EXPECTED_PER_BIN)));
89 if (!failed_any) LOG("None")
90 else LOG(a_sprintf("Saw %d anomalies of %d allowed.", failed_any, ANOMALIES_ALLOWED));
93 ASSERT_FALSE(failed_any > ANOMALIES_ALLOWED,
94 "probability anomalies should be less than the allowed number");
95 return final_report();
98 HOOPLE_MAIN(test_chaos, )