From 0fcfd492f85ac7cd8c310e9cae27d4024d838953 Mon Sep 17 00:00:00 2001 From: Joshua Moerman Date: Sun, 1 Dec 2013 17:38:55 +0100 Subject: [PATCH] Puts everything in a namespace --- wavelet/wavelet.hpp | 175 ++++++++++++++++------------------ wavelet/wavelet2.cpp | 2 + wavelet/wavelet_constants.hpp | 37 +++++++ 3 files changed, 122 insertions(+), 92 deletions(-) diff --git a/wavelet/wavelet.hpp b/wavelet/wavelet.hpp index 1bea72d..77a083c 100644 --- a/wavelet/wavelet.hpp +++ b/wavelet/wavelet.hpp @@ -4,108 +4,99 @@ #include "striding_iterator.hpp" #include "periodic_iterator.hpp" +#include "wavelet_constants.hpp" -static double const evn_coef[] = { - (1.0 + std::sqrt(3.0))/(std::sqrt(32.0)), - (3.0 + std::sqrt(3.0))/(std::sqrt(32.0)), - (3.0 - std::sqrt(3.0))/(std::sqrt(32.0)), - (1.0 - std::sqrt(3.0))/(std::sqrt(32.0)) -}; - -static double const odd_coef[] = { - evn_coef[3], - -evn_coef[2], - evn_coef[1], - -evn_coef[0] -}; - -// Apply the matrix Wn with the DAUB4 coefficients -// Assumes input to be periodic -template -void wavelet_mul(Iterator begin, Iterator end){ - auto mul = end - begin; - std::vector out(mul, 0.0); - for(int i = 0; i < mul; i += 2){ - out[i] = std::inner_product(evn_coef, evn_coef+4, periodic(begin, end) + i, 0.0); - out[i+1] = std::inner_product(odd_coef, odd_coef+4, periodic(begin, end) + i, 0.0); - } - for(int i = 0; i < mul; ++i){ - *begin++ = out[i]; - } -} +namespace wvlt { + namespace V1 { + // Apply the matrix Wn with the DAUB4 coefficients + template + void wavelet_mul(Iterator begin, Iterator end){ + auto mul = end - begin; + std::vector out(mul, 0.0); + for(int i = 0; i < mul; i += 2){ + out[i] = std::inner_product(evn_coef, evn_coef+4, periodic(begin, end) + i, 0.0); + out[i+1] = std::inner_product(odd_coef, odd_coef+4, periodic(begin, end) + i, 0.0); + } + for(int i = 0; i < mul; ++i){ + *begin++ = out[i]; + } + } -template -void wavelet_inv(Iterator begin, Iterator end){ - auto mul = end - begin; - std::vector out(mul, 0.0); - Iterator bc = begin; - for(int i = 0; i < mul; i += 2, begin += 2){ - Iterator b2 = begin + 1; - for(int j = 0; j < 4; ++j){ - out[(i+j) % mul] += *begin * evn_coef[j] + *b2 * odd_coef[j]; + // Apply inverse of the matrix Wn with the DAUB4 coefficients + template + void wavelet_inv(Iterator begin, Iterator end){ + auto mul = end - begin; + std::vector out(mul, 0.0); + Iterator bc = begin; + for(int i = 0; i < mul; i += 2, begin += 2){ + Iterator b2 = begin + 1; + for(int j = 0; j < 4; ++j){ + out[(i+j) % mul] += *begin * evn_coef[j] + *b2 * odd_coef[j]; + } + } + for(int i = 0; i < mul; ++i){ + *bc++ = out[i]; + } } - } - for(int i = 0; i < mul; ++i){ - *bc++ = out[i]; - } -} -// Shuffle works with an extra copy, might be inefficient, but it is at least correct ;) -// It applies the even-odd-sort matrix Sn -template -void shuffle(Iterator begin, Iterator end){ - typedef typename std::iterator_traits::value_type value_type; - auto s = end - begin; - assert(s % 2 == 0); + // Shuffle works with an extra copy, might be inefficient, but it is at least correct ;) + // It applies the even-odd-sort matrix Sn + template + void shuffle(Iterator begin, Iterator end){ + typedef typename std::iterator_traits::value_type value_type; + auto s = end - begin; + assert(s % 2 == 0); - std::vector v(s); - std::copy(strided(begin , 2), strided(end , 2), v.begin()); - std::copy(strided(begin+1, 2), strided(end+1, 2), v.begin() + s/2); - std::copy(v.begin(), v.end(), begin); -} + std::vector v(s); + std::copy(strided(begin , 2), strided(end , 2), v.begin()); + std::copy(strided(begin+1, 2), strided(end+1, 2), v.begin() + s/2); + std::copy(v.begin(), v.end(), begin); + } -template -void unshuffle(Iterator begin, Iterator end){ - typedef typename std::iterator_traits::value_type value_type; - auto s = end - begin; - assert(s % 2 == 0); + template + void unshuffle(Iterator begin, Iterator end){ + typedef typename std::iterator_traits::value_type value_type; + auto s = end - begin; + assert(s % 2 == 0); - std::vector v(s); - std::copy(begin, begin + s/2, strided(v.begin(), 2)); - std::copy(begin + s/2, end, strided(v.begin()+1, 2)); - std::copy(v.begin(), v.end(), begin); -} + std::vector v(s); + std::copy(begin, begin + s/2, strided(v.begin(), 2)); + std::copy(begin + s/2, end, strided(v.begin()+1, 2)); + std::copy(v.begin(), v.end(), begin); + } -// Combines the matrix Wn and Sn recusrively -// Only works for inputs of size 2^m -template -void wavelet(Iterator begin, Iterator end){ - auto s = end - begin; - assert(s >= 4); - for(int i = s; i >= 4; i >>= 1){ - // half interval - end = begin + i; - assert(is_pow_of_two(end - begin)); + // Combines the matrix Wn and Sn recusrively + // Only works for inputs of size 2^m + template + void wavelet(Iterator begin, Iterator end){ + auto s = end - begin; + assert(s >= 4); + for(int i = s; i >= 4; i >>= 1){ + // half interval + end = begin + i; + assert(is_pow_of_two(end - begin)); - // multiply with Wn - wavelet_mul(begin, end); - // then with Sn - shuffle(begin, end); - } -} + // multiply with Wn + wavelet_mul(begin, end); + // then with Sn + shuffle(begin, end); + } + } -template -void unwavelet(Iterator begin, Iterator end){ - auto s = end - begin; - assert(s >= 4); - for(int i = 4; i <= s; i <<= 1){ - // double interval - end = begin + i; - assert(is_pow_of_two(end - begin)); + template + void unwavelet(Iterator begin, Iterator end){ + auto s = end - begin; + assert(s >= 4); + for(int i = 4; i <= s; i <<= 1){ + // double interval + end = begin + i; + assert(is_pow_of_two(end - begin)); - // unshuffle: Sn^-1 - unshuffle(begin, end); - // then Wn^-1 - wavelet_inv(begin, end); + // unshuffle: Sn^-1 + unshuffle(begin, end); + // then Wn^-1 + wavelet_inv(begin, end); + } + } } } diff --git a/wavelet/wavelet2.cpp b/wavelet/wavelet2.cpp index 4433ada..3e3c505 100644 --- a/wavelet/wavelet2.cpp +++ b/wavelet/wavelet2.cpp @@ -9,6 +9,8 @@ #include "periodic_iterator.hpp" #include "wavelet.hpp" +using namespace wvlt::V1; + // note: we take a copy, because we will modify it in place jcmp::image compress(std::vector image, int width, double threshold, int& zeros){ auto height = image.size() / width; diff --git a/wavelet/wavelet_constants.hpp b/wavelet/wavelet_constants.hpp index e69de29..4647816 100644 --- a/wavelet/wavelet_constants.hpp +++ b/wavelet/wavelet_constants.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include + +namespace wvlt { + // first row of the matrix Wn + static double const evn_coef[] = { + (1.0 + std::sqrt(3.0))/(std::sqrt(32.0)), + (3.0 + std::sqrt(3.0))/(std::sqrt(32.0)), + (3.0 - std::sqrt(3.0))/(std::sqrt(32.0)), + (1.0 - std::sqrt(3.0))/(std::sqrt(32.0)) + }; + + // second row of the matrix Wn + static double const odd_coef[] = { + evn_coef[3], + -evn_coef[2], + evn_coef[1], + -evn_coef[0] + }; + + // first (shifted) row of the matrix Wn^-1 + static double const evn_coef_inv[] = { + evn_coef[2], + evn_coef[1], + evn_coef[0], + evn_coef[3] + }; + + // second (shifted) row of the matrix Wn^-1 + static double const odd_coef_inv[] = { + evn_coef[3], + -evn_coef[0], + evn_coef[1], + -evn_coef[2] + }; +}