00001
00030 #ifndef TRANSFORMS_H
00031 #define TRANSFORMS_H
00032
00033 #ifndef _MSC_VER
00034 # include <itpp/config.h>
00035 #else
00036 # include <itpp/config_msvc.h>
00037 #endif
00038
00039 #include <itpp/base/vec.h>
00040 #include <itpp/base/mat.h>
00041 #include <itpp/base/matfunc.h>
00042
00043
00044 namespace itpp
00045 {
00046
00087
00088
00089
00091 void fft(const cvec &in, cvec &out);
00093 cvec fft(const cvec &in);
00095 cvec fft(const cvec &in, const int N);
00097 void ifft(const cvec &in, cvec &out);
00099 cvec ifft(const cvec &in);
00101 cvec ifft(const cvec &in, const int N);
00102
00104 void fft_real(const vec& in, cvec &out);
00106 cvec fft_real(const vec& in);
00108 cvec fft_real(const vec &in, const int N);
00110 void ifft_real(const cvec &in, vec &out);
00112 vec ifft_real(const cvec &in);
00114 vec ifft_real(const cvec &in, const int N);
00116
00117
00159
00160
00161
00163 void dct(const vec &in, vec &out);
00165 vec dct(const vec &in);
00167 void idct(const vec &in, vec &out);
00169 vec idct(const vec &in);
00171
00172
00175
00177 template <class T> Vec<T> dht(const Vec<T> &v);
00179 template <class T> void dht(const Vec<T> &vin, Vec<T> &vout);
00181 template <class T> void self_dht(Vec<T> &v);
00182
00184 template <class T> Vec<T> dwht(const Vec<T> &v);
00186 template <class T> void dwht(const Vec<T> &vin, Vec<T> &vout);
00188 template <class T> void self_dwht(Vec<T> &v);
00189
00191 template <class T> Mat<T> dht2(const Mat<T> &m);
00193 template <class T> Mat<T> dwht2(const Mat<T> &m);
00195
00196 template <class T>
00197 Vec<T> dht(const Vec<T> &v)
00198 {
00199 Vec<T> ret(v.size());
00200 dht(v, ret);
00201 return ret;
00202 }
00203
00205 template <class T>
00206 void bitrv(Vec<T> &out)
00207 {
00208 int N = out.size();
00209 int j = 0;
00210 int N1 = N - 1;
00211 for (int i = 0; i < N1; ++i) {
00212 if (i < j) {
00213 T temp = out[j];
00214 out[j] = out[i];
00215 out[i] = temp;
00216 }
00217 int K = N / 2;
00218 while (K <= j) {
00219 j -= K;
00220 K /= 2;
00221 }
00222 j += K;
00223 }
00224 }
00225
00226 template <class T>
00227 void dht(const Vec<T> &vin, Vec<T> &vout)
00228 {
00229 int N = vin.size();
00230 int m = levels2bits(N);
00231 it_assert_debug((1 << m) == N, "dht(): The vector size must be a power of two");
00232
00233 vout.set_size(N);
00234
00235
00236 for (int ib = 0; ib < N; ib += 2) {
00237 vout(ib) = vin(ib) + vin(ib + 1);
00238 vout(ib + 1) = vin(ib) - vin(ib + 1);
00239 }
00240 N /= 2;
00241
00242 int l = 2;
00243 for (int i = 1; i < m; ++i) {
00244 N /= 2;
00245 int ib = 0;
00246 for (int k = 0; k < N; ++k) {
00247 for (int j = 0; j < l; ++j) {
00248 T t = vout(ib + j);
00249 vout(ib + j) += vout(ib + j + l);
00250 vout(ib + j + l) = t - vout(ib + j + l);
00251 }
00252 ib += 2 * l;
00253 }
00254 l *= 2;
00255 }
00256
00257 vout /= static_cast<T>(std::sqrt(static_cast<double>(vin.size())));
00258 }
00259
00260 template <class T>
00261 void self_dht(Vec<T> &v)
00262 {
00263 int N = v.size();
00264 int m = levels2bits(N);
00265 it_assert_debug((1 << m) == N, "self_dht(): The vector size must be a power "
00266 "of two");
00267
00268 int l = 1;
00269 for (int i = 0; i < m; ++i) {
00270 N /= 2;
00271 int ib = 0;
00272 for (int k = 0; k < N; ++k) {
00273 for (int j = 0; j < l; ++j) {
00274 T t = v(ib + j);
00275 v(ib + j) += v(ib + j + l);
00276 v(ib + j + l) = t - v(ib + j + l);
00277 }
00278 ib += 2 * l;
00279 }
00280 l *= 2;
00281 }
00282
00283 v /= static_cast<T>(std::sqrt(static_cast<double>(v.size())));
00284 }
00285
00286 template <class T>
00287 Vec<T> dwht(const Vec<T> &v)
00288 {
00289 Vec<T> ret(v.size());
00290 dwht(v, ret);
00291 return ret;
00292 }
00293
00294 template <class T>
00295 void dwht(const Vec<T> &vin, Vec<T> &vout)
00296 {
00297 dht(vin, vout);
00298 bitrv(vout);
00299 }
00300
00301
00302 template <class T>
00303 void self_dwht(Vec<T> &v)
00304 {
00305 self_dht(v);
00306 bitrv(v);
00307 }
00308
00309 template <class T>
00310 Mat<T> dht2(const Mat<T> &m)
00311 {
00312 Mat<T> ret(m.rows(), m.cols());
00313 Vec<T> v;
00314
00315 for (int i = 0; i < m.rows(); ++i) {
00316 v = m.get_row(i);
00317 self_dht(v);
00318 ret.set_row(i, v);
00319 }
00320 for (int i = 0; i < m.cols(); ++i) {
00321 v = ret.get_col(i);
00322 self_dht(v);
00323 ret.set_col(i, v);
00324 }
00325
00326 return transpose(ret);
00327 }
00328
00329 template <class T>
00330 Mat<T> dwht2(const Mat<T> &m)
00331 {
00332 Mat<T> ret(m.rows(), m.cols());
00333 Vec<T> v;
00334
00335 for (int i = 0; i < m.rows(); ++i) {
00336 v = m.get_row(i);
00337 self_dwht(v);
00338 ret.set_row(i, v);
00339 }
00340 for (int i = 0; i < m.cols(); ++i) {
00341 v = ret.get_col(i);
00342 self_dwht(v);
00343 ret.set_col(i, v);
00344 }
00345
00346 return transpose(ret);
00347 }
00348
00350
00351
00352
00353
00354
00355 #ifdef HAVE_EXTERN_TEMPLATE
00356
00357 extern template vec dht(const vec &v);
00358 extern template cvec dht(const cvec &v);
00359 extern template void dht(const vec &vin, vec &vout);
00360 extern template void dht(const cvec &vin, cvec &vout);
00361
00362 extern template void self_dht(vec &v);
00363 extern template void self_dht(cvec &v);
00364
00365 extern template vec dwht(const vec &v);
00366 extern template cvec dwht(const cvec &v);
00367 extern template void dwht(const vec &vin, vec &vout);
00368 extern template void dwht(const cvec &vin, cvec &vout);
00369
00370 extern template void self_dwht(vec &v);
00371 extern template void self_dwht(cvec &v);
00372
00373 extern template mat dht2(const mat &m);
00374 extern template cmat dht2(const cmat &m);
00375
00376 extern template mat dwht2(const mat &m);
00377 extern template cmat dwht2(const cmat &m);
00378
00379 #endif // HAVE_EXTERN_TEMPLATE
00380
00382
00383 }
00384
00385 #endif // #ifndef TRANSFORMS_H