Commit 4b980331d91dc158246eb715e7932241f16f846f
1 parent
79d739e6
Implement 2-dimensional Fast Fourier Transformation (#1731)
Showing
8 changed files
with
241 additions
and
72 deletions
include/GFft.hpp
| ... | ... | @@ -66,7 +66,9 @@ public: |
| 66 | 66 | |
| 67 | 67 | // FFT access operators |
| 68 | 68 | std::complex<double>& operator()(const int& ix); |
| 69 | + std::complex<double>& operator()(const int& ix, const int& iy); | |
| 69 | 70 | const std::complex<double>& operator()(const int& ix) const; |
| 71 | + const std::complex<double>& operator()(const int& ix, const int& iy) const; | |
| 70 | 72 | |
| 71 | 73 | // Operators |
| 72 | 74 | GFft& operator=(const GFft& fft); |
| ... | ... | @@ -197,7 +199,7 @@ std::string GFft::classname(void) const |
| 197 | 199 | /***********************************************************************//** |
| 198 | 200 | * @brief 1-dimensional FFT element access operator |
| 199 | 201 | * |
| 200 | - * @param[in] ix Element index [0,...,size()-1]. | |
| 202 | + * @param[in] ix Element index [0,...,shape(0)-1]. | |
| 201 | 203 | * @return Reference to FFT element. |
| 202 | 204 | ***************************************************************************/ |
| 203 | 205 | inline |
| ... | ... | @@ -209,9 +211,24 @@ std::complex<double>& GFft::operator()(const int& ix) |
| 209 | 211 | |
| 210 | 212 | |
| 211 | 213 | /***********************************************************************//** |
| 214 | + * @brief 2-dimensional FFT element access operator | |
| 215 | + * | |
| 216 | + * @param[in] ix Index in first dimension [0,...,shape(0)-1]. | |
| 217 | + * @param[in] iy Index in second dimension [0,...,shape(1)-1]. | |
| 218 | + * @return Reference to FFT element. | |
| 219 | + ***************************************************************************/ | |
| 220 | +inline | |
| 221 | +std::complex<double>& GFft::operator()(const int& ix, const int& iy) | |
| 222 | +{ | |
| 223 | + // Return array element | |
| 224 | + return *(m_data + ix + m_strides[1]*iy); | |
| 225 | +} | |
| 226 | + | |
| 227 | + | |
| 228 | +/***********************************************************************//** | |
| 212 | 229 | * @brief 1-dimensional FFT element access operator (const variant) |
| 213 | 230 | * |
| 214 | - * @param[in] ix Element index [0,...,size()-1]. | |
| 231 | + * @param[in] ix Element index [0,...,shape(0)-1]. | |
| 215 | 232 | * @return Const reference to FFT element. |
| 216 | 233 | ***************************************************************************/ |
| 217 | 234 | inline |
| ... | ... | @@ -223,6 +240,23 @@ const std::complex<double>& GFft::operator()(const int& ix) const |
| 223 | 240 | |
| 224 | 241 | |
| 225 | 242 | /***********************************************************************//** |
| 243 | + * @brief 2-dimensional FFT element access operator (const variant) | |
| 244 | + * | |
| 245 | + * @param[in] ix Index in first dimension [0,...,shape(0)-1]. | |
| 246 | + * @param[in] iy Index in second dimension [0,...,shape(1)-1]. | |
| 247 | + * @return Const reference to FFT element. | |
| 248 | + ***************************************************************************/ | |
| 249 | +inline | |
| 250 | +const std::complex<double>& GFft::operator()(const int& ix, const int& iy) const | |
| 251 | +{ | |
| 252 | + // Return array element | |
| 253 | + return *(m_data + ix + m_strides[1]*iy); | |
| 254 | +} | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | +/***********************************************************************//** | |
| 226 | 260 | * @brief Return dimension of Fast Fourier Transformation |
| 227 | 261 | * |
| 228 | 262 | * @return Dimension of Fast Fourier Transformation. | ... | ... |
src/model/GModelSpectralExpInvPlaw.cpp
| ... | ... | @@ -85,7 +85,7 @@ GModelSpectralExpInvPlaw::GModelSpectralExpInvPlaw(void) : GModelSpectral() |
| 85 | 85 | * @param[in] prefactor Name of prefactor parameter. |
| 86 | 86 | * @param[in] index Name of index parameter. |
| 87 | 87 | * @param[in] pivot Name of pivot parameter. |
| 88 | - * @param[in] cutoff Name of cutoff parameter. | |
| 88 | + * @param[in] lambda Name of cutoff parameter. | |
| 89 | 89 | ***************************************************************************/ |
| 90 | 90 | GModelSpectralExpInvPlaw::GModelSpectralExpInvPlaw(const std::string& type, |
| 91 | 91 | const std::string& prefactor, | ... | ... |
src/numerics/GFft.cpp
| ... | ... | @@ -35,6 +35,8 @@ |
| 35 | 35 | #include "GNdarray.hpp" |
| 36 | 36 | |
| 37 | 37 | /* __ Method name definitions ____________________________________________ */ |
| 38 | +#define G_FORWARD "GFft::forward(GNdarray&)" | |
| 39 | +#define G_BACKWARD "GFft::backward()" | |
| 38 | 40 | |
| 39 | 41 | |
| 40 | 42 | /*========================================================================== |
| ... | ... | @@ -277,7 +279,27 @@ GFft* GFft::clone(void) const |
| 277 | 279 | * |
| 278 | 280 | * @param[in] array N-dimensional array. |
| 279 | 281 | * |
| 280 | - * @todo Method should support N-dim arrays, only supports 1-dim so far | |
| 282 | + * GException::feature_not_implemented | |
| 283 | + * Array dimension is not supported. | |
| 284 | + * | |
| 285 | + * Performs discret Fast Fourier forward transformation for 1- and | |
| 286 | + * 2-dimensional arrays. | |
| 287 | + * | |
| 288 | + * For one dimensional arrays of length \f$N\f$ the transformation is given | |
| 289 | + * by | |
| 290 | + * | |
| 291 | + * \f[ | |
| 292 | + * X_k = \sum_{n=0}^{N-1} z_n e^{-i 2 \pi \frac{k n}{N}} | |
| 293 | + * \f] | |
| 294 | + * | |
| 295 | + * and for two dimensional arrays of length \f$ M \times N\f$ the | |
| 296 | + * transformation is given by | |
| 297 | + * | |
| 298 | + * \f[ | |
| 299 | + * X_{k,l} = \sum_{n=0}^{N-1} \left( | |
| 300 | + * \sum_{m=0}^{M-1} z_{m,n} e^{-i 2 \pi \frac{m k}{M}} \right) | |
| 301 | + * e^{-i 2 \pi \frac{n l}{N}} | |
| 302 | + * \f] | |
| 281 | 303 | ***************************************************************************/ |
| 282 | 304 | void GFft::forward(const GNdarray& array) |
| 283 | 305 | { |
| ... | ... | @@ -286,26 +308,36 @@ void GFft::forward(const GNdarray& array) |
| 286 | 308 | |
| 287 | 309 | // Continue only if there are elements in the data member |
| 288 | 310 | if (m_size > 0) { |
| 289 | -/* | |
| 290 | - // Loop over all dimensions of array | |
| 291 | - for (int d = 0; d < dim(); ++d) { | |
| 292 | 311 | |
| 293 | - // Loop over all dimensions of array | |
| 294 | - for (int i = 0; i < dim(); ++i) { | |
| 312 | + // Case A: array is 1-dimensional | |
| 313 | + if (array.dim() == 1) { | |
| 314 | + transform(m_data, 1, m_shape[0], m_wavetable[0], true); | |
| 315 | + } | |
| 295 | 316 | |
| 296 | - // Skip | |
| 297 | - if (d == i) { | |
| 298 | - continue; | |
| 299 | - } | |
| 317 | + // Case B: array is 2-dimensional | |
| 318 | + else if (array.dim() == 2) { | |
| 300 | 319 | |
| 301 | - // Loop over all | |
| 302 | - int n = shape()[d]; | |
| 303 | - int stride = strides()[d]; | |
| 304 | - int istart = | |
| 305 | -*/ | |
| 320 | + // Loop over rows | |
| 321 | + for (int row = 0; row < m_shape[1]; ++row) { | |
| 322 | + transform(m_data + row*m_strides[1], m_strides[0], m_shape[0], | |
| 323 | + m_wavetable[0], true); | |
| 324 | + } | |
| 306 | 325 | |
| 307 | - // Perform FFT (is only correct for 1D for now) | |
| 308 | - transform(m_data, 1, m_shape[0], m_wavetable[0], true); | |
| 326 | + // Loop over columns | |
| 327 | + for (int col = 0; col < m_shape[0]; ++col) { | |
| 328 | + transform(m_data + col*m_strides[0], m_strides[1], m_shape[1], | |
| 329 | + m_wavetable[1], true); | |
| 330 | + } | |
| 331 | + | |
| 332 | + } | |
| 333 | + | |
| 334 | + // ... otherwise throw an exception | |
| 335 | + else { | |
| 336 | + std::string msg = "Fast Fourier Transformation for "+ | |
| 337 | + gammalib::str(array.dim())+"-dimensional array " | |
| 338 | + "not implemented."; | |
| 339 | + throw GException::feature_not_implemented(G_FORWARD, msg); | |
| 340 | + } | |
| 309 | 341 | |
| 310 | 342 | } // endif: there were elements in the FFT data member |
| 311 | 343 | |
| ... | ... | @@ -319,7 +351,28 @@ void GFft::forward(const GNdarray& array) |
| 319 | 351 | * |
| 320 | 352 | * @return N-dimensional array. |
| 321 | 353 | * |
| 322 | - * @todo Method should support N-dim arrays, only supports 1-dim so far | |
| 354 | + * GException::feature_not_implemented | |
| 355 | + * Array dimension is not supported. | |
| 356 | + * | |
| 357 | + * Performs the inverse (or backward) discret Fast Fourier forward | |
| 358 | + * transformation for 1- and 2-dimensional arrays. | |
| 359 | + * | |
| 360 | + * For one dimensional arrays of length \f$N\f$ the transformation is given | |
| 361 | + * by | |
| 362 | + * | |
| 363 | + * \f[ | |
| 364 | + * z_k = \frac{1}{N} \sum_{n=0}^{N-1} X_n e^{i 2 \pi \frac{k n}{N}} | |
| 365 | + * \f] | |
| 366 | + * | |
| 367 | + * and for two dimensional arrays of length \f$ M \times N\f$ the | |
| 368 | + * transformation is given by | |
| 369 | + * | |
| 370 | + * \f[ | |
| 371 | + * z_{k,l} = \frac{1}{N} \sum_{n=0}^{N-1} \left( | |
| 372 | + * \frac{1}{M} \sum_{m=0}^{M-1} X_{m,n} | |
| 373 | + * e^{i 2 \pi \frac{m k}{M}} \right) | |
| 374 | + * e^{i 2 \pi \frac{n l}{N}} | |
| 375 | + * \f] | |
| 323 | 376 | ***************************************************************************/ |
| 324 | 377 | GNdarray GFft::backward(void) const |
| 325 | 378 | { |
| ... | ... | @@ -327,24 +380,66 @@ GNdarray GFft::backward(void) const |
| 327 | 380 | GNdarray array(shape()); |
| 328 | 381 | |
| 329 | 382 | // Continue only if there are elements in the array |
| 330 | - if (array.size() > 0) { | |
| 383 | + if (m_size > 0) { | |
| 331 | 384 | |
| 332 | 385 | // Create copy of complex array |
| 333 | - std::complex<double>* data = new std::complex<double>[array.size()]; | |
| 334 | - for (int i = 0; i < array.size(); ++i) { | |
| 386 | + std::complex<double>* data = new std::complex<double>[m_size]; | |
| 387 | + for (int i = 0; i < m_size; ++i) { | |
| 335 | 388 | *(data+i) = *(m_data+i); |
| 336 | 389 | } |
| 337 | 390 | |
| 338 | - // Perform FFT (circumvent const correctness) | |
| 339 | - const_cast<GFft*>(this)->transform(data, 1, m_shape[0], m_wavetable[0], | |
| 340 | - false); | |
| 391 | + // Case A: array is 1-dimensional | |
| 392 | + if (array.dim() == 1) { | |
| 393 | + | |
| 394 | + // Perform backward transformation (circumvent const correctness) | |
| 395 | + const_cast<GFft*>(this)->transform(data, 1, m_shape[0], m_wavetable[0], false); | |
| 396 | + | |
| 397 | + // Get normalisation factor | |
| 398 | + const double norm = 1.0 / double(m_shape[0]); | |
| 399 | + | |
| 400 | + // Extract 1-dimensional array and normalise with 1/n | |
| 401 | + for (int i = 0; i < m_size; ++i) { | |
| 402 | + array(i) = (data+i)->real() * norm; | |
| 403 | + } | |
| 404 | + | |
| 405 | + } | |
| 406 | + | |
| 407 | + // Case B: array is 2-dimensional | |
| 408 | + else if (array.dim() == 2) { | |
| 341 | 409 | |
| 342 | - // Get normalisation factor | |
| 343 | - const double norm = 1.0 / double(array.size()); | |
| 410 | + // Loop over rows | |
| 411 | + for (int row = 0; row < m_shape[1]; ++row) { | |
| 412 | + const_cast<GFft*>(this)->transform(data + row*m_strides[1], m_strides[0], m_shape[0], | |
| 413 | + m_wavetable[0], false); | |
| 414 | + } | |
| 415 | + | |
| 416 | + // Loop over columns | |
| 417 | + for (int col = 0; col < m_shape[0]; ++col) { | |
| 418 | + const_cast<GFft*>(this)->transform(data + col*m_strides[0], m_strides[1], m_shape[1], | |
| 419 | + m_wavetable[1], false); | |
| 420 | + } | |
| 421 | + | |
| 422 | + // Get normalisation factor | |
| 423 | + const double norm = 1.0 / double(m_shape[0]*m_shape[1]); | |
| 424 | + | |
| 425 | + // Extract 2-dimensional array and normalise with 1/(n*m) | |
| 426 | + for (int i = 0; i < m_size; ++i) { | |
| 427 | + array(i) = (data+i)->real() * norm; | |
| 428 | + } | |
| 344 | 429 | |
| 345 | - // Extract N-dimensional array and normalise with 1/n | |
| 346 | - for (int i = 0; i < array.size(); ++i) { | |
| 347 | - array(i) = (data+i)->real() * norm; | |
| 430 | + } | |
| 431 | + | |
| 432 | + // ... otherwise throw an exception | |
| 433 | + else { | |
| 434 | + | |
| 435 | + // Delete copy of complex array | |
| 436 | + delete [] data; | |
| 437 | + | |
| 438 | + // Throw exception | |
| 439 | + std::string msg = "Fast Fourier Transformation for "+ | |
| 440 | + gammalib::str(array.dim())+"-dimensional array " | |
| 441 | + "not implemented."; | |
| 442 | + throw GException::feature_not_implemented(G_BACKWARD, msg); | |
| 348 | 443 | } |
| 349 | 444 | |
| 350 | 445 | // Delete copy of complex array |
| ... | ... | @@ -501,15 +596,9 @@ void GFft::set_data(const GNdarray& array) |
| 501 | 596 | *(m_data+i) = std::complex<double>(array(i), 0.0); |
| 502 | 597 | } |
| 503 | 598 | |
| 504 | - // Save shape | |
| 505 | - m_shape = array.shape(); | |
| 506 | - | |
| 507 | - // Set strides | |
| 508 | - int stride = 1; | |
| 509 | - for (int i = 0; i < m_shape.size(); ++i) { | |
| 510 | - m_strides.push_back(stride); | |
| 511 | - stride *= m_shape[i]; | |
| 512 | - } | |
| 599 | + // Save shape and strides | |
| 600 | + m_shape = array.shape(); | |
| 601 | + m_strides = array.strides(); | |
| 513 | 602 | |
| 514 | 603 | // Set trigonometric coefficients |
| 515 | 604 | for (int i = 0; i < m_shape.size(); ++i) { |
| ... | ... | @@ -1319,30 +1408,18 @@ void GFft::factorn(std::complex<double>* in, |
| 1319 | 1408 | for (int e1 = 1; e1 < factor; ++e1) { |
| 1320 | 1409 | |
| 1321 | 1410 | // Get x |
| 1322 | - double x_real = (in+istride*(i + e1 * m))->real(); | |
| 1323 | - double x_imag = (in+istride*(i + e1 * m))->imag(); | |
| 1411 | + std::complex<double> x = *(in+istride*(i + e1 * m)); | |
| 1324 | 1412 | |
| 1325 | - // Get w | |
| 1326 | - double w_real, w_imag; | |
| 1327 | - | |
| 1328 | - // Compute indices | |
| 1413 | + // Compute index | |
| 1329 | 1414 | int twiddle = index + (e1-1)*q + k-1; |
| 1330 | 1415 | |
| 1331 | - // Set trigonometric coefficients for forward transform | |
| 1332 | - if (sign == -1) { | |
| 1333 | - w_real = wavetable[twiddle].real(); | |
| 1334 | - w_imag = wavetable[twiddle].imag(); | |
| 1335 | - } | |
| 1336 | - // ... otherwise set trigonometric coefficients for backward | |
| 1337 | - // tranform: w -> conjugate(w) | |
| 1338 | - else { | |
| 1339 | - w_real = wavetable[twiddle].real(); | |
| 1340 | - w_imag = -wavetable[twiddle].imag(); | |
| 1341 | - } | |
| 1416 | + // Get w | |
| 1417 | + std::complex<double> w = (sign == -1) | |
| 1418 | + ? wavetable[twiddle] | |
| 1419 | + : std::conj(wavetable[twiddle]); | |
| 1342 | 1420 | |
| 1343 | - // | |
| 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); | |
| 1421 | + // Compute out = w * x | |
| 1422 | + *(out+ostride*(j + e1 * p_1)) = w * x; | |
| 1346 | 1423 | |
| 1347 | 1424 | } // endfor: e1 |
| 1348 | 1425 | ... | ... |
src/numerics/GFftWavetable.cpp
| ... | ... | @@ -383,7 +383,7 @@ void GFftWavetable::set_members(const int& n) |
| 383 | 383 | * |
| 384 | 384 | * @exception GException::invalid_argument |
| 385 | 385 | * Non positive array length specified |
| 386 | - * @expection GException::invalid_value | |
| 386 | + * @exception GException::invalid_value | |
| 387 | 387 | * Product of factorisation factors are not equal to array length |
| 388 | 388 | * |
| 389 | 389 | * Computes the factorisation | ... | ... |
src/numerics/GNdarray.cpp
| ... | ... | @@ -777,6 +777,7 @@ bool GNdarray::has_same_shape(const GNdarray& array) const |
| 777 | 777 | /***********************************************************************//** |
| 778 | 778 | * @brief Throw exception if array shapes differ |
| 779 | 779 | * |
| 780 | + * @param[in] method Method that throws exception. | |
| 780 | 781 | * @param[in] array Array. |
| 781 | 782 | ***************************************************************************/ |
| 782 | 783 | void GNdarray::require_same_shape(const std::string& method, | ... | ... |
src/vo/GVOTable.cpp
| ... | ... | @@ -120,7 +120,7 @@ GVOTable::~GVOTable(void) |
| 120 | 120 | /***********************************************************************//** |
| 121 | 121 | * @brief Assignment operator |
| 122 | 122 | * |
| 123 | - * @param[in] VO table. | |
| 123 | + * @param[in] votable VO table. | |
| 124 | 124 | * @return VO table. |
| 125 | 125 | ***************************************************************************/ |
| 126 | 126 | GVOTable& GVOTable::operator=(const GVOTable& votable) | ... | ... |
test/test_GNumerics.cpp
| ... | ... | @@ -282,7 +282,7 @@ void TestGNumerics::test_ndarray(void) |
| 282 | 282 | ***************************************************************************/ |
| 283 | 283 | void TestGNumerics::test_fft(void) |
| 284 | 284 | { |
| 285 | - // Loop over array lengths | |
| 285 | + // Test 1-dimensional FFT | |
| 286 | 286 | for (int n = 2; n < 12; ++n) { |
| 287 | 287 | |
| 288 | 288 | // Skip n=8,9,10 since they can be factorised |
| ... | ... | @@ -303,25 +303,32 @@ void TestGNumerics::test_fft(void) |
| 303 | 303 | GNdarray back = fft.backward(); |
| 304 | 304 | |
| 305 | 305 | // Check FFT results |
| 306 | - check_fft(array, fft, back); | |
| 306 | + check_fft1(array, fft, back); | |
| 307 | 307 | |
| 308 | 308 | } // endfor: looped over array lengths |
| 309 | 309 | |
| 310 | + // Test 2-dimensional FFT | |
| 311 | + GNdarray array2(8,9); | |
| 312 | + array2(4,4) = 1.0; | |
| 313 | + GFft fft2(array2); | |
| 314 | + GNdarray back2 = fft2.backward(); | |
| 315 | + check_fft2(array2, fft2, back2); | |
| 316 | + | |
| 310 | 317 | // Exit test |
| 311 | 318 | return; |
| 312 | 319 | } |
| 313 | 320 | |
| 314 | 321 | |
| 315 | 322 | /***********************************************************************//** |
| 316 | - * @brief Check Fast Fourier Transform | |
| 323 | + * @brief Check 1-dimensional Fast Fourier Transform | |
| 317 | 324 | * |
| 318 | 325 | * @param[in] array Input array. |
| 319 | 326 | * @param[in] fft Fast Fourier Transform of input array. |
| 320 | 327 | * @param[in] back Backward transform of FFT (should be equal to input array) |
| 321 | 328 | ***************************************************************************/ |
| 322 | -void TestGNumerics::check_fft(const GNdarray& array, | |
| 323 | - const GFft& fft, | |
| 324 | - const GNdarray& back) | |
| 329 | +void TestGNumerics::check_fft1(const GNdarray& array, | |
| 330 | + const GFft& fft, | |
| 331 | + const GNdarray& back) | |
| 325 | 332 | { |
| 326 | 333 | // Get normalisation factor |
| 327 | 334 | double norm = 1.0 / double(array.size()); |
| ... | ... | @@ -350,6 +357,53 @@ void TestGNumerics::check_fft(const GNdarray& array, |
| 350 | 357 | |
| 351 | 358 | |
| 352 | 359 | /***********************************************************************//** |
| 360 | + * @brief Check 2-dimensional Fast Fourier Transform | |
| 361 | + * | |
| 362 | + * @param[in] array Input array. | |
| 363 | + * @param[in] fft Fast Fourier Transform of input array. | |
| 364 | + * @param[in] back Backward transform of FFT (should be equal to input array) | |
| 365 | + ***************************************************************************/ | |
| 366 | +void TestGNumerics::check_fft2(const GNdarray& array, | |
| 367 | + const GFft& fft, | |
| 368 | + const GNdarray& back) | |
| 369 | +{ | |
| 370 | + // Get normalisation factor | |
| 371 | + double normM = 1.0 / double(array.shape()[0]); | |
| 372 | + double normN = 1.0 / double(array.shape()[1]); | |
| 373 | + | |
| 374 | + // Compute reference value and compare with FFT result | |
| 375 | + for (int k = 0; k < array.shape()[0]; ++k) { | |
| 376 | + for (int l = 0; l < array.shape()[1]; ++l) { | |
| 377 | + double ref_real = 0.0; | |
| 378 | + double ref_imag = 0.0; | |
| 379 | + for (int n = 0; n < array.shape()[1]; ++n) { | |
| 380 | + double sum_real = 0.0; | |
| 381 | + double sum_imag = 0.0; | |
| 382 | + for (int m = 0; m < array.shape()[0]; ++m) { | |
| 383 | + double x = -gammalib::twopi * m * k * normM; | |
| 384 | + sum_real += array(m,n) * std::cos(x); | |
| 385 | + sum_imag += array(m,n) * std::sin(x); | |
| 386 | + } | |
| 387 | + double y = -gammalib::twopi * n * l * normN; | |
| 388 | + ref_real += (sum_real * std::cos(y) - sum_imag * std::sin(y)); | |
| 389 | + ref_imag += (sum_real * std::sin(y) + sum_imag * std::cos(y)); | |
| 390 | + } | |
| 391 | + std::complex<double> ref(ref_real, ref_imag); | |
| 392 | + test_value(fft(k,l), ref); | |
| 393 | + } | |
| 394 | + } | |
| 395 | + | |
| 396 | + // Test backward transformation | |
| 397 | + for (int k = 0; k < array.size(); ++k) { | |
| 398 | + test_value(back(k), array(k)); | |
| 399 | + } | |
| 400 | + | |
| 401 | + // Exit test | |
| 402 | + return; | |
| 403 | +} | |
| 404 | + | |
| 405 | + | |
| 406 | +/***********************************************************************//** | |
| 353 | 407 | * @brief Test model parameter handling |
| 354 | 408 | ***************************************************************************/ |
| 355 | 409 | void TestGNumerics::test_integral(void) | ... | ... |
test/test_GNumerics.hpp
| ... | ... | @@ -70,9 +70,12 @@ public: |
| 70 | 70 | virtual std::string classname(void) const { return "TestGNumerics"; } |
| 71 | 71 | void test_ndarray(void); |
| 72 | 72 | void test_fft(void); |
| 73 | - void check_fft(const GNdarray& array, | |
| 74 | - const GFft& fft, | |
| 75 | - const GNdarray& back); | |
| 73 | + void check_fft1(const GNdarray& array, | |
| 74 | + const GFft& fft, | |
| 75 | + const GNdarray& back); | |
| 76 | + void check_fft2(const GNdarray& array, | |
| 77 | + const GFft& fft, | |
| 78 | + const GNdarray& back); | |
| 76 | 79 | void test_integral(void); |
| 77 | 80 | void test_romberg_integration(void); |
| 78 | 81 | void test_adaptive_simpson_integration(void); | ... | ... |