diff --git a/include/utilities.hpp b/include/utilities.hpp index 1fd6cd1..029fb85 100644 --- a/include/utilities.hpp +++ b/include/utilities.hpp @@ -3,10 +3,16 @@ #include #include -inline bool is_pow_of_two(int n){ +template +bool is_pow_of_two(Int n){ return (n & (n - 1)) == 0; } +template +bool is_even(Int n){ + return (n & 1) == 0; +} + // calculates integer 2-log such that: // 2^(two_log(x)) >= x > 2^(two_log(x) - 1) unsigned int two_log(unsigned int x){ @@ -14,6 +20,8 @@ unsigned int two_log(unsigned int x){ return 8*sizeof(unsigned int) - __builtin_clz(x-1); } +// Makes numbers human-readable +// eg 2300000 becomes 2M inline std::string human_string(int n){ static const std::string names [] = {"", "K", "M", "G"}; int i = 0; @@ -21,7 +29,8 @@ inline std::string human_string(int n){ n /= 1000; ++i; } - return std::to_string(n) + names[i]; + // cast is to make the old gcc 4.4 happy (it doesn't have all overloads of to_string) + return std::to_string((long long)n) + names[i]; } inline std::string field(std::string const & str){ @@ -31,6 +40,17 @@ inline std::string field(std::string const & str){ return str + ":" + std::string(add, ' ') + "\t"; } +// Prints a vector with brackets and commas +// Does not work recursively! +template +void print_vec(std::vector v){ + auto it = v.begin(), end = v.end(); + std::cout << "{" << *it++; + while(it != end) std::cout << ", " << *it++; + std::cout << "}\n"; +} + +// RAII struct for timing struct timer{ typedef std::chrono::high_resolution_clock clock; typedef std::chrono::time_point time; @@ -46,7 +66,19 @@ struct timer{ ~timer(){ time end = clock::now(); - seconds elapsed = end - begin; - std::cout << name << "\t" << elapsed.count() << std::endl; + std::cout << name << "\t" << from_dur(end - begin) << std::endl; + } + + static double from_dur(seconds s){ + return s.count(); } }; + +namespace colors { + std::string red(std::string s){ + return "\x1b[31m" + s + "\x1b[39m"; + } + std::string green(std::string s){ + return "\x1b[32m" + s + "\x1b[39m"; + } +} diff --git a/wavelet/wavelet_test.cpp b/wavelet/wavelet_test.cpp index e69de29..85737bd 100644 --- a/wavelet/wavelet_test.cpp +++ b/wavelet/wavelet_test.cpp @@ -0,0 +1,59 @@ +#include +#include + +#include "wavelet.hpp" +#include "wavelet2.hpp" + + +template +void print_vec(std::vector v){ + auto it = v.begin(), end = v.end(); + std::cout << "{" << *it++; + while(it != end) std::cout << ", " << *it++; + std::cout << "}\n"; +} + +void timing_test(){ + std::vector input1 = {-1.0, -2.0, 2.0, 1.0, -3.0, -4.0, 4.0, 3.0}; + std::vector input2 = input1; + int test_size = 10; + + { timer t("newwvlt"); + auto const n = input1.size(); + for(int i = 0; i < test_size; ++i) + wvlt::V2::wavelet_mul(input2.data(), input2[0], input2[1], n, 1); + for(int i = 0; i < test_size; ++i) + wvlt::V2::wavelet_inv(input2.data(), input2[n-1], input2[n-2], n, 1); + } + { timer t("wavelet"); + for(int i = 0; i < test_size; ++i) + wvlt::V1::wavelet_mul(input1.begin(), input1.end()); + for(int i = 0; i < test_size; ++i) + wvlt::V1::wavelet_inv(input1.begin(), input1.end()); + } + + print_vec(input1); + print_vec(input2); +} + +void correctness_test(){ + std::vector input1 = {-1.0, -2.0, 2.0, 1.0, -3.0, -4.0, 4.0, 3.0}; + std::vector input2 = input1; + + wvlt::V1::wavelet(input1.begin(), input1.end()); + wvlt::V1::unwavelet(input1.begin(), input1.end()); + + wvlt::V2::wavelet(input2.data(), input2.size()); + wvlt::V2::unwavelet(input2.data(), input2.size()); + + std::cout << "V1\t"; print_vec(input1); + std::cout << "V2\t"; print_vec(input2); +} + +int main(){ + std::cout << "*** CORRECTNESS TEST ***\n"; + correctness_test(); + std::cout << "*** TIMING TEST ***\n"; + timing_test(); +} +