Browse Source

Puts everything in a namespace

master
Joshua Moerman 11 years ago
parent
commit
0fcfd492f8
  1. 175
      wavelet/wavelet.hpp
  2. 2
      wavelet/wavelet2.cpp
  3. 37
      wavelet/wavelet_constants.hpp

175
wavelet/wavelet.hpp

@ -4,108 +4,99 @@
#include "striding_iterator.hpp" #include "striding_iterator.hpp"
#include "periodic_iterator.hpp" #include "periodic_iterator.hpp"
#include "wavelet_constants.hpp"
static double const evn_coef[] = { namespace wvlt {
(1.0 + std::sqrt(3.0))/(std::sqrt(32.0)), namespace V1 {
(3.0 + std::sqrt(3.0))/(std::sqrt(32.0)), // Apply the matrix Wn with the DAUB4 coefficients
(3.0 - std::sqrt(3.0))/(std::sqrt(32.0)), template <typename Iterator>
(1.0 - std::sqrt(3.0))/(std::sqrt(32.0)) void wavelet_mul(Iterator begin, Iterator end){
}; auto mul = end - begin;
std::vector<double> out(mul, 0.0);
static double const odd_coef[] = { for(int i = 0; i < mul; i += 2){
evn_coef[3], out[i] = std::inner_product(evn_coef, evn_coef+4, periodic(begin, end) + i, 0.0);
-evn_coef[2], out[i+1] = std::inner_product(odd_coef, odd_coef+4, periodic(begin, end) + i, 0.0);
evn_coef[1], }
-evn_coef[0] for(int i = 0; i < mul; ++i){
}; *begin++ = out[i];
}
// Apply the matrix Wn with the DAUB4 coefficients }
// Assumes input to be periodic
template <typename Iterator>
void wavelet_mul(Iterator begin, Iterator end){
auto mul = end - begin;
std::vector<double> 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 <typename Iterator> // Apply inverse of the matrix Wn with the DAUB4 coefficients
void wavelet_inv(Iterator begin, Iterator end){ template <typename Iterator>
auto mul = end - begin; void wavelet_inv(Iterator begin, Iterator end){
std::vector<double> out(mul, 0.0); auto mul = end - begin;
Iterator bc = begin; std::vector<double> out(mul, 0.0);
for(int i = 0; i < mul; i += 2, begin += 2){ Iterator bc = begin;
Iterator b2 = begin + 1; for(int i = 0; i < mul; i += 2, begin += 2){
for(int j = 0; j < 4; ++j){ Iterator b2 = begin + 1;
out[(i+j) % mul] += *begin * evn_coef[j] + *b2 * odd_coef[j]; 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 ;) // Shuffle works with an extra copy, might be inefficient, but it is at least correct ;)
// It applies the even-odd-sort matrix Sn // It applies the even-odd-sort matrix Sn
template <typename Iterator> template <typename Iterator>
void shuffle(Iterator begin, Iterator end){ void shuffle(Iterator begin, Iterator end){
typedef typename std::iterator_traits<Iterator>::value_type value_type; typedef typename std::iterator_traits<Iterator>::value_type value_type;
auto s = end - begin; auto s = end - begin;
assert(s % 2 == 0); assert(s % 2 == 0);
std::vector<value_type> v(s); std::vector<value_type> v(s);
std::copy(strided(begin , 2), strided(end , 2), v.begin()); 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(strided(begin+1, 2), strided(end+1, 2), v.begin() + s/2);
std::copy(v.begin(), v.end(), begin); std::copy(v.begin(), v.end(), begin);
} }
template <typename Iterator> template <typename Iterator>
void unshuffle(Iterator begin, Iterator end){ void unshuffle(Iterator begin, Iterator end){
typedef typename std::iterator_traits<Iterator>::value_type value_type; typedef typename std::iterator_traits<Iterator>::value_type value_type;
auto s = end - begin; auto s = end - begin;
assert(s % 2 == 0); assert(s % 2 == 0);
std::vector<value_type> v(s); std::vector<value_type> v(s);
std::copy(begin, begin + s/2, strided(v.begin(), 2)); std::copy(begin, begin + s/2, strided(v.begin(), 2));
std::copy(begin + s/2, end, strided(v.begin()+1, 2)); std::copy(begin + s/2, end, strided(v.begin()+1, 2));
std::copy(v.begin(), v.end(), begin); std::copy(v.begin(), v.end(), begin);
} }
// Combines the matrix Wn and Sn recusrively // Combines the matrix Wn and Sn recusrively
// Only works for inputs of size 2^m // Only works for inputs of size 2^m
template <typename Iterator> template <typename Iterator>
void wavelet(Iterator begin, Iterator end){ void wavelet(Iterator begin, Iterator end){
auto s = end - begin; auto s = end - begin;
assert(s >= 4); assert(s >= 4);
for(int i = s; i >= 4; i >>= 1){ for(int i = s; i >= 4; i >>= 1){
// half interval // half interval
end = begin + i; end = begin + i;
assert(is_pow_of_two(end - begin)); assert(is_pow_of_two(end - begin));
// multiply with Wn // multiply with Wn
wavelet_mul(begin, end); wavelet_mul(begin, end);
// then with Sn // then with Sn
shuffle(begin, end); shuffle(begin, end);
} }
} }
template <typename Iterator> template <typename Iterator>
void unwavelet(Iterator begin, Iterator end){ void unwavelet(Iterator begin, Iterator end){
auto s = end - begin; auto s = end - begin;
assert(s >= 4); assert(s >= 4);
for(int i = 4; i <= s; i <<= 1){ for(int i = 4; i <= s; i <<= 1){
// double interval // double interval
end = begin + i; end = begin + i;
assert(is_pow_of_two(end - begin)); assert(is_pow_of_two(end - begin));
// unshuffle: Sn^-1 // unshuffle: Sn^-1
unshuffle(begin, end); unshuffle(begin, end);
// then Wn^-1 // then Wn^-1
wavelet_inv(begin, end); wavelet_inv(begin, end);
}
}
} }
} }

2
wavelet/wavelet2.cpp

@ -9,6 +9,8 @@
#include "periodic_iterator.hpp" #include "periodic_iterator.hpp"
#include "wavelet.hpp" #include "wavelet.hpp"
using namespace wvlt::V1;
// note: we take a copy, because we will modify it in place // note: we take a copy, because we will modify it in place
jcmp::image compress(std::vector<double> image, int width, double threshold, int& zeros){ jcmp::image compress(std::vector<double> image, int width, double threshold, int& zeros){
auto height = image.size() / width; auto height = image.size() / width;

37
wavelet/wavelet_constants.hpp

@ -0,0 +1,37 @@
#pragma once
#include <cmath>
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]
};
}