-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
131 lines (109 loc) · 3.45 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include "fibonacci_numbers.h" // first 94 fibonacci numbers
#include "functions.h"
#include <functional>
#include <chrono>
#include <string>
#include <iostream>
#include <map>
#include <fstream>
#include <bitset>
using namespace std;
long double timeFunction(string funcName, uint64_t param);
bool testAllFuncs();
bool testFibFunc(string funcName, int X);
void measureAllFuncs();
void measureAndRecordFunc(string funcName, uint64_t X, int nTrials = 100);
map<string, function<uint64_t(uint64_t)>> namesToFuncs {
{"FibLoop", FibLoop},
{"FibRecur", FibRecur},
{"FibRecurDP", FibRecurDP},
{"FibMatrix", FibMatrix},
{"FibRecurDPTail", FibRecurDPTail}
};
map<string, uint64_t> funcMaxXs {
{"FibLoop", 92},
{"FibRecur", 30},
{"FibRecurDP", 92},
{"FibMatrix", 92},
{"FibRecurDPTail", 92}
};
int main(int argc, char** argv) {
if (argc > 1 && string(argv[1]) == "test") {
return testAllFuncs();
}
testAllFuncs();
//measureAllFuncs();
return 0;
}
void measureAllFuncs() {
// iterate through each function and call measureAndRecordFunc
for (auto &it : namesToFuncs) {
string funcName = it.first; // this is the value in the namesToFuncs map
uint64_t maxX = funcMaxXs[funcName]; // get maximum N
cout << "Testing " << funcName << "\n";
measureAndRecordFunc(funcName, maxX);
}
}
// times function and writes results to file
void measureAndRecordFunc(string funcName, uint64_t X, int nTrials) {
ofstream fout("output\\" + funcName, ios::trunc);
fout << "N\tX\tT\n";
long double sum = 0;
long double avg = 0;
for (uint64_t i = 0; i <= X; i++) {
cout << i << " ";
for (int trial = 0; trial < nTrials; trial++) {
long double time = timeFunction(funcName, i);
sum += time;
//cout << "Trial " << trial << ", time: " << time << "\n";
//cout << "Sum: " << sum << "\n";
}
avg = sum / nTrials;
// i (n) needs to be represented as number of bits
bitset<64> bits(i);
fout << bits.count() << "\t" << i << "\t" << avg << endl;
}
cout << "\n";
fout.close();
}
bool testAllFuncs() {
// test each function by name
for (auto& it : namesToFuncs) {
string funcName = it.first; // map value is function name
uint64_t maxX = funcMaxXs[funcName]; // max X
if (!testFibFunc(funcName, maxX)) {
return false; // return if failed
}
}
return true;
}
bool testFibFunc(string funcName, int X) {
// First 94 fibonaccis (including zero)
// fibonacci(93) is the max uint64_t can handle
cout << "Testing " << funcName << "\n";
for (uint64_t i = 0; i < X; i++) {
// grab function object from map
function<uint64_t(uint64_t)> func = namesToFuncs[funcName];
// call function with i and store result
uint64_t result = func(i);
// check if it matches known fibonacci number
if (result != FIBS[i]) {
cout << funcName << "(" << i << "): failed\n";
cout << "Expected: " << FIBS[i] << ".Got : " << result << "\n";
return false;
}
cout << funcName << "(" << i << "): passed\n";
}
return true;
}
// time function passed in, called with param
long double timeFunction(string funcName, uint64_t param) {
using namespace chrono; // temporarily use namespace for ease
function<uint64_t(uint64_t)> func = namesToFuncs[funcName];
high_resolution_clock::time_point start = high_resolution_clock::now();
func(param); // call fibonacci function
high_resolution_clock::time_point end = high_resolution_clock::now();
// calculate timeTaken
duration<long double> timeTaken = duration_cast<duration<long double>>(end - start);
return timeTaken.count() * 1000;
}