Generative Fast Fourier Transforms (GFFT)  0.3
thirdparty.h
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2014 by Vladimir Mirnyy *
3  * *
4  * This program is free software; you can redistribute it and/or modify *
5  * it under the terms of the GNU General Public License as published by *
6  * the Free Software Foundation; either version 2 of the License, or *
7  * (at your option) any later version. *
8  * *
9  * This program is distributed in the hope that it will be useful, *
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12  * GNU General Public License for more details. *
13  ***************************************************************************/
14 
19 #include <iostream>
20 
21 #ifdef FFTW
22 #include <fftw3.h>
23 //#include <boost/iterator/iterator_concepts.hpp>
24 #endif
25 
26 //#include "nrfft.h"
27 #ifdef ARPREC
28 #include <arprec/mp_real.h>
29 #endif
30 
31 
32 template<class T>
33 class DFT_wrapper
34 {
35  void dft1(T* output_data, const T* input_data, const int_t size, bool inverse)
36  {
37  T pi2 = (inverse) ? 2.0 * M_PI : -2.0 * M_PI;
38  T a, ca, sa;
39  T invs = 1.0 / size;
40  for(int_t y = 0; y < size; y++) {
41  output_data[2*y] = 0.;
42  output_data[2*y+1] = 0.;
43  for(int_t x = 0; x < size; x++) {
44  a = pi2 * y * x * invs;
45  ca = cos(a);
46  sa = sin(a);
47  output_data[2*y] += input_data[2*x] * ca - input_data[2*x+1] * sa;
48  output_data[2*y+1] += input_data[2*x] * sa + input_data[2*x+1] * ca;
49  }
50  if(inverse) {
51  output_data[2*y] *= invs;
52  output_data[2*y+1] *= invs;
53  }
54  }
55  }
56 
57  T* input_data;
58  T* output_data;
59  int_t size;
60 
61 public:
62 
63  typedef T value_type;
64 
65  DFT_wrapper(const double* data, int_t n) : size(n)
66  {
67  init(data, n);
68  }
69  DFT_wrapper(const std::complex<double>* data, int_t n) : size(n)
70  {
71  init(data, n);
72  }
73  ~DFT_wrapper()
74  {
75  delete [] input_data;
76  delete [] output_data;
77  }
78 
79  T* getdata() const { return output_data; }
80 
81  template<typename Tp>
82  void init(const Tp* data, int_t n)
83  {
84  input_data = new T [n*2];
85  output_data = new T [n*2];
86 
87  for (int_t i=0; i < n*2; ++i) {
88  input_data[i] = data[i];
89  }
90  }
91  template<typename Tp>
92  void init(const std::complex<Tp>* data, int_t n)
93  {
94  input_data = new T [n*2];
95  output_data = new T [n*2];
96 
97  for (int_t i=0; i < n; ++i) {
98  input_data[2*i] = data[i].real();
99  input_data[2*i+1] = data[i].imag();
100  }
101  }
102 
103  void apply()
104  {
105  dft1(output_data, input_data, size, false);
106  }
107 
108  template<class Tp>
109  void diff(Tp* data)
110  {
111  for (int_t i=0; i<size*2; ++i)
112  data[i] -= output_data[i];
113  }
114  template<class Tp>
115  void diff(std::complex<Tp>* data)
116  {
117  for (int_t i=0; i<size; ++i) {
118  //data[i].real() -= output_data[2*i];
119  //data[i].imag() -= output_data[2*i+1];
120  data[i] -= std::complex<Tp>(output_data[2*i], output_data[2*i+1]);
121  }
122  }
123 };
124 
125 
126 #ifdef FFTW
127 template<class T>
128 class FFTW_wrapper
129 {
130  T* in;
131  T* out;
132  fftw_plan plan;
133  int_t size;
134 public:
135 
136  typedef T value_type;
137 
138  FFTW_wrapper(const double* data, int_t n) : size(n)
139  {
140  init(data, n);
141  }
142  ~FFTW_wrapper()
143  {
144  fftw_free(in);
145  fftw_free(out);
146  }
147 
148  void init(const double* data, int_t n)
149  {
150  in = (T*)fftw_malloc(sizeof(T)*n);
151  out = (T*)fftw_malloc(sizeof(T)*n);
152 
153  for (int_t i=0; i < n; ++i) {
154  in[i][0] = data[2*i];
155  in[i][1] = data[2*i+1];
156  }
157  }
158 
159  void apply()
160  {
161  plan = fftw_plan_dft_1d(size, in, out, FFTW_FORWARD, FFTW_ESTIMATE);
162  fftw_execute(plan);
163  }
164 
165  template<typename OtherType>
166  void diff(OtherType* data)
167  {
168  for (int_t i=0; i<size; ++i) {
169  data[2*i] -= out[i][0];
170  data[2*i+1] -= out[i][1];
171  }
172  }
173 };
174 #endif
175 
176 template<class T>
177 class Arprec_wrapper
178 {
179  T* y;
180  T* in;
181  int_t size;
182  int m, m1, m2;
183 public:
184  Arprec_wrapper(const T* data, int_t n) : size(n)
185  {
186  init(data, n);
187  }
188  ~Arprec_wrapper()
189  {
190  delete [] in;
191  delete [] y;
192  }
193 
194  T* getdata() const { return in; }
195 
196  void init(const T* data, int_t n)
197  {
198  in = new T [n * 2];
199 
200  m = log(n)/log(2);
201  m1 = ((m + 1) / 2);
202  m2 = (m - (m + 1) / 2);
203  int n1 = 1 << m1;
204  y = new T [(n + n1 * mp::mpnsp1) * 2];
205 // y = new T [n * 4];
206  mp_real::mpinix(n);
207 
208 // print out sample data
209 // cout<<"Input data:"<<endl;
210 // for (int i=0; i < n; ++i)
211 // cout<<"("<<data[2*i]<<","<<data[2*i+1]<<")"<<endl;
212 
213  for (int_t i=0; i < 2*n; ++i) {
214  in[i] = data[i];
215  }
216  }
217 
218  void apply()
219  {
220  mp_real::mpfft1(-1, m, m1, m2, in, y);
221 
222  // print out sample data
223 // cout<<"Output data:"<<endl;
224 // for (int i=0; i < size; ++i)
225 // cout<<"("<<in[2*i]<<","<<in[2*i+1]<<")"<<endl;
226  }
227 
228  void diff(T* data)
229  {
230  for (int_t i=0; i<2*size; ++i) {
231  data[i] -= in[i];
232  }
233  }
234 };
235 

Generated on Mon Feb 10 2014 for Generative Fast Fourier Transforms (GFFT) by DoxyGen 1.8.3.1