Commit 79d739e69d3d817317458905a124a3aa416628c4

Authored by Jürgen Knödlseder
1 parent a103d9db

Use pointers instead of std::vector in GFft class

include/GFft.hpp
@@ -80,7 +80,7 @@ public: @@ -80,7 +80,7 @@ public:
80 void clear(void); 80 void clear(void);
81 GFft* clone(void) const; 81 GFft* clone(void) const;
82 std::string classname(void) const; 82 std::string classname(void) const;
83 - int dim() const; 83 + int dim(void) const;
84 int size(void) const; 84 int size(void) const;
85 const std::vector<int>& shape(void) const; 85 const std::vector<int>& shape(void) const;
86 const std::vector<int>& strides(void) const; 86 const std::vector<int>& strides(void) const;
@@ -96,81 +96,89 @@ protected: @@ -96,81 +96,89 @@ protected:
96 void set_data(const GNdarray& array); 96 void set_data(const GNdarray& array);
97 97
98 // Low-level FFT methods 98 // Low-level FFT methods
99 - void transform(std::vector<std::complex<double> >& data,  
100 - const int& stride,  
101 - const int& n,  
102 - const GFftWavetable& wavetable,  
103 - const bool& forward = true);  
104 - void factor2(const std::vector<std::complex<double> >& in,  
105 - const int& istride,  
106 - std::vector<std::complex<double> >& out,  
107 - const int& ostride,  
108 - const GFftWavetable& wavetable,  
109 - const int& sign,  
110 - const int& product,  
111 - const int& n,  
112 - const int& index);  
113 - void factor3(const std::vector<std::complex<double> >& in,  
114 - const int& istride,  
115 - std::vector<std::complex<double> >& out,  
116 - const int& ostride,  
117 - const GFftWavetable& wavetable,  
118 - const int& sign,  
119 - const int& product,  
120 - const int& n,  
121 - const int& index);  
122 - void factor4(const std::vector<std::complex<double> >& in,  
123 - const int& istride,  
124 - std::vector<std::complex<double> >& out,  
125 - const int& ostride,  
126 - const GFftWavetable& wavetable,  
127 - const int& sign,  
128 - const int& product,  
129 - const int& n,  
130 - const int& index);  
131 - void factor5(const std::vector<std::complex<double> >& in,  
132 - const int& istride,  
133 - std::vector<std::complex<double> >& out,  
134 - const int& ostride,  
135 - const GFftWavetable& wavetable,  
136 - const int& sign,  
137 - const int& product,  
138 - const int& n,  
139 - const int& index);  
140 - void factor6(const std::vector<std::complex<double> >& in,  
141 - const int& istride,  
142 - std::vector<std::complex<double> >& out,  
143 - const int& ostride,  
144 - const GFftWavetable& wavetable,  
145 - const int& sign,  
146 - const int& product,  
147 - const int& n,  
148 - const int& index);  
149 - void factor7(const std::vector<std::complex<double> >& in,  
150 - const int& istride,  
151 - std::vector<std::complex<double> >& out,  
152 - const int& ostride,  
153 - const GFftWavetable& wavetable,  
154 - const int& sign,  
155 - const int& product,  
156 - const int& n,  
157 - const int& index);  
158 - void factorn(std::vector<std::complex<double> >& in,  
159 - const int& istride,  
160 - std::vector<std::complex<double> >& out,  
161 - const int& ostride,  
162 - const GFftWavetable& wavetable,  
163 - const int& sign,  
164 - const int& factor,  
165 - const int& product,  
166 - const int& n,  
167 - const int& index); 99 + void transform(std::complex<double>* data,
  100 + const int& stride,
  101 + const int& n,
  102 + const GFftWavetable& wavetable,
  103 + const bool& forward = true);
  104 + void factor2(const std::complex<double>* in,
  105 + const int& istride,
  106 + std::complex<double>* out,
  107 + const int& ostride,
  108 + const GFftWavetable& wavetable,
  109 + const int& sign,
  110 + const int& product,
  111 + const int& n,
  112 + const int& index);
  113 + void factor3(const std::complex<double>* in,
  114 + const int& istride,
  115 + std::complex<double>* out,
  116 + const int& ostride,
  117 + const GFftWavetable& wavetable,
  118 + const int& sign,
  119 + const int& product,
  120 + const int& n,
  121 + const int& index);
  122 + void factor4(const std::complex<double>* in,
  123 + const int& istride,
  124 + std::complex<double>* out,
  125 + const int& ostride,
  126 + const GFftWavetable& wavetable,
  127 + const int& sign,
  128 + const int& product,
  129 + const int& n,
  130 + const int& index);
  131 + void factor5(const std::complex<double>* in,
  132 + const int& istride,
  133 + std::complex<double>* out,
  134 + const int& ostride,
  135 + const GFftWavetable& wavetable,
  136 + const int& sign,
  137 + const int& product,
  138 + const int& n,
  139 + const int& index);
  140 + void factor6(const std::complex<double>* in,
  141 + const int& istride,
  142 + std::complex<double>* out,
  143 + const int& ostride,
  144 + const GFftWavetable& wavetable,
  145 + const int& sign,
  146 + const int& product,
  147 + const int& n,
  148 + const int& index);
  149 + void factor7(const std::complex<double>* in,
  150 + const int& istride,
  151 + std::complex<double>* out,
  152 + const int& ostride,
  153 + const GFftWavetable& wavetable,
  154 + const int& sign,
  155 + const int& product,
  156 + const int& n,
  157 + const int& index);
  158 + void factorn(std::complex<double>* in,
  159 + const int& istride,
  160 + std::complex<double>* out,
  161 + const int& ostride,
  162 + const GFftWavetable& wavetable,
  163 + const int& sign,
  164 + const int& factor,
  165 + const int& product,
  166 + const int& n,
  167 + const int& index);
  168 + std::vector<std::complex<double> > get_w(const GFftWavetable& wavetable,
  169 + const int& index,
  170 + const int& k,
  171 + const int& q,
  172 + const int& n,
  173 + const int& sign) const;
  174 + std::complex<double> timesi(const std::complex<double>& value) const;
168 175
169 // Protected members 176 // Protected members
170 - std::vector<int> m_shape; //!< Array dimensions  
171 - std::vector<int> m_strides; //!< Steps in each dimension  
172 - std::vector<std::complex<double> > m_data; //!< Array data  
173 - std::vector<GFftWavetable> m_wavetable; //!< Trigonometric coefficients 177 + int m_size; //!< Size of data array
  178 + std::complex<double>* m_data; //!< Pointer on array data
  179 + std::vector<int> m_shape; //!< Array dimensions
  180 + std::vector<int> m_strides; //!< Steps in each dimension
  181 + std::vector<GFftWavetable> m_wavetable; //!< Trigonometric coefficients
174 }; 182 };
175 183
176 184
@@ -189,28 +197,28 @@ std::string GFft::classname(void) const @@ -189,28 +197,28 @@ std::string GFft::classname(void) const
189 /***********************************************************************//** 197 /***********************************************************************//**
190 * @brief 1-dimensional FFT element access operator 198 * @brief 1-dimensional FFT element access operator
191 * 199 *
192 - * @param[in] ix Element index [0,...,shape(0)-1]. 200 + * @param[in] ix Element index [0,...,size()-1].
193 * @return Reference to FFT element. 201 * @return Reference to FFT element.
194 ***************************************************************************/ 202 ***************************************************************************/
195 inline 203 inline
196 std::complex<double>& GFft::operator()(const int& ix) 204 std::complex<double>& GFft::operator()(const int& ix)
197 { 205 {
198 // Return array element 206 // Return array element
199 - return m_data[ix]; 207 + return *(m_data + ix);
200 } 208 }
201 209
202 210
203 /***********************************************************************//** 211 /***********************************************************************//**
204 * @brief 1-dimensional FFT element access operator (const variant) 212 * @brief 1-dimensional FFT element access operator (const variant)
205 * 213 *
206 - * @param[in] ix Element index [0,...,shape(0)-1]. 214 + * @param[in] ix Element index [0,...,size()-1].
207 * @return Const reference to FFT element. 215 * @return Const reference to FFT element.
208 ***************************************************************************/ 216 ***************************************************************************/
209 inline 217 inline
210 const std::complex<double>& GFft::operator()(const int& ix) const 218 const std::complex<double>& GFft::operator()(const int& ix) const
211 { 219 {
212 // Return array element 220 // Return array element
213 - return m_data[ix]; 221 + return *(m_data + ix);
214 } 222 }
215 223
216 224
@@ -222,7 +230,7 @@ const std::complex&lt;double&gt;&amp; GFft::operator()(const int&amp; ix) const @@ -222,7 +230,7 @@ const std::complex&lt;double&gt;&amp; GFft::operator()(const int&amp; ix) const
222 * Returns the dimension of the Fast Fourier Transformation. 230 * Returns the dimension of the Fast Fourier Transformation.
223 ***************************************************************************/ 231 ***************************************************************************/
224 inline 232 inline
225 -int GFft::dim() const 233 +int GFft::dim(void) const
226 { 234 {
227 return m_shape.size(); 235 return m_shape.size();
228 } 236 }
@@ -236,9 +244,9 @@ int GFft::dim() const @@ -236,9 +244,9 @@ int GFft::dim() const
236 * Returns the number of elements in the array. 244 * Returns the number of elements in the array.
237 ***************************************************************************/ 245 ***************************************************************************/
238 inline 246 inline
239 -int GFft::size() const 247 +int GFft::size(void) const
240 { 248 {
241 - return m_data.size(); 249 + return m_size;
242 } 250 }
243 251
244 252
@@ -341,4 +349,20 @@ GFft operator/(const GFft&amp; a, const GFft&amp; b) @@ -341,4 +349,20 @@ GFft operator/(const GFft&amp; a, const GFft&amp; b)
341 return result; 349 return result;
342 } 350 }
343 351
  352 +
  353 +/***********************************************************************//**
  354 + * @brief Return complex value times i
  355 + *
  356 + * @param[in] value Complex value.
  357 + * @return Complex value times i.
  358 + *
  359 + * Returns complex value times i.
  360 + ***************************************************************************/
  361 +inline
  362 +std::complex<double> GFft::timesi(const std::complex<double>& value) const
  363 +{
  364 + std::complex<double> result(-value.imag(), value.real());
  365 + return result;
  366 +}
  367 +
344 #endif /* GFFT_HPP */ 368 #endif /* GFFT_HPP */
include/GNdarray.hpp
@@ -102,7 +102,7 @@ public: @@ -102,7 +102,7 @@ public:
102 void clear(void); 102 void clear(void);
103 GNdarray* clone(void) const; 103 GNdarray* clone(void) const;
104 std::string classname(void) const; 104 std::string classname(void) const;
105 - int dim() const; 105 + int dim(void) const;
106 int size(void) const; 106 int size(void) const;
107 const std::vector<int>& shape(void) const; 107 const std::vector<int>& shape(void) const;
108 const std::vector<int>& strides(void) const; 108 const std::vector<int>& strides(void) const;
@@ -270,7 +270,7 @@ const double&amp; GNdarray::operator()(const std::vector&lt;int&gt;&amp; i) const @@ -270,7 +270,7 @@ const double&amp; GNdarray::operator()(const std::vector&lt;int&gt;&amp; i) const
270 * Returns the dimension of the array. 270 * Returns the dimension of the array.
271 ***************************************************************************/ 271 ***************************************************************************/
272 inline 272 inline
273 -int GNdarray::dim() const 273 +int GNdarray::dim(void) const
274 { 274 {
275 return m_shape.size(); 275 return m_shape.size();
276 } 276 }
@@ -284,7 +284,7 @@ int GNdarray::dim() const @@ -284,7 +284,7 @@ int GNdarray::dim() const
284 * Returns the number of elements in the array. 284 * Returns the number of elements in the array.
285 ***************************************************************************/ 285 ***************************************************************************/
286 inline 286 inline
287 -int GNdarray::size() const 287 +int GNdarray::size(void) const
288 { 288 {
289 return m_data.size(); 289 return m_data.size();
290 } 290 }
src/numerics/GFft.cpp
@@ -229,8 +229,8 @@ GFft GFft::operator-(void) const @@ -229,8 +229,8 @@ GFft GFft::operator-(void) const
229 GFft fft = *this; 229 GFft fft = *this;
230 230
231 // Negate all elements 231 // Negate all elements
232 - for (int i = 0; i < m_data.size(); ++i) {  
233 - fft.m_data[i] = -fft.m_data[i]; 232 + for (int i = 0; i < fft.size(); ++i) {
  233 + fft(i) = -fft(i);
234 } 234 }
235 235
236 // Return FFT 236 // Return FFT
@@ -285,7 +285,24 @@ void GFft::forward(const GNdarray&amp; array) @@ -285,7 +285,24 @@ void GFft::forward(const GNdarray&amp; array)
285 set_data(array); 285 set_data(array);
286 286
287 // Continue only if there are elements in the data member 287 // Continue only if there are elements in the data member
288 - if (m_data.size() > 0) { 288 + if (m_size > 0) {
  289 +/*
  290 + // Loop over all dimensions of array
  291 + for (int d = 0; d < dim(); ++d) {
  292 +
  293 + // Loop over all dimensions of array
  294 + for (int i = 0; i < dim(); ++i) {
  295 +
  296 + // Skip
  297 + if (d == i) {
  298 + continue;
  299 + }
  300 +
  301 + // Loop over all
  302 + int n = shape()[d];
  303 + int stride = strides()[d];
  304 + int istart =
  305 +*/
289 306
290 // Perform FFT (is only correct for 1D for now) 307 // Perform FFT (is only correct for 1D for now)
291 transform(m_data, 1, m_shape[0], m_wavetable[0], true); 308 transform(m_data, 1, m_shape[0], m_wavetable[0], true);
@@ -313,7 +330,10 @@ GNdarray GFft::backward(void) const @@ -313,7 +330,10 @@ GNdarray GFft::backward(void) const
313 if (array.size() > 0) { 330 if (array.size() > 0) {
314 331
315 // Create copy of complex array 332 // Create copy of complex array
316 - std::vector<std::complex<double> > data = m_data; 333 + std::complex<double>* data = new std::complex<double>[array.size()];
  334 + for (int i = 0; i < array.size(); ++i) {
  335 + *(data+i) = *(m_data+i);
  336 + }
317 337
318 // Perform FFT (circumvent const correctness) 338 // Perform FFT (circumvent const correctness)
319 const_cast<GFft*>(this)->transform(data, 1, m_shape[0], m_wavetable[0], 339 const_cast<GFft*>(this)->transform(data, 1, m_shape[0], m_wavetable[0],
@@ -324,9 +344,12 @@ GNdarray GFft::backward(void) const @@ -324,9 +344,12 @@ GNdarray GFft::backward(void) const
324 344
325 // Extract N-dimensional array and normalise with 1/n 345 // Extract N-dimensional array and normalise with 1/n
326 for (int i = 0; i < array.size(); ++i) { 346 for (int i = 0; i < array.size(); ++i) {
327 - array(i) = data[i].real() * norm; 347 + array(i) = (data+i)->real() * norm;
328 } 348 }
329 349
  350 + // Delete copy of complex array
  351 + delete [] data;
  352 +
330 } // endif: there were elements in the array 353 } // endif: there were elements in the array
331 354
332 // Return N-dimensional array 355 // Return N-dimensional array
@@ -364,16 +387,16 @@ std::string GFft::print(const GChatter&amp; chatter) const @@ -364,16 +387,16 @@ std::string GFft::print(const GChatter&amp; chatter) const
364 } 387 }
365 result.append(")"); 388 result.append(")");
366 result.append("\n"+gammalib::parformat("Size")); 389 result.append("\n"+gammalib::parformat("Size"));
367 - result.append(gammalib::str(size())); 390 + result.append(gammalib::str(m_size));
368 391
369 // VERBOSE: Put all FFT elements in string 392 // VERBOSE: Put all FFT elements in string
370 if (chatter >= VERBOSE) { 393 if (chatter >= VERBOSE) {
371 result.append("\n"+gammalib::parformat("Elements")); 394 result.append("\n"+gammalib::parformat("Elements"));
372 - for (int i = 0; i < m_data.size(); ++i) { 395 + for (int i = 0; i < size(); ++i) {
373 if (i > 0) { 396 if (i > 0) {
374 result.append(","); 397 result.append(",");
375 } 398 }
376 - result.append(gammalib::str(m_data[i])); 399 + result.append(gammalib::str((*this)(i)));
377 } 400 }
378 result.append(")"); 401 result.append(")");
379 } 402 }
@@ -397,9 +420,10 @@ std::string GFft::print(const GChatter&amp; chatter) const @@ -397,9 +420,10 @@ std::string GFft::print(const GChatter&amp; chatter) const
397 void GFft::init_members(void) 420 void GFft::init_members(void)
398 { 421 {
399 // Initialise members 422 // Initialise members
  423 + m_size = 0;
  424 + m_data = NULL;
400 m_shape.clear(); 425 m_shape.clear();
401 m_strides.clear(); 426 m_strides.clear();
402 - m_data.clear();  
403 m_wavetable.clear(); 427 m_wavetable.clear();
404 428
405 // Return 429 // Return
@@ -415,11 +439,19 @@ void GFft::init_members(void) @@ -415,11 +439,19 @@ void GFft::init_members(void)
415 void GFft::copy_members(const GFft& fft) 439 void GFft::copy_members(const GFft& fft)
416 { 440 {
417 // Copy members 441 // Copy members
  442 + m_size = fft.m_size;
418 m_shape = fft.m_shape; 443 m_shape = fft.m_shape;
419 m_strides = fft.m_strides; 444 m_strides = fft.m_strides;
420 - m_data = fft.m_data;  
421 m_wavetable = fft.m_wavetable; 445 m_wavetable = fft.m_wavetable;
422 446
  447 + // Copy data
  448 + if (m_size > 0) {
  449 + m_data = new std::complex<double>[m_size];
  450 + for (int i = 0; i < m_size; ++i) {
  451 + *(m_data+i) = *(fft.m_data+i);
  452 + }
  453 + }
  454 +
423 // Return 455 // Return
424 return; 456 return;
425 } 457 }
@@ -430,6 +462,15 @@ void GFft::copy_members(const GFft&amp; fft) @@ -430,6 +462,15 @@ void GFft::copy_members(const GFft&amp; fft)
430 ***************************************************************************/ 462 ***************************************************************************/
431 void GFft::free_members(void) 463 void GFft::free_members(void)
432 { 464 {
  465 + // Delete data
  466 + if (m_data != NULL) {
  467 + delete [] m_data;
  468 + }
  469 +
  470 + // Reset size and pointer
  471 + m_size = 0;
  472 + m_data = NULL;
  473 +
433 // Return 474 // Return
434 return; 475 return;
435 } 476 }
@@ -443,21 +484,21 @@ void GFft::free_members(void) @@ -443,21 +484,21 @@ void GFft::free_members(void)
443 void GFft::set_data(const GNdarray& array) 484 void GFft::set_data(const GNdarray& array)
444 { 485 {
445 // Clear information 486 // Clear information
446 - m_shape.clear();  
447 - m_strides.clear();  
448 - m_data.clear();  
449 - m_wavetable.clear(); 487 + free_members();
  488 + init_members();
450 489
451 // Continue only if there are elements in the array 490 // Continue only if there are elements in the array
452 if (array.size() > 0) { 491 if (array.size() > 0) {
453 492
  493 + // Set size of array
  494 + m_size = array.size();
  495 +
454 // Allocate data and initialise data to zero 496 // Allocate data and initialise data to zero
455 - std::complex<double> zero(0.0, 0.0);  
456 - m_data.assign(array.size(), zero); 497 + m_data = new std::complex<double>[m_size];
457 498
458 // Set real part of data from n-dimensional array 499 // Set real part of data from n-dimensional array
459 - for (int i = 0; i < array.size(); ++i) {  
460 - m_data[i] = std::complex<double>(array(i), 0.0); 500 + for (int i = 0; i < m_size; ++i) {
  501 + *(m_data+i) = std::complex<double>(array(i), 0.0);
461 } 502 }
462 503
463 // Save shape 504 // Save shape
@@ -486,21 +527,24 @@ void GFft::set_data(const GNdarray&amp; array) @@ -486,21 +527,24 @@ void GFft::set_data(const GNdarray&amp; array)
486 /***********************************************************************//** 527 /***********************************************************************//**
487 * @brief Perform Fast Fourier Transform 528 * @brief Perform Fast Fourier Transform
488 * 529 *
489 - * @param[in] data FFT array.  
490 - * @param[in] stride Step size when traversing FFT array in one dimension.  
491 - * @param[in] n Number of elements in the dimension. 530 + * @param[in] data Pointer to complex array to be transformed.
  531 + * @param[in] stride Step size when traversing complex array.
  532 + * @param[in] n Number of elements in complex array.
492 * @param[in] wavetable Trigonometric coefficients. 533 * @param[in] wavetable Trigonometric coefficients.
493 * @param[in] forward Forward transform if true, otherwise backward transform. 534 * @param[in] forward Forward transform if true, otherwise backward transform.
494 ***************************************************************************/ 535 ***************************************************************************/
495 -void GFft::transform(std::vector<std::complex<double> >& data,  
496 - const int& stride,  
497 - const int& n,  
498 - const GFftWavetable& wavetable,  
499 - const bool& forward) 536 +void GFft::transform(std::complex<double>* data,
  537 + const int& stride,
  538 + const int& n,
  539 + const GFftWavetable& wavetable,
  540 + const bool& forward)
500 { 541 {
501 - // Allocate scratch space  
502 - std::complex<double> zero(0.0, 0.0);  
503 - std::vector<std::complex<double> > scratch(n, zero); 542 + // Allocate scratch space and initialize to zero
  543 + std::complex<double>* scratch = new std::complex<double>[n];
  544 + std::complex<double> zero(0.0, 0.0);
  545 + for (int i = 0; i < n; ++i) {
  546 + *(scratch+i) = zero;
  547 + }
504 548
505 // Initialise transformation state 549 // Initialise transformation state
506 int state = 0; 550 int state = 0;
@@ -525,46 +569,46 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data, @@ -525,46 +569,46 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data,
525 int q = n / product; 569 int q = n / product;
526 570
527 // Set state dependent stuff 571 // Set state dependent stuff
528 - std::vector<std::complex<double> >* in = &data;  
529 - std::vector<std::complex<double> >* out = &scratch;  
530 - int istride;  
531 - int ostride; 572 + std::complex<double>* in;
  573 + std::complex<double>* out;
  574 + int istride;
  575 + int ostride;
532 if (state == 0) { 576 if (state == 0) {
533 - in = &data; 577 + in = data;
534 istride = stride; 578 istride = stride;
535 - out = &scratch; 579 + out = scratch;
536 ostride = 1; 580 ostride = 1;
537 state = 1; 581 state = 1;
538 } 582 }
539 else { 583 else {
540 - in = &scratch; 584 + in = scratch;
541 istride = 1; 585 istride = 1;
542 - out = &data; 586 + out = data;
543 ostride = stride; 587 ostride = stride;
544 state = 0; 588 state = 0;
545 } 589 }
546 590
547 // Call factor dependent method 591 // Call factor dependent method
548 if (factor == 2) { 592 if (factor == 2) {
549 - factor2(*in, istride, *out, ostride, wavetable, sign, product, n, index); 593 + factor2(in, istride, out, ostride, wavetable, sign, product, n, index);
550 } 594 }
551 else if (factor == 3) { 595 else if (factor == 3) {
552 - factor3(*in, istride, *out, ostride, wavetable, sign, product, n, index); 596 + factor3(in, istride, out, ostride, wavetable, sign, product, n, index);
553 } 597 }
554 else if (factor == 4) { 598 else if (factor == 4) {
555 - factor4(*in, istride, *out, ostride, wavetable, sign, product, n, index); 599 + factor4(in, istride, out, ostride, wavetable, sign, product, n, index);
556 } 600 }
557 else if (factor == 5) { 601 else if (factor == 5) {
558 - factor5(*in, istride, *out, ostride, wavetable, sign, product, n, index); 602 + factor5(in, istride, out, ostride, wavetable, sign, product, n, index);
559 } 603 }
560 else if (factor == 6) { 604 else if (factor == 6) {
561 - factor6(*in, istride, *out, ostride, wavetable, sign, product, n, index); 605 + factor6(in, istride, out, ostride, wavetable, sign, product, n, index);
562 } 606 }
563 else if (factor == 7) { 607 else if (factor == 7) {
564 - factor7(*in, istride, *out, ostride, wavetable, sign, product, n, index); 608 + factor7(in, istride, out, ostride, wavetable, sign, product, n, index);
565 } 609 }
566 else { 610 else {
567 - factorn(*in, istride, *out, ostride, wavetable, sign, factor, product, n, index); 611 + factorn(in, istride, out, ostride, wavetable, sign, factor, product, n, index);
568 } 612 }
569 613
570 } // endfor: looped over all factors 614 } // endfor: looped over all factors
@@ -574,10 +618,13 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data, @@ -574,10 +618,13 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data,
574 // the data array 618 // the data array
575 if (state == 1) { 619 if (state == 1) {
576 for (int i = 0; i < n; ++i) { 620 for (int i = 0; i < n; ++i) {
577 - data[stride*i] = scratch[i]; 621 + *(data+stride*i) = *(scratch+i);
578 } 622 }
579 } 623 }
580 624
  625 + // Free scratch space
  626 + delete [] scratch;
  627 +
581 // Return 628 // Return
582 return; 629 return;
583 } 630 }
@@ -586,9 +633,9 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data, @@ -586,9 +633,9 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data,
586 /***********************************************************************//** 633 /***********************************************************************//**
587 * @brief Compute FFT for factor 2 634 * @brief Compute FFT for factor 2
588 * 635 *
589 - * @param[in] in Input array. 636 + * @param[in] in Pointer to input array.
590 * @param[in] istride Step size when traversing input array. 637 * @param[in] istride Step size when traversing input array.
591 - * @param[in] out Output array. 638 + * @param[in] out Pointer to output array.
592 * @param[in] ostride Step size when traversing output array. 639 * @param[in] ostride Step size when traversing output array.
593 * @param[in] wavetable Trigonometric coefficients. 640 * @param[in] wavetable Trigonometric coefficients.
594 * @param[in] sign Forward (-1) or backward (+1). 641 * @param[in] sign Forward (-1) or backward (+1).
@@ -596,15 +643,15 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data, @@ -596,15 +643,15 @@ void GFft::transform(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; data,
596 * @param[in] n Logical array length. 643 * @param[in] n Logical array length.
597 * @param[in] index Start index of trigonometric coefficients. 644 * @param[in] index Start index of trigonometric coefficients.
598 ***************************************************************************/ 645 ***************************************************************************/
599 -void GFft::factor2(const std::vector<std::complex<double> >& in,  
600 - const int& istride,  
601 - std::vector<std::complex<double> >& out,  
602 - const int& ostride,  
603 - const GFftWavetable& wavetable,  
604 - const int& sign,  
605 - const int& product,  
606 - const int& n,  
607 - const int& index) 646 +void GFft::factor2(const std::complex<double>* in,
  647 + const int& istride,
  648 + std::complex<double>* out,
  649 + const int& ostride,
  650 + const GFftWavetable& wavetable,
  651 + const int& sign,
  652 + const int& product,
  653 + const int& n,
  654 + const int& index)
608 { 655 {
609 // Compute ... 656 // Compute ...
610 const int factor = 2; 657 const int factor = 2;
@@ -616,63 +663,23 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -616,63 +663,23 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
616 // Loop over ... 663 // Loop over ...
617 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 664 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
618 665
619 - // Allocate variables  
620 - double w1_real, w1_imag;  
621 -  
622 - // Set trigonometric coefficients for k=0 since they are not stored  
623 - // in the wavetable object  
624 - if (k == 0) {  
625 - w1_real = 1.0;  
626 - w1_imag = 0.0;  
627 - }  
628 - else {  
629 -  
630 - // Compute indices  
631 - int twiddle = index + k - 1;  
632 -  
633 - // Set trigonometric coefficients for forward transform  
634 - if (sign == -1) {  
635 - w1_real = wavetable[twiddle].real();  
636 - w1_imag = wavetable[twiddle].imag();  
637 - }  
638 -  
639 - // ... otherwise set trigonometric coefficients for backward  
640 - // tranform: w -> conjugate(w)  
641 - else {  
642 - w1_real = wavetable[twiddle].real();  
643 - w1_imag = -wavetable[twiddle].imag();  
644 - }  
645 -  
646 - } // endelse: k != 0 666 + // Extract coefficients from wavetable
  667 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 1, sign);
647 668
648 - // Loop over ... 669 + // Compute x = W(2) z
649 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 670 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
650 671
651 - const double z0_real = in[istride*i].real();  
652 - const double z0_imag = in[istride*i].imag();  
653 - const double z1_real = in[istride*(i+m)].real();  
654 - const double z1_imag = in[istride*(i+m)].imag();  
655 -  
656 - // compute x = W(2) z  
657 -  
658 - // x0 = z0 + z1  
659 - const double x0_real = z0_real + z1_real;  
660 - const double x0_imag = z0_imag + z1_imag; 672 + // Get z
  673 + const std::complex<double> z0 = *(in+istride*i);
  674 + const std::complex<double> z1 = *(in+istride*(i+m));
661 675
662 - // x1 = z0 - z1  
663 - const double x1_real = z0_real - z1_real;  
664 - const double x1_imag = z0_imag - z1_imag; 676 + // Compute x
  677 + const std::complex<double> x0 = z0 + z1;
  678 + const std::complex<double> x1 = z0 - z1;
665 679
666 - // out0 = 1 * x0  
667 - //out[ostride*j].real(x0_real);  
668 - //out[ostride*j].imag(x0_imag);  
669 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
670 -  
671 - // out1 = w1 * x1  
672 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
673 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
674 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
675 - w1_real * x1_imag + w1_imag * x1_real); 680 + // out = w * x
  681 + *(out+ostride*j) = x0;
  682 + *(out+ostride*(j+p_1)) = w[0] * x1;
676 683
677 } // endfor: k1 684 } // endfor: k1
678 685
@@ -686,9 +693,9 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -686,9 +693,9 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
686 /***********************************************************************//** 693 /***********************************************************************//**
687 * @brief Compute FFT for factor 3 694 * @brief Compute FFT for factor 3
688 * 695 *
689 - * @param[in] in Input array. 696 + * @param[in] in Pointer to input array.
690 * @param[in] istride Step size when traversing input array. 697 * @param[in] istride Step size when traversing input array.
691 - * @param[in] out Output array. 698 + * @param[in] out Pointer to output array.
692 * @param[in] ostride Step size when traversing output array. 699 * @param[in] ostride Step size when traversing output array.
693 * @param[in] wavetable Trigonometric coefficients. 700 * @param[in] wavetable Trigonometric coefficients.
694 * @param[in] sign Forward (-1) or backward (+1). 701 * @param[in] sign Forward (-1) or backward (+1).
@@ -696,15 +703,15 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -696,15 +703,15 @@ void GFft::factor2(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
696 * @param[in] n Logical array length. 703 * @param[in] n Logical array length.
697 * @param[in] index Start index of trigonometric coefficients. 704 * @param[in] index Start index of trigonometric coefficients.
698 ***************************************************************************/ 705 ***************************************************************************/
699 -void GFft::factor3(const std::vector<std::complex<double> >& in,  
700 - const int& istride,  
701 - std::vector<std::complex<double> >& out,  
702 - const int& ostride,  
703 - const GFftWavetable& wavetable,  
704 - const int& sign,  
705 - const int& product,  
706 - const int& n,  
707 - const int& index) 706 +void GFft::factor3(const std::complex<double>* in,
  707 + const int& istride,
  708 + std::complex<double>* out,
  709 + const int& ostride,
  710 + const GFftWavetable& wavetable,
  711 + const int& sign,
  712 + const int& product,
  713 + const int& n,
  714 + const int& index)
708 { 715 {
709 // Compute ... 716 // Compute ...
710 const int factor = 3; 717 const int factor = 3;
@@ -719,95 +726,32 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -719,95 +726,32 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
719 726
720 // Loop over ... 727 // Loop over ...
721 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 728 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
722 -  
723 - // Allocate variables  
724 - double w1_real, w1_imag, w2_real, w2_imag;  
725 -  
726 - // Set trigonometric coefficients for k=0 since they are not stored  
727 - // in the wavetable object  
728 - if (k == 0) {  
729 - w1_real = 1.0;  
730 - w1_imag = 0.0;  
731 - w2_real = 1.0;  
732 - w2_imag = 0.0;  
733 - }  
734 - else {  
735 -  
736 - // Compute indices  
737 - int twiddle1 = index + k - 1;  
738 - int twiddle2 = twiddle1 + q;  
739 -  
740 - // Set trigonometric coefficients for forward transform  
741 - if (sign == -1) {  
742 - w1_real = wavetable[twiddle1].real();  
743 - w1_imag = wavetable[twiddle1].imag();  
744 - w2_real = wavetable[twiddle2].real();  
745 - w2_imag = wavetable[twiddle2].imag();  
746 - }  
747 729
748 - // ... otherwise set trigonometric coefficients for backward  
749 - // tranform: w -> conjugate(w)  
750 - else {  
751 - w1_real = wavetable[twiddle1].real();  
752 - w1_imag = -wavetable[twiddle1].imag();  
753 - w2_real = wavetable[twiddle2].real();  
754 - w2_imag = -wavetable[twiddle2].imag();  
755 - }  
756 - } // endelse: k != 0 730 + // Extract coefficients from wavetable
  731 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 2, sign);
757 732
758 - // ... 733 + // Compute x = W(3) z
759 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 734 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
760 735
761 // Get z 736 // Get z
762 - const double z0_real = in[istride*i].real();  
763 - const double z0_imag = in[istride*i].imag();  
764 - const double z1_real = in[istride*(i+m)].real();  
765 - const double z1_imag = in[istride*(i+m)].imag();  
766 - const double z2_real = in[istride*(i+2*m)].real();  
767 - const double z2_imag = in[istride*(i+2*m)].imag();  
768 -  
769 - // compute x = W(3) z  
770 -  
771 - // t1 = z1 + z2  
772 - const double t1_real = z1_real + z2_real;  
773 - const double t1_imag = z1_imag + z2_imag;  
774 -  
775 - // t2 = z0 - t1/2  
776 - const double t2_real = z0_real - t1_real / 2.0;  
777 - const double t2_imag = z0_imag - t1_imag / 2.0;  
778 -  
779 - // t3 = (+/-) sin(pi/3)*(z1 - z2)  
780 - const double t3_real = ((int) sign) * tau * (z1_real - z2_real);  
781 - const double t3_imag = ((int) sign) * tau * (z1_imag - z2_imag);  
782 -  
783 - // x0 = z0 + t1  
784 - const double x0_real = z0_real + t1_real;  
785 - const double x0_imag = z0_imag + t1_imag;  
786 -  
787 - // x1 = t2 + i t3  
788 - const double x1_real = t2_real - t3_imag;  
789 - const double x1_imag = t2_imag + t3_real;  
790 -  
791 - // x2 = t2 - i t3  
792 - const double x2_real = t2_real + t3_imag;  
793 - const double x2_imag = t2_imag - t3_real;  
794 -  
795 - // out0 = 1 * x0  
796 - //out[ostride*j].real(x0_real);  
797 - //out[ostride*j].imag(x0_imag);  
798 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
799 -  
800 - // out1 = w1 * x1  
801 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
802 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
803 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
804 - w1_real * x1_imag + w1_imag * x1_real);  
805 -  
806 - // out2 = w2 * x2  
807 - //out[ostride*(j+2*p_1)].real(w2_real * x2_real - w2_imag * x2_imag);  
808 - //out[ostride*(j+2*p_1)].imag(w2_real * x2_imag + w2_imag * x2_real);  
809 - out[ostride*(j+2*p_1)] = std::complex<double>(w2_real * x2_real - w2_imag * x2_imag,  
810 - w2_real * x2_imag + w2_imag * x2_real); 737 + const std::complex<double> z0 = *(in+istride*i);
  738 + const std::complex<double> z1 = *(in+istride*(i+m));
  739 + const std::complex<double> z2 = *(in+istride*(i+2*m));
  740 +
  741 + // Compute t
  742 + const std::complex<double> t1 = z1 + z2;
  743 + const std::complex<double> t2 = z0 - t1/2.0;
  744 + const std::complex<double> t3 = double((int)sign) * tau * (z1 - z2);
  745 +
  746 + // Compute x
  747 + const std::complex<double> x0 = z0 + t1;
  748 + const std::complex<double> x1 = t2 + timesi(t3);
  749 + const std::complex<double> x2 = t2 - timesi(t3);
  750 +
  751 + // out = w * x
  752 + *(out+ostride*j) = x0;
  753 + *(out+ostride*(j+p_1)) = w[0] * x1;
  754 + *(out+ostride*(j+2*p_1)) = w[1] * x2;
811 755
812 } // endfor: k1 756 } // endfor: k1
813 757
@@ -821,9 +765,9 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -821,9 +765,9 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
821 /***********************************************************************//** 765 /***********************************************************************//**
822 * @brief Compute FFT for factor 4 766 * @brief Compute FFT for factor 4
823 * 767 *
824 - * @param[in] in Input array. 768 + * @param[in] in Pointer to input array.
825 * @param[in] istride Step size when traversing input array. 769 * @param[in] istride Step size when traversing input array.
826 - * @param[in] out Output array. 770 + * @param[in] out Pointer to output array.
827 * @param[in] ostride Step size when traversing output array. 771 * @param[in] ostride Step size when traversing output array.
828 * @param[in] wavetable Trigonometric coefficients. 772 * @param[in] wavetable Trigonometric coefficients.
829 * @param[in] sign Forward (-1) or backward (+1). 773 * @param[in] sign Forward (-1) or backward (+1).
@@ -831,15 +775,15 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -831,15 +775,15 @@ void GFft::factor3(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
831 * @param[in] n Logical array length. 775 * @param[in] n Logical array length.
832 * @param[in] index Start index of trigonometric coefficients. 776 * @param[in] index Start index of trigonometric coefficients.
833 ***************************************************************************/ 777 ***************************************************************************/
834 -void GFft::factor4(const std::vector<std::complex<double> >& in,  
835 - const int& istride,  
836 - std::vector<std::complex<double> >& out,  
837 - const int& ostride,  
838 - const GFftWavetable& wavetable,  
839 - const int& sign,  
840 - const int& product,  
841 - const int& n,  
842 - const int& index) 778 +void GFft::factor4(const std::complex<double>* in,
  779 + const int& istride,
  780 + std::complex<double>* out,
  781 + const int& ostride,
  782 + const GFftWavetable& wavetable,
  783 + const int& sign,
  784 + const int& product,
  785 + const int& n,
  786 + const int& index)
843 { 787 {
844 // Compute ... 788 // Compute ...
845 const int factor = 4; 789 const int factor = 4;
@@ -850,121 +794,36 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -850,121 +794,36 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
850 794
851 // Loop over ... 795 // Loop over ...
852 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 796 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
853 -  
854 - // Allocate w  
855 - double w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag;  
856 -  
857 - // Set trigonometric coefficients for k=0 since they are not stored  
858 - // in the wavetable object  
859 - if (k == 0) {  
860 - w1_real = 1.0;  
861 - w1_imag = 0.0;  
862 - w2_real = 1.0;  
863 - w2_imag = 0.0;  
864 - w3_real = 1.0;  
865 - w3_imag = 0.0;  
866 - }  
867 - else  
868 - {  
869 -  
870 - // Compute indices  
871 - int twiddle1 = index + k - 1;  
872 - int twiddle2 = twiddle1 + q;  
873 - int twiddle3 = twiddle2 + q;  
874 -  
875 - // Set trigonometric coefficients for forward transform  
876 - if (sign == -1) {  
877 - w1_real = wavetable[twiddle1].real();  
878 - w1_imag = wavetable[twiddle1].imag();  
879 - w2_real = wavetable[twiddle2].real();  
880 - w2_imag = wavetable[twiddle2].imag();  
881 - w3_real = wavetable[twiddle3].real();  
882 - w3_imag = wavetable[twiddle3].imag();  
883 - }  
884 -  
885 - // ... otherwise set trigonometric coefficients for backward  
886 - // tranform: w -> conjugate(w)  
887 - else {  
888 - w1_real = wavetable[twiddle1].real();  
889 - w1_imag = -wavetable[twiddle1].imag();  
890 - w2_real = wavetable[twiddle2].real();  
891 - w2_imag = -wavetable[twiddle2].imag();  
892 - w3_real = wavetable[twiddle3].real();  
893 - w3_imag = -wavetable[twiddle3].imag();  
894 - }  
895 797
896 - } // endelse: k != 0 798 + // Extract coefficients from wavetable
  799 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 3, sign);
897 800
898 - // Loop over ... 801 + // Compute x = W(4) z
899 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 802 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
900 803
901 -  
902 // Get z 804 // Get z
903 - const double z0_real = in[istride*i].real();  
904 - const double z0_imag = in[istride*i].imag();  
905 - const double z1_real = in[istride*(i+m)].real();  
906 - const double z1_imag = in[istride*(i+m)].imag();  
907 - const double z2_real = in[istride*(i+2*m)].real();  
908 - const double z2_imag = in[istride*(i+2*m)].imag();  
909 - const double z3_real = in[istride*(i+3*m)].real();  
910 - const double z3_imag = in[istride*(i+3*m)].imag();  
911 -  
912 - // compute x = W(4) z 805 + const std::complex<double> z0 = *(in+istride*i);
  806 + const std::complex<double> z1 = *(in+istride*(i+m));
  807 + const std::complex<double> z2 = *(in+istride*(i+2*m));
  808 + const std::complex<double> z3 = *(in+istride*(i+3*m));
913 809
914 - // t1 = z0 + z2  
915 - const double t1_real = z0_real + z2_real;  
916 - const double t1_imag = z0_imag + z2_imag;  
917 -  
918 - // t2 = z1 + z3  
919 - const double t2_real = z1_real + z3_real;  
920 - const double t2_imag = z1_imag + z3_imag;  
921 -  
922 - // t3 = z0 - z2  
923 - const double t3_real = z0_real - z2_real;  
924 - const double t3_imag = z0_imag - z2_imag;  
925 -  
926 - // t4 = (+/-) (z1 - z3)  
927 - const double t4_real = ((int) sign) * (z1_real - z3_real);  
928 - const double t4_imag = ((int) sign) * (z1_imag - z3_imag);  
929 -  
930 - // x0 = t1 + t2  
931 - const double x0_real = t1_real + t2_real;  
932 - const double x0_imag = t1_imag + t2_imag;  
933 -  
934 - // x1 = t3 + i t4  
935 - const double x1_real = t3_real - t4_imag;  
936 - const double x1_imag = t3_imag + t4_real;  
937 -  
938 - // x2 = t1 - t2  
939 - const double x2_real = t1_real - t2_real;  
940 - const double x2_imag = t1_imag - t2_imag;  
941 -  
942 - // x3 = t3 - i t4  
943 - const double x3_real = t3_real + t4_imag;  
944 - const double x3_imag = t3_imag - t4_real;  
945 -  
946 - // out0 = 1 * x0  
947 - //out[ostride*j].real(x0_real);  
948 - //out[ostride*j].imag(x0_imag);  
949 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
950 -  
951 - // out1 = w1 * x1  
952 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
953 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
954 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
955 - w1_real * x1_imag + w1_imag * x1_real);  
956 -  
957 - // out2 = w2 * x2  
958 - //out[ostride*(j+2*p_1)].real(w2_real * x2_real - w2_imag * x2_imag);  
959 - //out[ostride*(j+2*p_1)].imag(w2_real * x2_imag + w2_imag * x2_real);  
960 - out[ostride*(j+2*p_1)] = std::complex<double>(w2_real * x2_real - w2_imag * x2_imag,  
961 - w2_real * x2_imag + w2_imag * x2_real);  
962 -  
963 - // out3 = w3 * x3  
964 - //out[ostride*(j+3*p_1)].real(w3_real * x3_real - w3_imag * x3_imag);  
965 - //out[ostride*(j+3*p_1)].imag(w3_real * x3_imag + w3_imag * x3_real);  
966 - out[ostride*(j+3*p_1)] = std::complex<double>(w3_real * x3_real - w3_imag * x3_imag,  
967 - w3_real * x3_imag + w3_imag * x3_real); 810 + // Compute t
  811 + const std::complex<double> t1 = z0 + z2;
  812 + const std::complex<double> t2 = z1 + z3;
  813 + const std::complex<double> t3 = z0 - z2;
  814 + const std::complex<double> t4 = double((int)sign) * (z1 - z3);
  815 +
  816 + // Compute x
  817 + const std::complex<double> x0 = t1 + t2;
  818 + const std::complex<double> x1 = t3 + timesi(t4);
  819 + const std::complex<double> x2 = t1 - t2;
  820 + const std::complex<double> x3 = t3 - timesi(t4);
  821 +
  822 + // out = w * x
  823 + *(out+ostride*j) = x0;
  824 + *(out+ostride*(j+p_1)) = w[0] * x1;
  825 + *(out+ostride*(j+2*p_1)) = w[1] * x2;
  826 + *(out+ostride*(j+3*p_1)) = w[2] * x3;
968 827
969 } // endfor: k1 828 } // endfor: k1
970 829
@@ -978,9 +837,9 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -978,9 +837,9 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
978 /***********************************************************************//** 837 /***********************************************************************//**
979 * @brief Compute FFT for factor 5 838 * @brief Compute FFT for factor 5
980 * 839 *
981 - * @param[in] in Input array. 840 + * @param[in] in Pointer to input array.
982 * @param[in] istride Step size when traversing input array. 841 * @param[in] istride Step size when traversing input array.
983 - * @param[in] out Output array. 842 + * @param[in] out Pointer to output array.
984 * @param[in] ostride Step size when traversing output array. 843 * @param[in] ostride Step size when traversing output array.
985 * @param[in] wavetable Trigonometric coefficients. 844 * @param[in] wavetable Trigonometric coefficients.
986 * @param[in] sign Forward (-1) or backward (+1). 845 * @param[in] sign Forward (-1) or backward (+1).
@@ -988,15 +847,15 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -988,15 +847,15 @@ void GFft::factor4(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
988 * @param[in] n Logical array length. 847 * @param[in] n Logical array length.
989 * @param[in] index Start index of trigonometric coefficients. 848 * @param[in] index Start index of trigonometric coefficients.
990 ***************************************************************************/ 849 ***************************************************************************/
991 -void GFft::factor5(const std::vector<std::complex<double> >& in,  
992 - const int& istride,  
993 - std::vector<std::complex<double> >& out,  
994 - const int& ostride,  
995 - const GFftWavetable& wavetable,  
996 - const int& sign,  
997 - const int& product,  
998 - const int& n,  
999 - const int& index) 850 +void GFft::factor5(const std::complex<double>* in,
  851 + const int& istride,
  852 + std::complex<double>* out,
  853 + const int& ostride,
  854 + const GFftWavetable& wavetable,
  855 + const int& sign,
  856 + const int& product,
  857 + const int& n,
  858 + const int& index)
1000 { 859 {
1001 // Compute ... 860 // Compute ...
1002 const int factor = 5; 861 const int factor = 5;
@@ -1013,170 +872,47 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1013,170 +872,47 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1013 // Loop over ... 872 // Loop over ...
1014 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 873 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1015 874
1016 - // Allocate w  
1017 - double w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real,  
1018 - w4_imag;  
1019 -  
1020 - // Set trigonometric coefficients for k=0 since they are not stored  
1021 - // in the wavetable object  
1022 - if (k == 0) {  
1023 - w1_real = 1.0;  
1024 - w1_imag = 0.0;  
1025 - w2_real = 1.0;  
1026 - w2_imag = 0.0;  
1027 - w3_real = 1.0;  
1028 - w3_imag = 0.0;  
1029 - w4_real = 1.0;  
1030 - w4_imag = 0.0;  
1031 - }  
1032 - else {  
1033 -  
1034 - // Compute indices  
1035 - int twiddle1 = index + k - 1;  
1036 - int twiddle2 = twiddle1 + q;  
1037 - int twiddle3 = twiddle2 + q;  
1038 - int twiddle4 = twiddle3 + q;  
1039 -  
1040 - // Set trigonometric coefficients for forward transform  
1041 - if (sign == -1) {  
1042 - w1_real = wavetable[twiddle1].real();  
1043 - w1_imag = wavetable[twiddle1].imag();  
1044 - w2_real = wavetable[twiddle2].real();  
1045 - w2_imag = wavetable[twiddle2].imag();  
1046 - w3_real = wavetable[twiddle3].real();  
1047 - w3_imag = wavetable[twiddle3].imag();  
1048 - w4_real = wavetable[twiddle4].real();  
1049 - w4_imag = wavetable[twiddle4].imag();  
1050 - }  
1051 -  
1052 - // ... otherwise set trigonometric coefficients for backward  
1053 - // tranform: w -> conjugate(w)  
1054 - else {  
1055 - w1_real = wavetable[twiddle1].real();  
1056 - w1_imag = -wavetable[twiddle1].imag();  
1057 - w2_real = wavetable[twiddle2].real();  
1058 - w2_imag = -wavetable[twiddle2].imag();  
1059 - w3_real = wavetable[twiddle3].real();  
1060 - w3_imag = -wavetable[twiddle3].imag();  
1061 - w4_real = wavetable[twiddle4].real();  
1062 - w4_imag = -wavetable[twiddle4].imag();  
1063 - } 875 + // Extract coefficients from wavetable
  876 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 4, sign);
1064 877
1065 - } // endelse: k != 0  
1066 -  
1067 - // Loop over ... 878 + // Compute x = W(5) z
1068 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 879 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1069 880
1070 // Get z 881 // Get z
1071 - const double z0_real = in[istride*i].real();  
1072 - const double z0_imag = in[istride*i].imag();  
1073 - const double z1_real = in[istride*(i+m)].real();  
1074 - const double z1_imag = in[istride*(i+m)].imag();  
1075 - const double z2_real = in[istride*(i+2*m)].real();  
1076 - const double z2_imag = in[istride*(i+2*m)].imag();  
1077 - const double z3_real = in[istride*(i+3*m)].real();  
1078 - const double z3_imag = in[istride*(i+3*m)].imag();  
1079 - const double z4_real = in[istride*(i+4*m)].real();  
1080 - const double z4_imag = in[istride*(i+4*m)].imag();  
1081 -  
1082 - // compute x = W(5) z  
1083 -  
1084 - // t1 = z1 + z4  
1085 - const double t1_real = z1_real + z4_real;  
1086 - const double t1_imag = z1_imag + z4_imag;  
1087 -  
1088 - // t2 = z2 + z3  
1089 - const double t2_real = z2_real + z3_real;  
1090 - const double t2_imag = z2_imag + z3_imag;  
1091 -  
1092 - // t3 = z1 - z4  
1093 - const double t3_real = z1_real - z4_real;  
1094 - const double t3_imag = z1_imag - z4_imag;  
1095 -  
1096 - // t4 = z2 - z3  
1097 - const double t4_real = z2_real - z3_real;  
1098 - const double t4_imag = z2_imag - z3_imag;  
1099 -  
1100 - // t5 = t1 + t2  
1101 - const double t5_real = t1_real + t2_real;  
1102 - const double t5_imag = t1_imag + t2_imag;  
1103 -  
1104 - // t6 = (sqrt(5)/4)(t1 - t2)  
1105 - const double t6_real = (tau) * (t1_real - t2_real);  
1106 - const double t6_imag = (tau) * (t1_imag - t2_imag);  
1107 -  
1108 - // t7 = z0 - ((t5)/4)  
1109 - const double t7_real = z0_real - t5_real / 4.0;  
1110 - const double t7_imag = z0_imag - t5_imag / 4.0;  
1111 -  
1112 - // t8 = t7 + t6  
1113 - const double t8_real = t7_real + t6_real;  
1114 - const double t8_imag = t7_imag + t6_imag;  
1115 -  
1116 - // t9 = t7 - t6  
1117 - const double t9_real = t7_real - t6_real;  
1118 - const double t9_imag = t7_imag - t6_imag;  
1119 -  
1120 - // t10 = sin(2 pi/5) t3 + sin(2 pi/10) t4 */  
1121 - const double t10_real = ((int) sign) * (sin_2pi_by_5 * t3_real +  
1122 - sin_2pi_by_10 * t4_real);  
1123 - const double t10_imag = ((int) sign) * (sin_2pi_by_5 * t3_imag +  
1124 - sin_2pi_by_10 * t4_imag);  
1125 -  
1126 - // t11 = sin(2 pi/10) t3 - sin(2 pi/5) t4  
1127 - const double t11_real = ((int) sign) * (sin_2pi_by_10 * t3_real -  
1128 - sin_2pi_by_5 * t4_real);  
1129 - const double t11_imag = ((int) sign) * (sin_2pi_by_10 * t3_imag -  
1130 - sin_2pi_by_5 * t4_imag);  
1131 -  
1132 - // x0 = z0 + t5  
1133 - const double x0_real = z0_real + t5_real;  
1134 - const double x0_imag = z0_imag + t5_imag;  
1135 -  
1136 - // x1 = t8 + i t10  
1137 - const double x1_real = t8_real - t10_imag;  
1138 - const double x1_imag = t8_imag + t10_real;  
1139 -  
1140 - // x2 = t9 + i t11  
1141 - const double x2_real = t9_real - t11_imag;  
1142 - const double x2_imag = t9_imag + t11_real;  
1143 -  
1144 - // x3 = t9 - i t11  
1145 - const double x3_real = t9_real + t11_imag;  
1146 - const double x3_imag = t9_imag - t11_real;  
1147 -  
1148 - // x4 = t8 - i t10  
1149 - const double x4_real = t8_real + t10_imag;  
1150 - const double x4_imag = t8_imag - t10_real;  
1151 -  
1152 - // out0 = 1 * x0  
1153 - //out[ostride*j].real(x0_real);  
1154 - //out[ostride*j].imag(x0_imag);  
1155 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
1156 -  
1157 - // out1 = w1 * x1  
1158 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
1159 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
1160 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
1161 - w1_real * x1_imag + w1_imag * x1_real);  
1162 -  
1163 - // out2 = w2 * x2  
1164 - //out[ostride*(j+2*p_1)].real(w2_real * x2_real - w2_imag * x2_imag);  
1165 - //out[ostride*(j+2*p_1)].imag(w2_real * x2_imag + w2_imag * x2_real);  
1166 - out[ostride*(j+2*p_1)] = std::complex<double>(w2_real * x2_real - w2_imag * x2_imag,  
1167 - w2_real * x2_imag + w2_imag * x2_real);  
1168 -  
1169 - // out3 = w3 * x3  
1170 - //out[ostride*(j+3*p_1)].real(w3_real * x3_real - w3_imag * x3_imag);  
1171 - //out[ostride*(j+3*p_1)].imag(w3_real * x3_imag + w3_imag * x3_real);  
1172 - out[ostride*(j+3*p_1)] = std::complex<double>(w3_real * x3_real - w3_imag * x3_imag,  
1173 - w3_real * x3_imag + w3_imag * x3_real);  
1174 -  
1175 - // out4 = w4 * x4  
1176 - //out[ostride*(j+4*p_1)].real(w4_real * x4_real - w4_imag * x4_imag);  
1177 - //out[ostride*(j+4*p_1)].imag(w4_real * x4_imag + w4_imag * x4_real);  
1178 - out[ostride*(j+4*p_1)] = std::complex<double>(w4_real * x4_real - w4_imag * x4_imag,  
1179 - w4_real * x4_imag + w4_imag * x4_real); 882 + const std::complex<double> z0 = *(in+istride*i);
  883 + const std::complex<double> z1 = *(in+istride*(i+m));
  884 + const std::complex<double> z2 = *(in+istride*(i+2*m));
  885 + const std::complex<double> z3 = *(in+istride*(i+3*m));
  886 + const std::complex<double> z4 = *(in+istride*(i+4*m));
  887 +
  888 + // Compute t
  889 + const std::complex<double> t1 = z1 + z4;
  890 + const std::complex<double> t2 = z2 + z3;
  891 + const std::complex<double> t3 = z1 - z4;
  892 + const std::complex<double> t4 = z2 - z3;
  893 + const std::complex<double> t5 = t1 + t2;
  894 + const std::complex<double> t6 = tau * (t1 - t2);
  895 + const std::complex<double> t7 = z0 - t5/4.0;
  896 + const std::complex<double> t8 = t7 + t6;
  897 + const std::complex<double> t9 = t7 - t6;
  898 + const std::complex<double> t10 = double((int)sign) *
  899 + (sin_2pi_by_5*t3 + sin_2pi_by_10*t4);
  900 + const std::complex<double> t11 = double((int)sign) *
  901 + (sin_2pi_by_10*t3 - sin_2pi_by_5*t4);
  902 +
  903 + // Compute x
  904 + const std::complex<double> x0 = z0 + t5;
  905 + const std::complex<double> x1 = t8 + timesi(t10);
  906 + const std::complex<double> x2 = t9 + timesi(t11);
  907 + const std::complex<double> x3 = t9 - timesi(t11);
  908 + const std::complex<double> x4 = t8 - timesi(t10);
  909 +
  910 + // Compute out = w * x
  911 + *(out+ostride*j) = x0;
  912 + *(out+ostride*(j+p_1)) = w[0] * x1;
  913 + *(out+ostride*(j+2*p_1)) = w[1] * x2;
  914 + *(out+ostride*(j+3*p_1)) = w[2] * x3;
  915 + *(out+ostride*(j+4*p_1)) = w[3] * x4;
1180 916
1181 } // endfor: k1 917 } // endfor: k1
1182 918
@@ -1190,9 +926,9 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1190,9 +926,9 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1190 /***********************************************************************//** 926 /***********************************************************************//**
1191 * @brief Compute FFT for factor 6 927 * @brief Compute FFT for factor 6
1192 * 928 *
1193 - * @param[in] in Input array. 929 + * @param[in] in Pointer to input array.
1194 * @param[in] istride Step size when traversing input array. 930 * @param[in] istride Step size when traversing input array.
1195 - * @param[in] out Output array. 931 + * @param[in] out Pointer to output array.
1196 * @param[in] ostride Step size when traversing output array. 932 * @param[in] ostride Step size when traversing output array.
1197 * @param[in] wavetable Trigonometric coefficients. 933 * @param[in] wavetable Trigonometric coefficients.
1198 * @param[in] sign Forward (-1) or backward (+1). 934 * @param[in] sign Forward (-1) or backward (+1).
@@ -1200,15 +936,15 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1200,15 +936,15 @@ void GFft::factor5(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1200 * @param[in] n Logical array length. 936 * @param[in] n Logical array length.
1201 * @param[in] index Start index of trigonometric coefficients. 937 * @param[in] index Start index of trigonometric coefficients.
1202 ***************************************************************************/ 938 ***************************************************************************/
1203 -void GFft::factor6(const std::vector<std::complex<double> >& in,  
1204 - const int& istride,  
1205 - std::vector<std::complex<double> >& out,  
1206 - const int& ostride,  
1207 - const GFftWavetable& wavetable,  
1208 - const int& sign,  
1209 - const int& product,  
1210 - const int& n,  
1211 - const int& index) 939 +void GFft::factor6(const std::complex<double>* in,
  940 + const int& istride,
  941 + std::complex<double>* out,
  942 + const int& ostride,
  943 + const GFftWavetable& wavetable,
  944 + const int& sign,
  945 + const int& product,
  946 + const int& n,
  947 + const int& index)
1212 { 948 {
1213 // Compute ... 949 // Compute ...
1214 const int factor = 6; 950 const int factor = 6;
@@ -1222,193 +958,57 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1222,193 +958,57 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1222 958
1223 // Loop over ... 959 // Loop over ...
1224 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 960 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1225 -  
1226 - // Allocate w  
1227 - double w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real,  
1228 - w4_imag, w5_real, w5_imag;  
1229 -  
1230 - // Set trigonometric coefficients for k=0 since they are not stored  
1231 - // in the wavetable object  
1232 - if (k == 0) {  
1233 - w1_real = 1.0;  
1234 - w1_imag = 0.0;  
1235 - w2_real = 1.0;  
1236 - w2_imag = 0.0;  
1237 - w3_real = 1.0;  
1238 - w3_imag = 0.0;  
1239 - w4_real = 1.0;  
1240 - w4_imag = 0.0;  
1241 - w5_real = 1.0;  
1242 - w5_imag = 0.0;  
1243 - }  
1244 - else {  
1245 961
1246 - // Compute indices  
1247 - int twiddle1 = index + k - 1;  
1248 - int twiddle2 = twiddle1 + q;  
1249 - int twiddle3 = twiddle2 + q;  
1250 - int twiddle4 = twiddle3 + q;  
1251 - int twiddle5 = twiddle4 + q;  
1252 -  
1253 - // Set trigonometric coefficients for forward transform  
1254 - if (sign == -1) {  
1255 - w1_real = wavetable[twiddle1].real();  
1256 - w1_imag = wavetable[twiddle1].imag();  
1257 - w2_real = wavetable[twiddle2].real();  
1258 - w2_imag = wavetable[twiddle2].imag();  
1259 - w3_real = wavetable[twiddle3].real();  
1260 - w3_imag = wavetable[twiddle3].imag();  
1261 - w4_real = wavetable[twiddle4].real();  
1262 - w4_imag = wavetable[twiddle4].imag();  
1263 - w5_real = wavetable[twiddle5].real();  
1264 - w5_imag = wavetable[twiddle5].imag();  
1265 - } 962 + // Extract coefficients from wavetable
  963 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 5, sign);
1266 964
1267 - // ... otherwise set trigonometric coefficients for backward  
1268 - // tranform: w -> conjugate(w)  
1269 - else {  
1270 - w1_real = wavetable[twiddle1].real();  
1271 - w1_imag = -wavetable[twiddle1].imag();  
1272 - w2_real = wavetable[twiddle2].real();  
1273 - w2_imag = -wavetable[twiddle2].imag();  
1274 - w3_real = wavetable[twiddle3].real();  
1275 - w3_imag = -wavetable[twiddle3].imag();  
1276 - w4_real = wavetable[twiddle4].real();  
1277 - w4_imag = -wavetable[twiddle4].imag();  
1278 - w5_real = wavetable[twiddle5].real();  
1279 - w5_imag = -wavetable[twiddle5].imag();  
1280 - }  
1281 -  
1282 - } // endelse: k != 0  
1283 -  
1284 - // ... 965 + // Compute x = W(6) z. W(6) is a combination of sums and differences of
  966 + // W(3) acting on the even and odd elements of z
1285 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 967 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1286 968
1287 // Get z 969 // Get z
1288 - const double z0_real = in[istride*i].real();  
1289 - const double z0_imag = in[istride*i].imag();  
1290 - const double z1_real = in[istride*(i+m)].real();  
1291 - const double z1_imag = in[istride*(i+m)].imag();  
1292 - const double z2_real = in[istride*(i+2*m)].real();  
1293 - const double z2_imag = in[istride*(i+2*m)].imag();  
1294 - const double z3_real = in[istride*(i+3*m)].real();  
1295 - const double z3_imag = in[istride*(i+3*m)].imag();  
1296 - const double z4_real = in[istride*(i+4*m)].real();  
1297 - const double z4_imag = in[istride*(i+4*m)].imag();  
1298 - const double z5_real = in[istride*(i+5*m)].real();  
1299 - const double z5_imag = in[istride*(i+5*m)].imag();  
1300 -  
1301 - // compute x = W(6) z  
1302 -  
1303 - // W(6) is a combination of sums and differences of W(3) acting  
1304 - // on the even and odd elements of z  
1305 -  
1306 - // ta1 = z2 + z4  
1307 - const double ta1_real = z2_real + z4_real;  
1308 - const double ta1_imag = z2_imag + z4_imag;  
1309 -  
1310 - // ta2 = z0 - ta1/2  
1311 - const double ta2_real = z0_real - ta1_real / 2.0;  
1312 - const double ta2_imag = z0_imag - ta1_imag / 2.0;  
1313 -  
1314 - // ta3 = (+/-) sin(pi/3)*(z2 - z4)  
1315 - const double ta3_real = ((int) sign) * tau * (z2_real - z4_real);  
1316 - const double ta3_imag = ((int) sign) * tau * (z2_imag - z4_imag);  
1317 -  
1318 - // a0 = z0 + ta1  
1319 - const double a0_real = z0_real + ta1_real;  
1320 - const double a0_imag = z0_imag + ta1_imag;  
1321 -  
1322 - // a1 = ta2 + i ta3  
1323 - const double a1_real = ta2_real - ta3_imag;  
1324 - const double a1_imag = ta2_imag + ta3_real;  
1325 -  
1326 - // a2 = ta2 - i ta3  
1327 - const double a2_real = ta2_real + ta3_imag;  
1328 - const double a2_imag = ta2_imag - ta3_real;  
1329 -  
1330 - // tb1 = z5 + z1  
1331 - const double tb1_real = z5_real + z1_real;  
1332 - const double tb1_imag = z5_imag + z1_imag;  
1333 -  
1334 - // tb2 = z3 - tb1/2  
1335 - const double tb2_real = z3_real - tb1_real / 2.0;  
1336 - const double tb2_imag = z3_imag - tb1_imag / 2.0;  
1337 -  
1338 - // tb3 = (+/-) sin(pi/3)*(z5 - z1)  
1339 - const double tb3_real = ((int) sign) * tau * (z5_real - z1_real);  
1340 - const double tb3_imag = ((int) sign) * tau * (z5_imag - z1_imag);  
1341 -  
1342 - // b0 = z3 + tb1  
1343 - const double b0_real = z3_real + tb1_real;  
1344 - const double b0_imag = z3_imag + tb1_imag;  
1345 -  
1346 - // b1 = tb2 + i tb3  
1347 - const double b1_real = tb2_real - tb3_imag;  
1348 - const double b1_imag = tb2_imag + tb3_real;  
1349 -  
1350 - // b2 = tb2 - i tb3  
1351 - const double b2_real = tb2_real + tb3_imag;  
1352 - const double b2_imag = tb2_imag - tb3_real;  
1353 -  
1354 - // x0 = a0 + b0  
1355 - const double x0_real = a0_real + b0_real;  
1356 - const double x0_imag = a0_imag + b0_imag;  
1357 -  
1358 - // x4 = a1 + b1  
1359 - const double x4_real = a1_real + b1_real;  
1360 - const double x4_imag = a1_imag + b1_imag;  
1361 -  
1362 - // x2 = a2 + b2  
1363 - const double x2_real = a2_real + b2_real;  
1364 - const double x2_imag = a2_imag + b2_imag;  
1365 -  
1366 - // x3 = a0 - b0  
1367 - const double x3_real = a0_real - b0_real;  
1368 - const double x3_imag = a0_imag - b0_imag;  
1369 -  
1370 - // x1 = a1 - b1  
1371 - const double x1_real = a1_real - b1_real;  
1372 - const double x1_imag = a1_imag - b1_imag;  
1373 -  
1374 - // x5 = a2 - b2  
1375 - const double x5_real = a2_real - b2_real;  
1376 - const double x5_imag = a2_imag - b2_imag;  
1377 -  
1378 - // out0 = 1 * x0  
1379 - //out[ostride*j].real(x0_real);  
1380 - //out[ostride*j].imag(x0_imag);  
1381 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
1382 -  
1383 - // out1 = w1 * x1  
1384 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
1385 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
1386 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
1387 - w1_real * x1_imag + w1_imag * x1_real);  
1388 -  
1389 - // out2 = w2 * x2  
1390 - //out[ostride*(j+2*p_1)].real(w2_real * x2_real - w2_imag * x2_imag);  
1391 - //out[ostride*(j+2*p_1)].imag(w2_real * x2_imag + w2_imag * x2_real);  
1392 - out[ostride*(j+2*p_1)] = std::complex<double>(w2_real * x2_real - w2_imag * x2_imag,  
1393 - w2_real * x2_imag + w2_imag * x2_real);  
1394 -  
1395 - // out3 = w3 * x3  
1396 - //out[ostride*(j+3*p_1)].real(w3_real * x3_real - w3_imag * x3_imag);  
1397 - //out[ostride*(j+3*p_1)].imag(w3_real * x3_imag + w3_imag * x3_real);  
1398 - out[ostride*(j+3*p_1)] = std::complex<double>(w3_real * x3_real - w3_imag * x3_imag,  
1399 - w3_real * x3_imag + w3_imag * x3_real);  
1400 -  
1401 - // out4 = w4 * x4  
1402 - //out[ostride*(j+4*p_1)].real(w4_real * x4_real - w4_imag * x4_imag);  
1403 - //out[ostride*(j+4*p_1)].imag(w4_real * x4_imag + w4_imag * x4_real);  
1404 - out[ostride*(j+4*p_1)] = std::complex<double>(w4_real * x4_real - w4_imag * x4_imag,  
1405 - w4_real * x4_imag + w4_imag * x4_real); 970 + const std::complex<double> z0 = *(in+istride*i);
  971 + const std::complex<double> z1 = *(in+istride*(i+m));
  972 + const std::complex<double> z2 = *(in+istride*(i+2*m));
  973 + const std::complex<double> z3 = *(in+istride*(i+3*m));
  974 + const std::complex<double> z4 = *(in+istride*(i+4*m));
  975 + const std::complex<double> z5 = *(in+istride*(i+5*m));
  976 +
  977 + // Compute ta
  978 + const std::complex<double> ta1 = z2 + z4;
  979 + const std::complex<double> ta2 = z0 - ta1/2.0;
  980 + const std::complex<double> ta3 = double((int)sign) * tau * (z2 - z4);
  981 +
  982 + // Compute a
  983 + const std::complex<double> a0 = z0 + ta1;
  984 + const std::complex<double> a1 = ta2 + timesi(ta3);
  985 + const std::complex<double> a2 = ta2 - timesi(ta3);
  986 +
  987 + // Compute tb
  988 + const std::complex<double> tb1 = z5 + z1;
  989 + const std::complex<double> tb2 = z3 - tb1/2.0;
  990 + const std::complex<double> tb3 = double((int)sign) * tau * (z5 - z1);
  991 +
  992 + // Compute b
  993 + const std::complex<double> b0 = z3 + tb1;
  994 + const std::complex<double> b1 = tb2 + timesi(tb3);
  995 + const std::complex<double> b2 = tb2 - timesi(tb3);
  996 +
  997 + // Compute x
  998 + const std::complex<double> x0 = a0 + b0;
  999 + const std::complex<double> x1 = a1 - b1;
  1000 + const std::complex<double> x2 = a2 + b2;
  1001 + const std::complex<double> x3 = a0 - b0;
  1002 + const std::complex<double> x4 = a1 + b1;
  1003 + const std::complex<double> x5 = a2 - b2;
1406 1004
1407 - // out5 = w5 * x5  
1408 - //out[ostride*(j+5*p_1)].real(w5_real * x5_real - w5_imag * x5_imag);  
1409 - //out[ostride*(j+5*p_1)].imag(w5_real * x5_imag + w5_imag * x5_real);  
1410 - out[ostride*(j+5*p_1)] = std::complex<double>(w5_real * x5_real - w5_imag * x5_imag,  
1411 - w5_real * x5_imag + w5_imag * x5_real); 1005 + // Compute out = w * x
  1006 + *(out+ostride*j) = x0;
  1007 + *(out+ostride*(j+p_1)) = w[0] * x1;
  1008 + *(out+ostride*(j+2*p_1)) = w[1] * x2;
  1009 + *(out+ostride*(j+3*p_1)) = w[2] * x3;
  1010 + *(out+ostride*(j+4*p_1)) = w[3] * x4;
  1011 + *(out+ostride*(j+5*p_1)) = w[4] * x5;
1412 1012
1413 } // endfor: k1 1013 } // endfor: k1
1414 1014
@@ -1422,9 +1022,9 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1422,9 +1022,9 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1422 /***********************************************************************//** 1022 /***********************************************************************//**
1423 * @brief Compute FFT for factor 7 1023 * @brief Compute FFT for factor 7
1424 * 1024 *
1425 - * @param[in] in Input array. 1025 + * @param[in] in Pointer to input array.
1426 * @param[in] istride Step size when traversing input array. 1026 * @param[in] istride Step size when traversing input array.
1427 - * @param[in] out Output array. 1027 + * @param[in] out Pointer to output array.
1428 * @param[in] ostride Step size when traversing output array. 1028 * @param[in] ostride Step size when traversing output array.
1429 * @param[in] wavetable Trigonometric coefficients. 1029 * @param[in] wavetable Trigonometric coefficients.
1430 * @param[in] sign Forward (-1) or backward (+1). 1030 * @param[in] sign Forward (-1) or backward (+1).
@@ -1432,15 +1032,15 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1432,15 +1032,15 @@ void GFft::factor6(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1432 * @param[in] n Logical array length. 1032 * @param[in] n Logical array length.
1433 * @param[in] index Start index of trigonometric coefficients. 1033 * @param[in] index Start index of trigonometric coefficients.
1434 ***************************************************************************/ 1034 ***************************************************************************/
1435 -void GFft::factor7(const std::vector<std::complex<double> >& in,  
1436 - const int& istride,  
1437 - std::vector<std::complex<double> >& out,  
1438 - const int& ostride,  
1439 - const GFftWavetable& wavetable,  
1440 - const int& sign,  
1441 - const int& product,  
1442 - const int& n,  
1443 - const int& index) 1035 +void GFft::factor7(const std::complex<double>* in,
  1036 + const int& istride,
  1037 + std::complex<double>* out,
  1038 + const int& ostride,
  1039 + const GFftWavetable& wavetable,
  1040 + const int& sign,
  1041 + const int& product,
  1042 + const int& n,
  1043 + const int& index)
1444 { 1044 {
1445 // Compute ... 1045 // Compute ...
1446 const int factor = 7; 1046 const int factor = 7;
@@ -1468,282 +1068,76 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1468,282 +1068,76 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1468 1068
1469 // Loop over ... 1069 // Loop over ...
1470 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) { 1070 for (int k = 0, i = 0, j = 0; k < q; ++k, j += jump) {
1471 -  
1472 - //  
1473 - double w1_real, w1_imag, w2_real, w2_imag, w3_real, w3_imag, w4_real,  
1474 - w4_imag, w5_real, w5_imag, w6_real, w6_imag;  
1475 -  
1476 - // Set trigonometric coefficients for k=0 since they are not stored  
1477 - // in the wavetable object  
1478 - if (k == 0) {  
1479 - w1_real = 1.0;  
1480 - w1_imag = 0.0;  
1481 - w2_real = 1.0;  
1482 - w2_imag = 0.0;  
1483 - w3_real = 1.0;  
1484 - w3_imag = 0.0;  
1485 - w4_real = 1.0;  
1486 - w4_imag = 0.0;  
1487 - w5_real = 1.0;  
1488 - w5_imag = 0.0;  
1489 - w6_real = 1.0;  
1490 - w6_imag = 0.0;  
1491 - }  
1492 - else {  
1493 -  
1494 - // Compute indices  
1495 - int twiddle1 = index + k - 1;  
1496 - int twiddle2 = twiddle1 + q;  
1497 - int twiddle3 = twiddle2 + q;  
1498 - int twiddle4 = twiddle3 + q;  
1499 - int twiddle5 = twiddle4 + q;  
1500 - int twiddle6 = twiddle5 + q;  
1501 -  
1502 - // Set trigonometric coefficients for forward transform  
1503 - if (sign == -1) {  
1504 - w1_real = wavetable[twiddle1].real();  
1505 - w1_imag = wavetable[twiddle1].imag();  
1506 - w2_real = wavetable[twiddle2].real();  
1507 - w2_imag = wavetable[twiddle2].imag();  
1508 - w3_real = wavetable[twiddle3].real();  
1509 - w3_imag = wavetable[twiddle3].imag();  
1510 - w4_real = wavetable[twiddle4].real();  
1511 - w4_imag = wavetable[twiddle4].imag();  
1512 - w5_real = wavetable[twiddle5].real();  
1513 - w5_imag = wavetable[twiddle5].imag();  
1514 - w6_real = wavetable[twiddle6].real();  
1515 - w6_imag = wavetable[twiddle6].imag();  
1516 - }  
1517 -  
1518 - // ... otherwise set trigonometric coefficients for backward  
1519 - // tranform: w -> conjugate(w)  
1520 - else {  
1521 - w1_real = wavetable[twiddle1].real();  
1522 - w1_imag = -wavetable[twiddle1].imag();  
1523 - w2_real = wavetable[twiddle2].real();  
1524 - w2_imag = -wavetable[twiddle2].imag();  
1525 - w3_real = wavetable[twiddle3].real();  
1526 - w3_imag = -wavetable[twiddle3].imag();  
1527 - w4_real = wavetable[twiddle4].real();  
1528 - w4_imag = -wavetable[twiddle4].imag();  
1529 - w5_real = wavetable[twiddle5].real();  
1530 - w5_imag = -wavetable[twiddle5].imag();  
1531 - w6_real = wavetable[twiddle6].real();  
1532 - w6_imag = -wavetable[twiddle6].imag();  
1533 - }  
1534 1071
1535 - } // endelse: k != 0 1072 + // Extract coefficients from wavetable
  1073 + std::vector<std::complex<double> > w = get_w(wavetable, index, k, q, 6, sign);
1536 1074
1537 - // ... 1075 + // Compute x = W(7) z
1538 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 1076 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1539 1077
1540 // Get z 1078 // Get z
1541 - const double z0_real = in[istride*i].real();  
1542 - const double z0_imag = in[istride*i].imag();  
1543 - const double z1_real = in[istride*(i+m)].real();  
1544 - const double z1_imag = in[istride*(i+m)].imag();  
1545 - const double z2_real = in[istride*(i+2*m)].real();  
1546 - const double z2_imag = in[istride*(i+2*m)].imag();  
1547 - const double z3_real = in[istride*(i+3*m)].real();  
1548 - const double z3_imag = in[istride*(i+3*m)].imag();  
1549 - const double z4_real = in[istride*(i+4*m)].real();  
1550 - const double z4_imag = in[istride*(i+4*m)].imag();  
1551 - const double z5_real = in[istride*(i+5*m)].real();  
1552 - const double z5_imag = in[istride*(i+5*m)].imag();  
1553 - const double z6_real = in[istride*(i+6*m)].real();  
1554 - const double z6_imag = in[istride*(i+6*m)].imag();  
1555 -  
1556 - // Compute x = W(7) z  
1557 -  
1558 - // t0 = z1 + z6  
1559 - const double t0_real = z1_real + z6_real;  
1560 - const double t0_imag = z1_imag + z6_imag;  
1561 -  
1562 - // t1 = z1 - z6  
1563 - const double t1_real = z1_real - z6_real;  
1564 - const double t1_imag = z1_imag - z6_imag;  
1565 -  
1566 - // t2 = z2 + z5  
1567 - const double t2_real = z2_real + z5_real;  
1568 - const double t2_imag = z2_imag + z5_imag;  
1569 -  
1570 - // t3 = z2 - z5  
1571 - const double t3_real = z2_real - z5_real;  
1572 - const double t3_imag = z2_imag - z5_imag;  
1573 -  
1574 - // t4 = z4 + z3  
1575 - const double t4_real = z4_real + z3_real;  
1576 - const double t4_imag = z4_imag + z3_imag;  
1577 -  
1578 - // t5 = z4 - z3  
1579 - const double t5_real = z4_real - z3_real;  
1580 - const double t5_imag = z4_imag - z3_imag;  
1581 -  
1582 - // t6 = t2 + t0  
1583 - const double t6_real = t2_real + t0_real;  
1584 - const double t6_imag = t2_imag + t0_imag;  
1585 -  
1586 - // t7 = t5 + t3  
1587 - const double t7_real = t5_real + t3_real;  
1588 - const double t7_imag = t5_imag + t3_imag;  
1589 -  
1590 - // b0 = z0 + t6 + t4  
1591 - const double b0_real = z0_real + t6_real + t4_real;  
1592 - const double b0_imag = z0_imag + t6_imag + t4_imag; 1079 + const std::complex<double> z0 = *(in+istride*i);
  1080 + const std::complex<double> z1 = *(in+istride*(i+m));
  1081 + const std::complex<double> z2 = *(in+istride*(i+2*m));
  1082 + const std::complex<double> z3 = *(in+istride*(i+3*m));
  1083 + const std::complex<double> z4 = *(in+istride*(i+4*m));
  1084 + const std::complex<double> z5 = *(in+istride*(i+5*m));
  1085 + const std::complex<double> z6 = *(in+istride*(i+6*m));
  1086 +
  1087 + // Compute t
  1088 + const std::complex<double> t0 = z1 + z6;
  1089 + const std::complex<double> t1 = z1 - z6;
  1090 + const std::complex<double> t2 = z2 + z5;
  1091 + const std::complex<double> t3 = z2 - z5;
  1092 + const std::complex<double> t4 = z4 + z3;
  1093 + const std::complex<double> t5 = z4 - z3;
  1094 + const std::complex<double> t6 = t2 + t0;
  1095 + const std::complex<double> t7 = t5 + t3;
  1096 +
  1097 + // Compute b
  1098 + const std::complex<double> b0 = z0 + t6 + t4;
  1099 + const std::complex<double> b1 = tau1 * (t6 + t4);
  1100 + const std::complex<double> b2 = tau2 * (t0 - t4);
  1101 + const std::complex<double> b3 = tau3 * (t4 - t2);
  1102 + const std::complex<double> b4 = tau4 * (t2 - t0);
  1103 + const std::complex<double> b5 = double(-(int)sign) * tau5 * (t7 + t1);
  1104 + const std::complex<double> b6 = double(-(int)sign) * tau6 * (t1 - t5);
  1105 + const std::complex<double> b7 = double(-(int)sign) * tau7 * (t5 - t3);
  1106 + const std::complex<double> b8 = double(-(int)sign) * tau8 * (t3 - t1);
  1107 +
  1108 + // Compute T
  1109 + const std::complex<double> T0 = b0 + b1;
  1110 + const std::complex<double> T1 = b2 + b3;
  1111 + const std::complex<double> T2 = b4 - b3;
  1112 + const std::complex<double> T3 = -b2 - b4;
  1113 + const std::complex<double> T4 = b6 + b7;
  1114 + const std::complex<double> T5 = b8 - b7;
  1115 + const std::complex<double> T6 = -b8 - b6;
  1116 + const std::complex<double> T7 = T0 + T1;
  1117 + const std::complex<double> T8 = T0 + T2;
  1118 + const std::complex<double> T9 = T0 + T3;
  1119 + const std::complex<double> T10 = T4 + b5;
  1120 + const std::complex<double> T11 = T5 + b5;
  1121 + const std::complex<double> T12 = T6 + b5;
  1122 +
  1123 + // Compute x
  1124 + const std::complex<double> x0 = b0;
  1125 + const std::complex<double> x1 = T7 - timesi(T10);
  1126 + const std::complex<double> x2 = T9 - timesi(T12);
  1127 + const std::complex<double> x3 = T8 + timesi(T11);
  1128 + const std::complex<double> x4 = T8 - timesi(T11);
  1129 + const std::complex<double> x5 = T9 + timesi(T12);
  1130 + const std::complex<double> x6 = T7 + timesi(T10);
  1131 +
  1132 + // Compute out = w * x
  1133 + *(out+ostride*j) = x0;
  1134 + *(out+ostride*(j+p_1)) = w[0] * x1;
  1135 + *(out+ostride*(j+2*p_1)) = w[1] * x2;
  1136 + *(out+ostride*(j+3*p_1)) = w[2] * x3;
  1137 + *(out+ostride*(j+4*p_1)) = w[3] * x4;
  1138 + *(out+ostride*(j+5*p_1)) = w[4] * x5;
  1139 + *(out+ostride*(j+6*p_1)) = w[5] * x6;
1593 1140
1594 - // b1 = ((cos(2pi/7) + cos(4pi/7) + cos(6pi/7))/3-1) (t6 + t4)  
1595 - const double b1_real = tau1 * (t6_real + t4_real);  
1596 - const double b1_imag = tau1 * (t6_imag + t4_imag);  
1597 -  
1598 - // b2 = ((2*cos(2pi/7) - cos(4pi/7) - cos(6pi/7))/3) (t0 - t4)  
1599 - const double b2_real = tau2 * (t0_real - t4_real);  
1600 - const double b2_imag = tau2 * (t0_imag - t4_imag);  
1601 -  
1602 - // b3 = ((cos(2pi/7) - 2*cos(4pi/7) + cos(6pi/7))/3) (t4 - t2)  
1603 - const double b3_real = tau3 * (t4_real - t2_real);  
1604 - const double b3_imag = tau3 * (t4_imag - t2_imag);  
1605 -  
1606 - // b4 = ((cos(2pi/7) + cos(4pi/7) - 2*cos(6pi/7))/3) (t2 - t0)  
1607 - const double b4_real = tau4 * (t2_real - t0_real);  
1608 - const double b4_imag = tau4 * (t2_imag - t0_imag);  
1609 -  
1610 - // b5 = sign * ((sin(2pi/7) + sin(4pi/7) - sin(6pi/7))/3) (t7 + t1)  
1611 - const double b5_real = (-(int)sign) * tau5 * (t7_real + t1_real);  
1612 - const double b5_imag = (-(int)sign) * tau5 * (t7_imag + t1_imag);  
1613 -  
1614 - // b6 = sign * ((2sin(2pi/7) - sin(4pi/7) + sin(6pi/7))/3) (t1 - t5)  
1615 - const double b6_real = (-(int)sign) * tau6 * (t1_real - t5_real);  
1616 - const double b6_imag = (-(int)sign) * tau6 * (t1_imag - t5_imag);  
1617 -  
1618 - // b7 = sign * ((sin(2pi/7) - 2sin(4pi/7) - sin(6pi/7))/3) (t5 - t3)  
1619 - const double b7_real = (-(int)sign) * tau7 * (t5_real - t3_real);  
1620 - const double b7_imag = (-(int)sign) * tau7 * (t5_imag - t3_imag);  
1621 -  
1622 - // b8 = sign * ((sin(2pi/7) + sin(4pi/7) + 2sin(6pi/7))/3) (t3 - t1) */  
1623 - const double b8_real = (-(int)sign) * tau8 * (t3_real - t1_real);  
1624 - const double b8_imag = (-(int)sign) * tau8 * (t3_imag - t1_imag);  
1625 -  
1626 - // T0 = b0 + b1  
1627 - const double T0_real = b0_real + b1_real;  
1628 - const double T0_imag = b0_imag + b1_imag;  
1629 -  
1630 - // T1 = b2 + b3  
1631 - const double T1_real = b2_real + b3_real;  
1632 - const double T1_imag = b2_imag + b3_imag;  
1633 -  
1634 - // T2 = b4 - b3  
1635 - const double T2_real = b4_real - b3_real;  
1636 - const double T2_imag = b4_imag - b3_imag;  
1637 -  
1638 - // T3 = -b2 - b4  
1639 - const double T3_real = -b2_real - b4_real;  
1640 - const double T3_imag = -b2_imag - b4_imag;  
1641 -  
1642 - // T4 = b6 + b7  
1643 - const double T4_real = b6_real + b7_real;  
1644 - const double T4_imag = b6_imag + b7_imag;  
1645 -  
1646 - // T5 = b8 - b7  
1647 - const double T5_real = b8_real - b7_real;  
1648 - const double T5_imag = b8_imag - b7_imag;  
1649 -  
1650 - // T6 = -b8 - b6  
1651 - const double T6_real = -b8_real - b6_real;  
1652 - const double T6_imag = -b8_imag - b6_imag;  
1653 -  
1654 - // T7 = T0 + T1  
1655 - const double T7_real = T0_real + T1_real;  
1656 - const double T7_imag = T0_imag + T1_imag;  
1657 -  
1658 - // T8 = T0 + T2  
1659 - const double T8_real = T0_real + T2_real;  
1660 - const double T8_imag = T0_imag + T2_imag;  
1661 -  
1662 - // T9 = T0 + T3  
1663 - const double T9_real = T0_real + T3_real;  
1664 - const double T9_imag = T0_imag + T3_imag;  
1665 -  
1666 - // T10 = T4 + b5  
1667 - const double T10_real = T4_real + b5_real;  
1668 - const double T10_imag = T4_imag + b5_imag;  
1669 -  
1670 - // T11 = T5 + b5  
1671 - const double T11_real = T5_real + b5_real;  
1672 - const double T11_imag = T5_imag + b5_imag;  
1673 -  
1674 - // T12 = T6 + b5  
1675 - const double T12_real = T6_real + b5_real;  
1676 - const double T12_imag = T6_imag + b5_imag;  
1677 -  
1678 - // x0 = b0  
1679 - const double x0_real = b0_real;  
1680 - const double x0_imag = b0_imag;  
1681 -  
1682 - // x1 = T7 - i T10  
1683 - const double x1_real = T7_real + T10_imag;  
1684 - const double x1_imag = T7_imag - T10_real;  
1685 -  
1686 - // x2 = T9 - i T12  
1687 - const double x2_real = T9_real + T12_imag;  
1688 - const double x2_imag = T9_imag - T12_real;  
1689 -  
1690 - // x3 = T8 + i T11  
1691 - const double x3_real = T8_real - T11_imag;  
1692 - const double x3_imag = T8_imag + T11_real;  
1693 -  
1694 - // x4 = T8 - i T11  
1695 - const double x4_real = T8_real + T11_imag;  
1696 - const double x4_imag = T8_imag - T11_real;  
1697 -  
1698 - // x5 = T9 + i T12  
1699 - const double x5_real = T9_real - T12_imag;  
1700 - const double x5_imag = T9_imag + T12_real;  
1701 -  
1702 - // x6 = T7 + i T10  
1703 - const double x6_real = T7_real - T10_imag;  
1704 - const double x6_imag = T7_imag + T10_real;  
1705 -  
1706 - // out0 = 1 * x0  
1707 - //out[ostride*j].real(x0_real);  
1708 - //out[ostride*j].imag(x0_imag);  
1709 - out[ostride*j] = std::complex<double>(x0_real, x0_imag);  
1710 -  
1711 - // out1 = w1 * x1  
1712 - //out[ostride*(j+p_1)].real(w1_real * x1_real - w1_imag * x1_imag);  
1713 - //out[ostride*(j+p_1)].imag(w1_real * x1_imag + w1_imag * x1_real);  
1714 - out[ostride*(j+p_1)] = std::complex<double>(w1_real * x1_real - w1_imag * x1_imag,  
1715 - w1_real * x1_imag + w1_imag * x1_real);  
1716 -  
1717 - // out2 = w2 * x2  
1718 - //out[ostride*(j+2*p_1)].real(w2_real * x2_real - w2_imag * x2_imag);  
1719 - //out[ostride*(j+2*p_1)].imag(w2_real * x2_imag + w2_imag * x2_real);  
1720 - out[ostride*(j+2*p_1)] = std::complex<double>(w2_real * x2_real - w2_imag * x2_imag,  
1721 - w2_real * x2_imag + w2_imag * x2_real);  
1722 -  
1723 - // out3 = w3 * x3  
1724 - //out[ostride*(j+3*p_1)].real(w3_real * x3_real - w3_imag * x3_imag);  
1725 - //out[ostride*(j+3*p_1)].imag(w3_real * x3_imag + w3_imag * x3_real);  
1726 - out[ostride*(j+3*p_1)] = std::complex<double>(w3_real * x3_real - w3_imag * x3_imag,  
1727 - w3_real * x3_imag + w3_imag * x3_real);  
1728 -  
1729 - // out4 = w4 * x4  
1730 - //out[ostride*(j+4*p_1)].real(w4_real * x4_real - w4_imag * x4_imag);  
1731 - //out[ostride*(j+4*p_1)].imag(w4_real * x4_imag + w4_imag * x4_real);  
1732 - out[ostride*(j+4*p_1)] = std::complex<double>(w4_real * x4_real - w4_imag * x4_imag,  
1733 - w4_real * x4_imag + w4_imag * x4_real);  
1734 -  
1735 - // out5 = w5 * x5  
1736 - //out[ostride*(j+5*p_1)].real(w5_real * x5_real - w5_imag * x5_imag);  
1737 - //out[ostride*(j+5*p_1)].imag(w5_real * x5_imag + w5_imag * x5_real);  
1738 - out[ostride*(j+5*p_1)] = std::complex<double>(w5_real * x5_real - w5_imag * x5_imag,  
1739 - w5_real * x5_imag + w5_imag * x5_real);  
1740 -  
1741 - // out6 = w6 * x6  
1742 - //out[ostride*(j+6*p_1)].real(w6_real * x6_real - w6_imag * x6_imag);  
1743 - //out[ostride*(j+6*p_1)].imag(w6_real * x6_imag + w6_imag * x6_real);  
1744 - out[ostride*(j+6*p_1)] = std::complex<double>(w6_real * x6_real - w6_imag * x6_imag,  
1745 - w6_real * x6_imag + w6_imag * x6_real);  
1746 -  
1747 } // endfor: k1 1141 } // endfor: k1
1748 1142
1749 } // endfor: k 1143 } // endfor: k
@@ -1756,9 +1150,9 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1756,9 +1150,9 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1756 /***********************************************************************//** 1150 /***********************************************************************//**
1757 * @brief Compute FFT for arbitrary factor 1151 * @brief Compute FFT for arbitrary factor
1758 * 1152 *
1759 - * @param[in] in Input array. 1153 + * @param[in] in Pointer to input array.
1760 * @param[in] istride Step size when traversing input array. 1154 * @param[in] istride Step size when traversing input array.
1761 - * @param[in] out Output array. 1155 + * @param[in] out Pointer to output array.
1762 * @param[in] ostride Step size when traversing output array. 1156 * @param[in] ostride Step size when traversing output array.
1763 * @param[in] wavetable Trigonometric coefficients. 1157 * @param[in] wavetable Trigonometric coefficients.
1764 * @param[in] sign Forward (-1) or backward (+1). 1158 * @param[in] sign Forward (-1) or backward (+1).
@@ -1767,16 +1161,16 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1767,16 +1161,16 @@ void GFft::factor7(const std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1767 * @param[in] n Logical array length. 1161 * @param[in] n Logical array length.
1768 * @param[in] index Start index of trigonometric coefficients. 1162 * @param[in] index Start index of trigonometric coefficients.
1769 ***************************************************************************/ 1163 ***************************************************************************/
1770 -void GFft::factorn(std::vector<std::complex<double> >& in,  
1771 - const int& istride,  
1772 - std::vector<std::complex<double> >& out,  
1773 - const int& ostride,  
1774 - const GFftWavetable& wavetable,  
1775 - const int& sign,  
1776 - const int& factor,  
1777 - const int& product,  
1778 - const int& n,  
1779 - const int& index) 1164 +void GFft::factorn(std::complex<double>* in,
  1165 + const int& istride,
  1166 + std::complex<double>* out,
  1167 + const int& ostride,
  1168 + const GFftWavetable& wavetable,
  1169 + const int& sign,
  1170 + const int& factor,
  1171 + const int& product,
  1172 + const int& n,
  1173 + const int& index)
1780 { 1174 {
1781 // Compute ... 1175 // Compute ...
1782 const int m = n / factor; 1176 const int m = n / factor;
@@ -1786,7 +1180,7 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1786,7 +1180,7 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1786 1180
1787 // ... 1181 // ...
1788 for (int i = 0; i < m; ++i) { 1182 for (int i = 0; i < m; ++i) {
1789 - out[ostride*i] = in[istride*i]; 1183 + *(out+ostride*i) = *(in+istride*i);
1790 } 1184 }
1791 1185
1792 // ... 1186 // ...
@@ -1794,19 +1188,19 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1794,19 +1188,19 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1794 for (int i = 0; i < m; ++i) { 1188 for (int i = 0; i < m; ++i) {
1795 const int idx = i + e * m; 1189 const int idx = i + e * m;
1796 const int idxc = i + (factor - e) * m; 1190 const int idxc = i + (factor - e) * m;
1797 - out[ostride*idx] = in[istride*idx] + in[istride*idxc];  
1798 - out[ostride*idxc] = in[istride*idx] - in[istride*idxc]; 1191 + *(out+ostride*idx) = *(in+istride*idx) + *(in+istride*idxc);
  1192 + *(out+ostride*idxc) = *(in+istride*idx) - *(in+istride*idxc);
1799 } 1193 }
1800 } 1194 }
1801 1195
1802 // e = 0 1196 // e = 0
1803 for (int i = 0; i < m; ++i) { 1197 for (int i = 0; i < m; ++i) {
1804 - in[istride*i] = out[ostride*i]; 1198 + *(in+istride*i) = *(out+ostride*i);
1805 } 1199 }
1806 for (int e = 1; e < (factor - 1) / 2 + 1; ++e) { 1200 for (int e = 1; e < (factor - 1) / 2 + 1; ++e) {
1807 for (int i = 0; i < m; ++i) { 1201 for (int i = 0; i < m; ++i) {
1808 - const int idx = i + e * m;  
1809 - in[istride*i] += out[ostride*idx]; 1202 + const int idx = i + e * m;
  1203 + *(in+istride*i) += *(out+ostride*idx);
1810 } 1204 }
1811 } 1205 }
1812 1206
@@ -1826,8 +1220,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1826,8 +1220,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1826 1220
1827 // ... 1221 // ...
1828 for (int i = 0; i < m; ++i) { 1222 for (int i = 0; i < m; ++i) {
1829 - in[istride*(i+em)] = out[ostride*i];  
1830 - in[istride*(i+ecm)] = out[ostride*i]; 1223 + *(in+istride*(i+em)) = *(out+ostride*i);
  1224 + *(in+istride*(i+ecm)) = *(out+ostride*i);
1831 } 1225 }
1832 1226
1833 // ... 1227 // ...
@@ -1860,10 +1254,10 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1860,10 +1254,10 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1860 for (int i = 0; i < m; ++i) { 1254 for (int i = 0; i < m; ++i) {
1861 1255
1862 // 1256 //
1863 - const double xp_real = out[ostride*(i + e1 * m)].real();  
1864 - const double xp_imag = out[ostride*(i + e1 * m)].imag();  
1865 - const double xm_real = out[ostride*(i + (factor-e1)*m)].real();  
1866 - const double xm_imag = out[ostride*(i + (factor-e1)*m)].imag(); 1257 + const double xp_real = (out+ostride*(i + e1 * m))->real();
  1258 + const double xp_imag = (out+ostride*(i + e1 * m))->imag();
  1259 + const double xm_real = (out+ostride*(i + (factor-e1)*m))->real();
  1260 + const double xm_imag = (out+ostride*(i + (factor-e1)*m))->imag();
1867 1261
1868 // 1262 //
1869 const double ap = w_real * xp_real; 1263 const double ap = w_real * xp_real;
@@ -1882,14 +1276,10 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1882,14 +1276,10 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1882 double sumc_imag = bp - bm; 1276 double sumc_imag = bp - bm;
1883 1277
1884 // 1278 //
1885 - //in[istride*(i+em)].real(in[istride*(i+em)].real() + sum_real);  
1886 - //in[istride*(i+em)].imag(in[istride*(i+em)].imag() + sum_imag);  
1887 - //in[istride*(i+ecm)].real(in[istride*(i+ecm)].real() + sumc_real);  
1888 - //in[istride*(i+ecm)].imag(in[istride*(i+ecm)].imag() + sumc_imag);  
1889 - in[istride*(i+em)] = std::complex<double>(in[istride*(i+em)].real() + sum_real,  
1890 - in[istride*(i+em)].imag() + sum_imag);  
1891 - in[istride*(i+ecm)] = std::complex<double>(in[istride*(i+ecm)].real() + sumc_real,  
1892 - in[istride*(i+ecm)].imag() + sumc_imag); 1279 + *(in+istride*(i+em)) = std::complex<double>((in+istride*(i+em))->real() + sum_real,
  1280 + (in+istride*(i+em))->imag() + sum_imag);
  1281 + *(in+istride*(i+ecm)) = std::complex<double>((in+istride*(i+ecm))->real() + sumc_real,
  1282 + (in+istride*(i+ecm))->imag() + sumc_imag);
1893 1283
1894 1284
1895 } // endfor: i 1285 } // endfor: i
@@ -1904,20 +1294,20 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1904,20 +1294,20 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1904 1294
1905 // k = 0 1295 // k = 0
1906 for (int k1 = 0; k1 < p_1; ++k1) { 1296 for (int k1 = 0; k1 < p_1; ++k1) {
1907 - out[ostride*k1] = in[istride*k1]; 1297 + *(out+ostride*k1) = *(in+istride*k1);
1908 } 1298 }
1909 1299
1910 // k > 0 1300 // k > 0
1911 for (int e1 = 1; e1 < factor; ++e1) { 1301 for (int e1 = 1; e1 < factor; ++e1) {
1912 for (int k1 = 0; k1 < p_1; ++k1) { 1302 for (int k1 = 0; k1 < p_1; ++k1) {
1913 - out[ostride*(k1 + e1 * p_1)] = in[istride*(k1 + e1 * m)]; 1303 + *(out+ostride*(k1 + e1 * p_1)) = *(in+istride*(k1 + e1 * m));
1914 } 1304 }
1915 } 1305 }
1916 1306
1917 // e = 0 1307 // e = 0
1918 for (int k = 1, i = p_1, j = product; k < q; ++k, j += jump) { 1308 for (int k = 1, i = p_1, j = product; k < q; ++k, j += jump) {
1919 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) { 1309 for (int k1 = 0; k1 < p_1; ++k1, ++i, ++j) {
1920 - out[ostride*j] = in[istride*i]; 1310 + *(out+ostride*j) = *(in+istride*i);
1921 } 1311 }
1922 } 1312 }
1923 1313
@@ -1929,8 +1319,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1929,8 +1319,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1929 for (int e1 = 1; e1 < factor; ++e1) { 1319 for (int e1 = 1; e1 < factor; ++e1) {
1930 1320
1931 // Get x 1321 // Get x
1932 - double x_real = in[istride*(i + e1 * m)].real();  
1933 - double x_imag = in[istride*(i + e1 * m)].imag(); 1322 + double x_real = (in+istride*(i + e1 * m))->real();
  1323 + double x_imag = (in+istride*(i + e1 * m))->imag();
1934 1324
1935 // Get w 1325 // Get w
1936 double w_real, w_imag; 1326 double w_real, w_imag;
@@ -1951,10 +1341,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1951,10 +1341,8 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1951 } 1341 }
1952 1342
1953 // 1343 //
1954 - //out[ostride*(j + e1 * p_1)].real(w_real * x_real - w_imag * x_imag);  
1955 - //out[ostride*(j + e1 * p_1)].imag(w_real * x_imag + w_imag * x_real);  
1956 - out[ostride*(j + e1 * p_1)] = std::complex<double>(w_real * x_real - w_imag * x_imag,  
1957 - w_real * x_imag + w_imag * x_real); 1344 + *(out+ostride*(j + e1 * p_1)) = std::complex<double>(w_real * x_real - w_imag * x_imag,
  1345 + w_real * x_imag + w_imag * x_real);
1958 1346
1959 } // endfor: e1 1347 } // endfor: e1
1960 1348
@@ -1965,3 +1353,57 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in, @@ -1965,3 +1353,57 @@ void GFft::factorn(std::vector&lt;std::complex&lt;double&gt; &gt;&amp; in,
1965 // Return 1353 // Return
1966 return; 1354 return;
1967 } 1355 }
  1356 +
  1357 +
  1358 +/***********************************************************************//**
  1359 + * @brief Extract coefficients from wavetable
  1360 + *
  1361 + * @param[in] index Start index of trigonometric coefficients.
  1362 + * @param[in] k ...
  1363 + * @param[in] q ...
  1364 + * @param[in] n Number of coefficients.
  1365 + * @param[in] sign Forward (-1) or backward (+1) transformation.
  1366 + * @param[in] wavetable Trigonometric coefficients.
  1367 + ***************************************************************************/
  1368 +std::vector<std::complex<double> > GFft::get_w(const GFftWavetable& wavetable,
  1369 + const int& index,
  1370 + const int& k,
  1371 + const int& q,
  1372 + const int& n,
  1373 + const int& sign) const
  1374 +{
  1375 + // Allocate w vectors
  1376 + std::vector<std::complex<double> > w(n);
  1377 +
  1378 + // Set trigonometric coefficients for k=0 since they are not stored in the
  1379 + // wavetable object
  1380 + if (k == 0) {
  1381 + w.assign(n, std::complex<double>(1.0, 0.0));
  1382 + }
  1383 +
  1384 + // ... otherwise use coefficients stored in wavetable
  1385 + else {
  1386 +
  1387 + // Compute indices
  1388 + int twiddle = index + k - 1;
  1389 +
  1390 + // If sign==-1 then set trigonometric coefficients for forward transform
  1391 + if (sign == -1) {
  1392 + for (int i = 0; i < n; ++i, twiddle += q) {
  1393 + w[i] = wavetable[twiddle];
  1394 + }
  1395 + }
  1396 +
  1397 + // ... otherwise set trigonometric coefficients for backward tranform
  1398 + // w -> conjugate(w)
  1399 + else {
  1400 + for (int i = 0; i < n; ++i, twiddle += q) {
  1401 + w[i] = std::conj(wavetable[twiddle]);
  1402 + }
  1403 + }
  1404 +
  1405 + } // endelse: k != 0
  1406 +
  1407 + // Return w vectors
  1408 + return w;
  1409 +}