00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef WAVELET_H
00019 #define WAVELET_H
00020
00021 #include <cassert>
00022 #include <cmath>
00023 #include <limits>
00024 #include <vector>
00025 #include <string>
00026 #include <iostream>
00027 #include <blitz/array.h>
00028
00029 #include "arrayTools.h"
00030
00031 namespace bwave {
00032
00033
00041
00042 class Wavelet {
00043 public:
00046 static bool equals(double x, double y);
00047
00048 public:
00051
00052 class WaveletComponent {
00053 public:
00054 virtual ~WaveletComponent() { }
00055 };
00056
00074
00075 class LiftingStep : public WaveletComponent {
00076 public:
00078 enum Type { PRIMAL, DUAL, SSCALE, DSCALE };
00079
00080 protected:
00081 Type m_type;
00082 int m_origin;
00083 std::vector<double> m_coeffs;
00084 double m_divisor;
00085
00086 template<class tp_Type, int tp_size> inline void applyFS
00087 (blitz::Array<tp_Type, 1> &s, blitz::Array<tp_Type, 1> &d, bool inverse, ExtensionMode be) const;
00088
00089 public:
00093 Type type() const { return m_type; }
00094
00098 int origin() const { return m_origin; }
00099
00102 int size() const { return int(m_coeffs.size()); }
00103
00107 double coeff(int i) const { return m_coeffs[i]; }
00108
00111 double divisor() const { return m_divisor; }
00112
00118 template<class tp_Type> inline void apply
00119 (blitz::Array<tp_Type, 1> &s, blitz::Array<tp_Type, 1> &d, bool inverse, ExtensionMode be=CONSTANT_EXT) const;
00120
00122 LiftingStep () {}
00123
00133 LiftingStep (Type t, int o, double d, double c0);
00135 LiftingStep (Type t, int o, double d, double c0, double c1);
00137 LiftingStep (Type t, int o, double d, double c0, double c1, double c2);
00139 LiftingStep (Type t, int o, double d, double c0, double c1, double c2, double c3);
00141 LiftingStep (Type t, int o, double d, double c0, double c1, double c2, double c3, double c4);
00143 LiftingStep (Type t, int o, double d, double c0, double c1, double c2, double c3, double c4, double c5);
00144
00149 bool operator==(const LiftingStep &s) const;
00150
00152 virtual ~LiftingStep() {}
00153 };
00154
00155 protected:
00156 std::string m_spec;
00157 double m_nS, m_nD;
00158 std::vector<LiftingStep> m_steps;
00159
00160 public:
00162 const std::string& name() const { return m_spec; }
00163
00174 bool integerCompatible() const;
00175
00180 bool normalized() const;
00181
00183 int steps() const { return int(m_steps.size()); }
00184
00187 const LiftingStep& liftingStep(int i) const { return m_steps[i]; }
00188
00193 double normS() const { return m_nS; }
00194
00197 double normD() const { return m_nD; }
00198
00202 bool operator==(const Wavelet &w) const;
00203
00210 template<class tp_Type> void lift( blitz::Array<tp_Type, 1> &s,
00211 blitz::Array<tp_Type, 1> &d, ExtensionMode be=CONSTANT_EXT) const;
00212
00217 template<class tp_Type> void invLift( blitz::Array<tp_Type, 1> &s,
00218 blitz::Array<tp_Type, 1> &d, ExtensionMode be=CONSTANT_EXT) const;
00219
00220
00231 blitz::Array<double, 1> forwardFkt(unsigned int size = 1<<9, int scale = 6,
00232 unsigned int trans = 3) const;
00233
00237 blitz::Array<double, 1> inverseFkt(unsigned int size = 1<<9, int scale = 6,
00238 unsigned int trans = 3) const;
00239
00241 Wavelet() {}
00242
00252 Wavelet(const std::string &name, double ns, double nd, const LiftingStep &s0, const LiftingStep &s1);
00254 Wavelet(const std::string &name, double ns, double nd, const LiftingStep &s0, const LiftingStep &s1, const LiftingStep &s2);
00256 Wavelet(const std::string &name, double ns, double nd, const LiftingStep &s0, const LiftingStep &s1, const LiftingStep &s2, const LiftingStep &s3);
00257
00258 virtual ~Wavelet() {}
00259 };
00260
00261
00265 std::ostream & operator<<(std::ostream &os, const Wavelet::LiftingStep &s);
00266
00270 std::ostream & operator<<(std::ostream &os, const Wavelet &w);
00271
00272
00275 extern const Wavelet WL_CDF_1_1;
00276
00281 extern const Wavelet WL_CDF_2_2;
00282
00284 extern const Wavelet WL_CDF_3_1;
00285
00287 extern const Wavelet WL_CDF_3_3;
00288
00290 extern const Wavelet WL_CDF_4_2;
00291
00296 extern const Wavelet WL_CDF_97;
00297
00299 extern const Wavelet WL_HAAR;
00300
00304 extern const Wavelet WL_LEG_5_3;
00305
00311 extern const Wavelet WL_CUBIC_SPLINE;
00312
00314 extern const Wavelet WL_D_4;
00315
00316
00317 template<class tp_Type, int tp_size> void Wavelet::LiftingStep::applyFS
00318 (blitz::Array<tp_Type, 1> &s, blitz::Array<tp_Type, 1> &d, bool inverse, ExtensionMode be) const
00319 {
00320 assert(size() == tp_size);
00321 tp_Type coeffs[tp_size];
00322 for (int i=0; i<size(); ++i) coeffs[i] = (tp_Type) coeff(i);
00323 GenFilter<tp_Type, tp_size> liftFilter(origin(), coeffs, (tp_Type) divisor());
00324
00325 if (type() == PRIMAL) {
00326 if (!inverse) liftFilter.applyAdd(d, s, be);
00327 else liftFilter.applySub(d, s, be);
00328 } else if (type() == DUAL) {
00329 if (!inverse) liftFilter.applyAdd(s, d, be);
00330 else liftFilter.applySub(s, d, be);
00331 } else if (type() == SSCALE) {
00332 if (!inverse) {
00333 s *= tp_Type(coeff(0));
00334 if (divisor()!=1.) s /= tp_Type(divisor());
00335 }
00336 else {
00337 if (divisor()!=1.) s *= tp_Type(divisor());
00338 s /= tp_Type(coeff(0));
00339 }
00340 } else if (type() == DSCALE) {
00341 if (!inverse) {
00342 d *= tp_Type(coeff(0));
00343 if (divisor()!=1.) d /= tp_Type(divisor());
00344 }
00345 else {
00346 if (divisor()!=1.) d *= tp_Type(divisor());
00347 d /= tp_Type(coeff(0));
00348 }
00349 } else {
00350 assert(false);
00351 }
00352 }
00353
00354
00355 template<class tp_Type> void Wavelet::LiftingStep::apply
00356 (blitz::Array<tp_Type, 1> &s, blitz::Array<tp_Type, 1> &d, bool inverse, ExtensionMode be) const
00357 {
00358 switch(size()) {
00359 case 1: applyFS<tp_Type, 1>(s, d, inverse, be); break;
00360 case 2: applyFS<tp_Type, 2>(s, d, inverse, be); break;
00361 case 3: applyFS<tp_Type, 3>(s, d, inverse, be); break;
00362
00363
00364
00365 default: assert(false);
00366 }
00367 }
00368
00369
00370 template<class tp_Type> void Wavelet::lift( blitz::Array<tp_Type, 1> &s,
00371 blitz::Array<tp_Type, 1> &d, ExtensionMode be) const
00372 {
00373 for (int step=0; step<steps(); ++step)
00374 liftingStep(step).apply(s, d, false, be);
00375 }
00376
00377
00378 template<class tp_Type> void Wavelet::invLift( blitz::Array<tp_Type, 1> &s,
00379 blitz::Array<tp_Type, 1> &d, ExtensionMode be) const
00380 {
00381 for (int step=steps()-1; step>=0; --step)
00382 liftingStep(step).apply(s, d, true, be);
00383 }
00384
00385
00386 }
00387
00388 #endif