Browse Source

Added code to test correctness/speed of implementations.

Some small bits and pieces in utilities.
master
Joshua Moerman 11 years ago
parent
commit
a4bf3adb7d
  1. 40
      include/utilities.hpp
  2. 59
      wavelet/wavelet_test.cpp

40
include/utilities.hpp

@ -3,10 +3,16 @@
#include <string> #include <string>
#include <chrono> #include <chrono>
inline bool is_pow_of_two(int n){ template <typename Int>
bool is_pow_of_two(Int n){
return (n & (n - 1)) == 0; return (n & (n - 1)) == 0;
} }
template <typename Int>
bool is_even(Int n){
return (n & 1) == 0;
}
// calculates integer 2-log such that: // calculates integer 2-log such that:
// 2^(two_log(x)) >= x > 2^(two_log(x) - 1) // 2^(two_log(x)) >= x > 2^(two_log(x) - 1)
unsigned int two_log(unsigned int x){ 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); return 8*sizeof(unsigned int) - __builtin_clz(x-1);
} }
// Makes numbers human-readable
// eg 2300000 becomes 2M
inline std::string human_string(int n){ inline std::string human_string(int n){
static const std::string names [] = {"", "K", "M", "G"}; static const std::string names [] = {"", "K", "M", "G"};
int i = 0; int i = 0;
@ -21,7 +29,8 @@ inline std::string human_string(int n){
n /= 1000; n /= 1000;
++i; ++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){ 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"; return str + ":" + std::string(add, ' ') + "\t";
} }
// Prints a vector with brackets and commas
// Does not work recursively!
template <typename T>
void print_vec(std::vector<T> 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{ struct timer{
typedef std::chrono::high_resolution_clock clock; typedef std::chrono::high_resolution_clock clock;
typedef std::chrono::time_point<clock> time; typedef std::chrono::time_point<clock> time;
@ -46,7 +66,19 @@ struct timer{
~timer(){ ~timer(){
time end = clock::now(); time end = clock::now();
seconds elapsed = end - begin; std::cout << name << "\t" << from_dur(end - begin) << std::endl;
std::cout << name << "\t" << elapsed.count() << 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";
}
}

59
wavelet/wavelet_test.cpp

@ -0,0 +1,59 @@
#include <includes.hpp>
#include <utilities.hpp>
#include "wavelet.hpp"
#include "wavelet2.hpp"
template <typename T>
void print_vec(std::vector<T> 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<double> input1 = {-1.0, -2.0, 2.0, 1.0, -3.0, -4.0, 4.0, 3.0};
std::vector<double> 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<double> input1 = {-1.0, -2.0, 2.0, 1.0, -3.0, -4.0, 4.0, 3.0};
std::vector<double> 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();
}