Main Page | Modules | File List | Globals

ls_fft.c

00001 /*
00002  *  This file is part of Healpix_cxx.
00003  *
00004  *  Healpix_cxx is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  Healpix_cxx is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with Healpix_cxx; if not, write to the Free Software
00016  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00017  *
00018  *  For more information about HEALPix, see http://healpix.jpl.nasa.gov
00019  */
00020 
00021 /*
00022  *  Healpix_cxx is being developed at the Max-Planck-Institut fuer Astrophysik
00023  *  and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
00024  *  (DLR).
00025  */
00026 
00027 /*
00028  *  Copyright (C) 2005 Max-Planck-Society
00029  *  \author Martin Reinecke
00030  */
00031 
00032 #include <stdlib.h>
00033 #include <math.h>
00034 #include <string.h>
00035 #include "bluestein.h"
00036 #include "fftpack.h"
00037 #include "ls_fft.h"
00038 
00039 complex_plan make_complex_plan (int length)
00040   {
00041   complex_plan plan = (complex_plan) malloc(sizeof(complex_plan_i));
00042   int pfsum = prime_factor_sum(length);
00043   double comp1 = length*pfsum;
00044   double comp2 = 2*3*length*log(3.*length);
00045   plan->length=length;
00046   plan->bluestein = (comp2<comp1);
00047   if (plan->bluestein)
00048     bluestein_i (length,&(plan->work));
00049   else
00050     {
00051     plan->work=(double *)malloc((4*length+15)*sizeof(double));
00052     cffti(length, plan->work);
00053     }
00054   return plan;
00055   }
00056 
00057 void kill_complex_plan (complex_plan plan)
00058   {
00059   free(plan->work);
00060   free(plan);
00061   }
00062 
00063 void complex_plan_forward (complex_plan plan, double *data)
00064   {
00065   if (plan->bluestein)
00066     bluestein (plan->length, data, plan->work, -1);
00067   else
00068     cfftf (plan->length, data, plan->work);
00069   }
00070 
00071 void complex_plan_backward (complex_plan plan, double *data)
00072   {
00073   if (plan->bluestein)
00074     bluestein (plan->length, data, plan->work, 1);
00075   else
00076     cfftb (plan->length, data, plan->work);
00077   }
00078 
00079 
00080 real_plan make_real_plan (int length)
00081   {
00082   real_plan plan = (real_plan) malloc(sizeof(real_plan_i));
00083   int pfsum = prime_factor_sum(length);
00084   double comp1 = .5*length*pfsum;
00085   double comp2 = 2*3*length*log(3.*length);
00086   plan->length=length;
00087   plan->bluestein = (comp2<comp1);
00088   if (plan->bluestein)
00089     bluestein_i (length,&(plan->work));
00090   else
00091     {
00092     plan->work=(double *)malloc((2*length+15)*sizeof(double));
00093     rffti(length, plan->work);
00094     }
00095   return plan;
00096   }
00097 
00098 void kill_real_plan (real_plan plan)
00099   {
00100   free(plan->work);
00101   free(plan);
00102   }
00103 
00104 void real_plan_forward_fftpack (real_plan plan, double *data)
00105   {
00106   if (plan->bluestein)
00107     {
00108     int m;
00109     int n=plan->length;
00110     double *tmp = (double *)malloc(2*n*sizeof(double));
00111     for (m=0; m<n; ++m)
00112       {
00113       tmp[2*m] = data[m];
00114       tmp[2*m+1] = 0.;
00115       }
00116     bluestein(n,tmp,plan->work,-1);
00117     data[0] = tmp[0];
00118     memcpy (data+1, tmp+2, (n-1)*sizeof(double));
00119     free (tmp);
00120     }
00121   else
00122     rfftf (plan->length, data, plan->work);
00123   }
00124 
00125 static void fftpack2halfcomplex (double *data, int n)
00126   {
00127   int m;
00128   double *tmp = (double *)malloc(n*sizeof(double));
00129   tmp[0]=data[0];
00130   for (m=1; m<(n+1)/2; ++m)
00131     {
00132     tmp[m]=data[2*m-1];
00133     tmp[n-m]=data[2*m];
00134     }
00135   if (!(n&1))
00136     tmp[n/2]=data[n-1];
00137   memcpy (data,tmp,n*sizeof(double));
00138   free(tmp);
00139   }
00140 
00141 static void halfcomplex2fftpack (double *data, int n)
00142   {
00143   int m;
00144   double *tmp = (double *)malloc(n*sizeof(double));
00145   tmp[0]=data[0];
00146   for (m=1; m<(n+1)/2; ++m)
00147     {
00148     tmp[2*m-1]=data[m];
00149     tmp[2*m]=data[n-m];
00150     }
00151   if (!(n&1))
00152     tmp[n-1]=data[n/2];
00153   memcpy (data,tmp,n*sizeof(double));
00154   free(tmp);
00155   }
00156 
00157 void real_plan_forward_fftw (real_plan plan, double *data)
00158   {
00159   real_plan_forward_fftpack (plan, data);
00160   fftpack2halfcomplex (data,plan->length);
00161   }
00162 
00163 void real_plan_backward_fftpack (real_plan plan, double *data)
00164   {
00165   if (plan->bluestein)
00166     {
00167     int m;
00168     int n=plan->length;
00169     double *tmp = (double *)malloc(2*n*sizeof(double));
00170     tmp[0]=data[0];
00171     tmp[1]=0.;
00172     memcpy (tmp+2,data+1, (n-1)*sizeof(double));
00173     if ((n&1)==0) tmp[n+1]=0.;
00174     for (m=2; m<n; m+=2)
00175       {
00176       tmp[2*n-m]=tmp[m];
00177       tmp[2*n-m+1]=-tmp[m+1];
00178       }
00179     bluestein (n, tmp, plan->work, 1);
00180     for (m=0; m<n; ++m)
00181       data[m] = tmp[2*m];
00182     free (tmp);
00183     }
00184   else
00185     rfftb (plan->length, data, plan->work);
00186   }
00187 
00188 void real_plan_backward_fftw (real_plan plan, double *data)
00189   {
00190   halfcomplex2fftpack (data,plan->length);
00191   real_plan_backward_fftpack (plan, data);
00192   }
00193 
00194 void real_plan_forward_c (real_plan plan, double *data)
00195   {
00196   int m;
00197   int n=plan->length;
00198 
00199   if (plan->bluestein)
00200     {
00201     for (m=1; m<2*n; m+=2)
00202       data[m]=0;
00203     bluestein (plan->length, data, plan->work, -1);
00204     data[1]=0;
00205     for (m=2; m<n; m+=2)
00206       {
00207       double avg;
00208       avg = 0.5*(data[2*n-m]+data[m]);
00209       data[2*n-m] = data[m] = avg;
00210       avg = 0.5*(data[2*n-m+1]-data[m+1]);
00211       data[2*n-m+1] = avg;
00212       data[m+1] = -avg;
00213       }
00214     if ((n&1)==0) data[n+1] = 0.;
00215     }
00216   else
00217     {
00218     for (m=0; m<n; ++m) data[m+1] = data[2*m];
00219     rfftf (n, data+1, plan->work);
00220     data[0] = data[1];
00221     data[1] = 0;
00222     for (m=2; m<n; m+=2)
00223       {
00224       data[2*n-m]   =  data[m];
00225       data[2*n-m+1] = -data[m+1];
00226       }
00227     if ((n&1)==0) data[n+1] = 0.;
00228     }
00229   }
00230 
00231 void real_plan_backward_c (real_plan plan, double *data)
00232   {
00233   int m;
00234   int n=plan->length;
00235 
00236   if (plan->bluestein)
00237     {
00238     data[1]=0;
00239     for (m=2; m<n; m+=2)
00240       {
00241       double avg;
00242       avg = 0.5*(data[2*n-m]+data[m]);
00243       data[2*n-m] = data[m] = avg;
00244       avg = 0.5*(data[2*n-m+1]-data[m+1]);
00245       data[2*n-m+1] = avg;
00246       data[m+1] = -avg;
00247       }
00248     if ((n&1)==0) data[n+1] = 0.;
00249     bluestein (plan->length, data, plan->work, 1);
00250     for (m=1; m<2*n; m+=2)
00251       data[m]=0;
00252     }
00253   else
00254     {
00255     data[1] = data[0];
00256     rfftb (n, data+1, plan->work);
00257     for (m=n-1; m>=0; --m)
00258       {
00259       data[2*m]   = data[m+1];
00260       data[2*m+1] = 0.;
00261       }
00262     }
00263   }

Generated on Fri Jul 8 09:37:13 2005 for LevelS FFT library