Blame fft/test_real_source.c

Packit 67cb25
/* fft/test_real.c
Packit 67cb25
 * 
Packit 67cb25
 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Brian Gough
Packit 67cb25
 * 
Packit 67cb25
 * This program is free software; you can redistribute it and/or modify
Packit 67cb25
 * it under the terms of the GNU General Public License as published by
Packit 67cb25
 * the Free Software Foundation; either version 3 of the License, or (at
Packit 67cb25
 * your option) any later version.
Packit 67cb25
 * 
Packit 67cb25
 * This program is distributed in the hope that it will be useful, but
Packit 67cb25
 * WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 67cb25
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 67cb25
 * General Public License for more details.
Packit 67cb25
 * 
Packit 67cb25
 * You should have received a copy of the GNU General Public License
Packit 67cb25
 * along with this program; if not, write to the Free Software
Packit 67cb25
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
Packit 67cb25
 */
Packit 67cb25
Packit 67cb25
#include "bitreverse.h"
Packit 67cb25
#include "signals.h"
Packit 67cb25
#include "compare.h"
Packit 67cb25
Packit 67cb25
void FUNCTION(test_real,func) (size_t stride, size_t n);
Packit 67cb25
void FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n);
Packit 67cb25
void FUNCTION(test_real,radix2) (size_t stride, size_t n);
Packit 67cb25
Packit 67cb25
void FUNCTION(test_real,func) (size_t stride, size_t n) 
Packit 67cb25
{
Packit 67cb25
  size_t i ;
Packit 67cb25
  int status ;
Packit 67cb25
Packit 67cb25
  TYPE(gsl_fft_real_wavetable) * rw ;
Packit 67cb25
  TYPE(gsl_fft_halfcomplex_wavetable) * hcw ;
Packit 67cb25
  TYPE(gsl_fft_real_workspace) * rwork ;
Packit 67cb25
Packit 67cb25
  BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE));
Packit 67cb25
  BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
  BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
  BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
Packit 67cb25
  for (i = 0 ; i < n * stride ; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i] = (BASE)i ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  for (i = 0 ; i < 2 * n * stride ; i++)
Packit 67cb25
    {
Packit 67cb25
      complex_data[i] = (BASE)(i + 1000.0) ;
Packit 67cb25
      complex_tmp[i] = (BASE)(i + 2000.0) ;
Packit 67cb25
      fft_complex_data[i] = (BASE)(i + 3000.0) ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_set_error_handler (NULL); /* abort on any errors */
Packit 67cb25
  
Packit 67cb25
  /* mixed radix real fft */
Packit 67cb25
  
Packit 67cb25
  rw = FUNCTION(gsl_fft_real_wavetable,alloc) (n);
Packit 67cb25
  gsl_test (rw == 0, NAME(gsl_fft_real_wavetable) 
Packit 67cb25
            "_alloc, n = %d, stride = %d", n, stride);
Packit 67cb25
Packit 67cb25
  rwork = FUNCTION(gsl_fft_real_workspace,alloc) (n);
Packit 67cb25
  gsl_test (rwork == 0, NAME(gsl_fft_real_workspace) 
Packit 67cb25
            "_alloc, n = %d", n);
Packit 67cb25
    
Packit 67cb25
  FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data);
Packit 67cb25
  memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE));
Packit 67cb25
Packit 67cb25
  for (i = 0; i < n; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i*stride] = REAL(complex_data,stride,i);
Packit 67cb25
    }
Packit 67cb25
  
Packit 67cb25
  FUNCTION(gsl_fft_real,transform) (real_data, stride, n, rw, rwork);
Packit 67cb25
  FUNCTION(gsl_fft_halfcomplex,unpack) (real_data, complex_data, stride, n);
Packit 67cb25
  
Packit 67cb25
  status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
Packit 67cb25
                                              "fft of noise", complex_data,
Packit 67cb25
                                              stride, n, 1e6);
Packit 67cb25
  gsl_test (status, NAME(gsl_fft_real) 
Packit 67cb25
            " with signal_real_noise, n = %d, stride = %d", n, stride);
Packit 67cb25
  
Packit 67cb25
  /* compute the inverse fft */
Packit 67cb25
Packit 67cb25
  hcw = FUNCTION(gsl_fft_halfcomplex_wavetable,alloc) (n);
Packit 67cb25
  gsl_test (hcw == 0, NAME(gsl_fft_halfcomplex_wavetable) 
Packit 67cb25
            "_alloc, n = %d, stride = %d", n, stride);
Packit 67cb25
Packit 67cb25
  status = FUNCTION(gsl_fft_halfcomplex,transform) (real_data, stride, n, hcw, rwork);
Packit 67cb25
  
Packit 67cb25
  for (i = 0; i < n; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i*stride] /= n;
Packit 67cb25
    }
Packit 67cb25
  
Packit 67cb25
  FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n);
Packit 67cb25
  
Packit 67cb25
  status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
Packit 67cb25
                                              "fft inverse", complex_data,
Packit 67cb25
                                              stride, n, 1e6);
Packit 67cb25
Packit 67cb25
  gsl_test (status, NAME(gsl_fft_halfcomplex) 
Packit 67cb25
            " with data from signal_noise, n = %d, stride = %d", n, stride);
Packit 67cb25
Packit 67cb25
  FUNCTION(gsl_fft_real_workspace,free) (rwork);
Packit 67cb25
  FUNCTION(gsl_fft_real_wavetable,free) (rw);
Packit 67cb25
  FUNCTION(gsl_fft_halfcomplex_wavetable,free) (hcw);
Packit 67cb25
Packit 67cb25
  free(real_data) ;
Packit 67cb25
  free(complex_data) ;
Packit 67cb25
  free(complex_tmp) ;
Packit 67cb25
  free(fft_complex_data) ;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
void 
Packit 67cb25
FUNCTION(test_real,bitreverse_order) (size_t stride, size_t n) 
Packit 67cb25
{
Packit 67cb25
  int status ;
Packit 67cb25
  size_t logn, i ;
Packit 67cb25
Packit 67cb25
  BASE * tmp = (BASE *) malloc (n * stride * sizeof (BASE));
Packit 67cb25
  BASE * data = (BASE *) malloc (n * stride * sizeof (BASE));
Packit 67cb25
  BASE * reversed_data = (BASE *) malloc (n * stride * sizeof (BASE));
Packit 67cb25
  
Packit 67cb25
  for (i = 0; i <  stride * n; i++) 
Packit 67cb25
    {
Packit 67cb25
      data[i] = (BASE)i ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  memcpy (tmp, data, n * stride * sizeof(BASE)) ;
Packit 67cb25
Packit 67cb25
  logn = 0 ;  while (n > (1U <
Packit 67cb25
Packit 67cb25
  /* do a naive bit reversal as a baseline for testing the other routines */
Packit 67cb25
Packit 67cb25
  for (i = 0; i < n; i++) 
Packit 67cb25
    {
Packit 67cb25
      size_t i_tmp = i ;
Packit 67cb25
      size_t j = 0 ;
Packit 67cb25
      size_t bit ;
Packit 67cb25
Packit 67cb25
      for (bit = 0; bit < logn; bit++)
Packit 67cb25
        {
Packit 67cb25
          j <<= 1;              /* reverse shift i into j */
Packit 67cb25
          j |= i_tmp & 1;
Packit 67cb25
          i_tmp >>= 1;
Packit 67cb25
        }
Packit 67cb25
Packit 67cb25
      reversed_data[j*stride] = data[i*stride] ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  FUNCTION(fft_real,bitreverse_order) (data, stride, n, logn);
Packit 67cb25
Packit 67cb25
  status = FUNCTION(compare_real,results) ("naive bit reverse", 
Packit 67cb25
                                           reversed_data,
Packit 67cb25
                                           "fft_complex_bitreverse_order", 
Packit 67cb25
                                           data,
Packit 67cb25
                                           stride, n, 1e6);
Packit 67cb25
Packit 67cb25
  gsl_test (status, NAME(fft_real) "_bitreverse_order, n = %d", n);
Packit 67cb25
Packit 67cb25
  free (reversed_data) ;
Packit 67cb25
  free (data) ;
Packit 67cb25
  free (tmp) ;
Packit 67cb25
}
Packit 67cb25
Packit 67cb25
Packit 67cb25
void FUNCTION(test_real,radix2) (size_t stride, size_t n) 
Packit 67cb25
{
Packit 67cb25
  size_t i ;
Packit 67cb25
  int status ;
Packit 67cb25
Packit 67cb25
  BASE * real_data = (BASE *) malloc (n * stride * sizeof (BASE));
Packit 67cb25
  BASE * complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
  BASE * complex_tmp = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
  BASE * fft_complex_data = (BASE *) malloc (2 * n * stride * sizeof (BASE));
Packit 67cb25
Packit 67cb25
  for (i = 0 ; i < n * stride ; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i] = (BASE)i ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  for (i = 0 ; i < 2 * n * stride ; i++)
Packit 67cb25
    {
Packit 67cb25
      complex_data[i] = (BASE)(i + 1000.0) ;
Packit 67cb25
      complex_tmp[i] = (BASE)(i + 2000.0) ;
Packit 67cb25
      fft_complex_data[i] = (BASE)(i + 3000.0) ;
Packit 67cb25
    }
Packit 67cb25
Packit 67cb25
  gsl_set_error_handler (NULL); /* abort on any errors */
Packit 67cb25
  
Packit 67cb25
  /* radix-2 real fft */
Packit 67cb25
  
Packit 67cb25
  FUNCTION(fft_signal,real_noise) (n, stride, complex_data, fft_complex_data);
Packit 67cb25
  memcpy (complex_tmp, complex_data, 2 * n * stride * sizeof (BASE));
Packit 67cb25
Packit 67cb25
  for (i = 0; i < n; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i*stride] = REAL(complex_data,stride,i);
Packit 67cb25
    }
Packit 67cb25
  
Packit 67cb25
  FUNCTION(gsl_fft_real,radix2_transform) (real_data, stride, n);
Packit 67cb25
  FUNCTION(gsl_fft_halfcomplex,radix2_unpack) (real_data, complex_data, stride, n);
Packit 67cb25
  
Packit 67cb25
  status = FUNCTION(compare_complex,results) ("dft", fft_complex_data,
Packit 67cb25
                                              "fft of noise", complex_data,
Packit 67cb25
                                              stride, n, 1e6);
Packit 67cb25
  gsl_test (status, NAME(gsl_fft_real) 
Packit 67cb25
            "_radix2 with signal_real_noise, n = %d, stride = %d", n, stride);
Packit 67cb25
  
Packit 67cb25
  /* compute the inverse fft */
Packit 67cb25
  
Packit 67cb25
  status = FUNCTION(gsl_fft_halfcomplex,radix2_transform) (real_data, stride, n);
Packit 67cb25
  
Packit 67cb25
  for (i = 0; i < n; i++)
Packit 67cb25
    {
Packit 67cb25
      real_data[i*stride] /= n;
Packit 67cb25
    }
Packit 67cb25
  
Packit 67cb25
  FUNCTION(gsl_fft_real,unpack) (real_data, complex_data, stride, n);
Packit 67cb25
  
Packit 67cb25
  status = FUNCTION(compare_complex,results) ("orig", complex_tmp,
Packit 67cb25
                                              "fft inverse", complex_data,
Packit 67cb25
                                              stride, n, 1e6);
Packit 67cb25
Packit 67cb25
  gsl_test (status, NAME(gsl_fft_halfcomplex) 
Packit 67cb25
            "_radix2 with data from signal_noise, n = %d, stride = %d", n, stride);
Packit 67cb25
Packit 67cb25
Packit 67cb25
  free(real_data) ;
Packit 67cb25
  free(complex_data) ;
Packit 67cb25
  free(complex_tmp) ;
Packit 67cb25
  free(fft_complex_data) ;
Packit 67cb25
}