gsl_fft__dft_source.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /* fft/dft_source.c
  2. *
  3. * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 3 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  18. */
  19. int
  20. FUNCTION(gsl_dft_complex,forward) (const BASE data[],
  21. const size_t stride, const size_t n,
  22. BASE result[])
  23. {
  24. gsl_fft_direction sign = gsl_fft_forward;
  25. int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign);
  26. return status;
  27. }
  28. int
  29. FUNCTION(gsl_dft_complex,backward) (const BASE data[],
  30. const size_t stride, const size_t n,
  31. BASE result[])
  32. {
  33. gsl_fft_direction sign = gsl_fft_backward;
  34. int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign);
  35. return status;
  36. }
  37. int
  38. FUNCTION(gsl_dft_complex,inverse) (const BASE data[],
  39. const size_t stride, const size_t n,
  40. BASE result[])
  41. {
  42. gsl_fft_direction sign = gsl_fft_backward;
  43. int status = FUNCTION(gsl_dft_complex,transform) (data, stride, n, result, sign);
  44. /* normalize inverse fft with 1/n */
  45. {
  46. const ATOMIC norm = ONE / (ATOMIC)n;
  47. size_t i;
  48. for (i = 0; i < n; i++)
  49. {
  50. REAL(result,stride,i) *= norm;
  51. IMAG(result,stride,i) *= norm;
  52. }
  53. }
  54. return status;
  55. }
  56. int
  57. FUNCTION(gsl_dft_complex,transform) (const BASE data[],
  58. const size_t stride, const size_t n,
  59. BASE result[],
  60. const gsl_fft_direction sign)
  61. {
  62. size_t i, j, exponent;
  63. const double d_theta = 2.0 * ((int) sign) * M_PI / (double) n;
  64. /* FIXME: check that input length == output length and give error */
  65. for (i = 0; i < n; i++)
  66. {
  67. ATOMIC sum_real = 0;
  68. ATOMIC sum_imag = 0;
  69. exponent = 0;
  70. for (j = 0; j < n; j++)
  71. {
  72. double theta = d_theta * (double) exponent;
  73. /* sum = exp(i theta) * data[j] */
  74. ATOMIC w_real = (ATOMIC) cos (theta);
  75. ATOMIC w_imag = (ATOMIC) sin (theta);
  76. ATOMIC data_real = REAL(data,stride,j);
  77. ATOMIC data_imag = IMAG(data,stride,j);
  78. sum_real += w_real * data_real - w_imag * data_imag;
  79. sum_imag += w_real * data_imag + w_imag * data_real;
  80. exponent = (exponent + i) % n;
  81. }
  82. REAL(result,stride,i) = sum_real;
  83. IMAG(result,stride,i) = sum_imag;
  84. }
  85. return 0;
  86. }