first check-in of feisty meow codebase. many things broken still due to recent
[feisty_meow.git] / core / library / tests_mathematics / test_chaos.cpp
1 /*
2 *  Name   : test_chaos
3 *  Author : Chris Koeritz
4 **
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                               *
11 */
12
13 //#define DEBUG_CHAOS
14
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>
23
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;
33
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)
39
40 #define LOG(to_print) EMERGENCY_LOG(program_wide_logger::get(), astring(to_print))
41
42 class test_chaos : virtual public unit_base, virtual public application_shell
43 {
44 public:
45   test_chaos() : application_shell() {}
46   DEFINE_CLASS_NAME("test_chaos");
47   virtual int execute();
48 };
49
50 int test_chaos::execute()
51 {
52   FUNCDEF("execute");
53 #ifdef DEBUG_CHAOS
54   LOG(a_sprintf("average expected=%f, variation allowed=%f",
55       AVG_EXPECTED_PER_BIN, VARIATION_ALLOWED));
56 #endif
57   int results[MAX_RANDOM_BINS];
58   for (int k = 0; k < MAX_RANDOM_BINS; k++) results[k] = 0;
59   chaos randomizer;
60
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]++;
74   }
75 #ifdef DEBUG_CHAOS
76   LOG("Anomalies:");
77 #endif
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) {
81       failed_any++;
82 #ifdef DEBUG_CHAOS
83       LOG(astring(astring::SPRINTF, "%d: difference=%f",
84           j, double(results[j] - AVG_EXPECTED_PER_BIN)));
85 #endif
86     }
87   }
88 #ifdef DEBUG_CHAOS
89   if (!failed_any) LOG("None")
90   else LOG(a_sprintf("Saw %d anomalies of %d allowed.", failed_any, ANOMALIES_ALLOWED));
91 #endif
92
93   ASSERT_FALSE(failed_any > ANOMALIES_ALLOWED,
94       "probability anomalies should be less than the allowed number");
95   return final_report();
96 }
97
98 HOOPLE_MAIN(test_chaos, )
99