initial import
This commit is contained in:
commit
2942428e92
53 changed files with 9133 additions and 0 deletions
291
libfftpack/ls_fft.c
Normal file
291
libfftpack/ls_fft.c
Normal file
|
@ -0,0 +1,291 @@
|
|||
/*
|
||||
* This file is part of libfftpack.
|
||||
*
|
||||
* libfftpack is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* libfftpack is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with libfftpack; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* libfftpack is being developed at the Max-Planck-Institut fuer Astrophysik
|
||||
* and financially supported by the Deutsches Zentrum fuer Luft- und Raumfahrt
|
||||
* (DLR).
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Max-Planck-Society
|
||||
* \author Martin Reinecke
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include "bluestein.h"
|
||||
#include "fftpack.h"
|
||||
#include "ls_fft.h"
|
||||
|
||||
complex_plan make_complex_plan (size_t length)
|
||||
{
|
||||
complex_plan plan = RALLOC(complex_plan_i,1);
|
||||
size_t pfsum = prime_factor_sum(length);
|
||||
double comp1 = (double)(length*pfsum);
|
||||
double comp2 = 2*3*length*log(3.*length);
|
||||
comp2*=3.; /* fudge factor that appears to give good overall performance */
|
||||
plan->length=length;
|
||||
plan->bluestein = (comp2<comp1);
|
||||
if (plan->bluestein)
|
||||
bluestein_i (length,&(plan->work),&(plan->worksize));
|
||||
else
|
||||
{
|
||||
plan->worksize=4*length+15;
|
||||
plan->work=RALLOC(double,4*length+15);
|
||||
cffti(length, plan->work);
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
complex_plan copy_complex_plan (complex_plan plan)
|
||||
{
|
||||
if (!plan) return NULL;
|
||||
{
|
||||
complex_plan newplan = RALLOC(complex_plan_i,1);
|
||||
*newplan = *plan;
|
||||
newplan->work=RALLOC(double,newplan->worksize);
|
||||
memcpy(newplan->work,plan->work,sizeof(double)*newplan->worksize);
|
||||
return newplan;
|
||||
}
|
||||
}
|
||||
|
||||
void kill_complex_plan (complex_plan plan)
|
||||
{
|
||||
DEALLOC(plan->work);
|
||||
DEALLOC(plan);
|
||||
}
|
||||
|
||||
void complex_plan_forward (complex_plan plan, double *data)
|
||||
{
|
||||
if (plan->bluestein)
|
||||
bluestein (plan->length, data, plan->work, -1);
|
||||
else
|
||||
cfftf (plan->length, data, plan->work);
|
||||
}
|
||||
|
||||
void complex_plan_backward (complex_plan plan, double *data)
|
||||
{
|
||||
if (plan->bluestein)
|
||||
bluestein (plan->length, data, plan->work, 1);
|
||||
else
|
||||
cfftb (plan->length, data, plan->work);
|
||||
}
|
||||
|
||||
|
||||
real_plan make_real_plan (size_t length)
|
||||
{
|
||||
real_plan plan = RALLOC(real_plan_i,1);
|
||||
size_t pfsum = prime_factor_sum(length);
|
||||
double comp1 = .5*length*pfsum;
|
||||
double comp2 = 2*3*length*log(3.*length);
|
||||
comp2*=3; /* fudge factor that appears to give good overall performance */
|
||||
plan->length=length;
|
||||
plan->bluestein = (comp2<comp1);
|
||||
if (plan->bluestein)
|
||||
bluestein_i (length,&(plan->work),&(plan->worksize));
|
||||
else
|
||||
{
|
||||
plan->worksize=2*length+15;
|
||||
plan->work=RALLOC(double,2*length+15);
|
||||
rffti(length, plan->work);
|
||||
}
|
||||
return plan;
|
||||
}
|
||||
|
||||
real_plan copy_real_plan (real_plan plan)
|
||||
{
|
||||
if (!plan) return NULL;
|
||||
{
|
||||
real_plan newplan = RALLOC(real_plan_i,1);
|
||||
*newplan = *plan;
|
||||
newplan->work=RALLOC(double,newplan->worksize);
|
||||
memcpy(newplan->work,plan->work,sizeof(double)*newplan->worksize);
|
||||
return newplan;
|
||||
}
|
||||
}
|
||||
|
||||
void kill_real_plan (real_plan plan)
|
||||
{
|
||||
DEALLOC(plan->work);
|
||||
DEALLOC(plan);
|
||||
}
|
||||
|
||||
void real_plan_forward_fftpack (real_plan plan, double *data)
|
||||
{
|
||||
if (plan->bluestein)
|
||||
{
|
||||
size_t m;
|
||||
size_t n=plan->length;
|
||||
double *tmp = RALLOC(double,2*n);
|
||||
for (m=0; m<n; ++m)
|
||||
{
|
||||
tmp[2*m] = data[m];
|
||||
tmp[2*m+1] = 0.;
|
||||
}
|
||||
bluestein(n,tmp,plan->work,-1);
|
||||
data[0] = tmp[0];
|
||||
memcpy (data+1, tmp+2, (n-1)*sizeof(double));
|
||||
DEALLOC(tmp);
|
||||
}
|
||||
else
|
||||
rfftf (plan->length, data, plan->work);
|
||||
}
|
||||
|
||||
static void fftpack2halfcomplex (double *data, size_t n)
|
||||
{
|
||||
size_t m;
|
||||
double *tmp = RALLOC(double,n);
|
||||
tmp[0]=data[0];
|
||||
for (m=1; m<(n+1)/2; ++m)
|
||||
{
|
||||
tmp[m]=data[2*m-1];
|
||||
tmp[n-m]=data[2*m];
|
||||
}
|
||||
if (!(n&1))
|
||||
tmp[n/2]=data[n-1];
|
||||
memcpy (data,tmp,n*sizeof(double));
|
||||
DEALLOC(tmp);
|
||||
}
|
||||
|
||||
static void halfcomplex2fftpack (double *data, size_t n)
|
||||
{
|
||||
size_t m;
|
||||
double *tmp = RALLOC(double,n);
|
||||
tmp[0]=data[0];
|
||||
for (m=1; m<(n+1)/2; ++m)
|
||||
{
|
||||
tmp[2*m-1]=data[m];
|
||||
tmp[2*m]=data[n-m];
|
||||
}
|
||||
if (!(n&1))
|
||||
tmp[n-1]=data[n/2];
|
||||
memcpy (data,tmp,n*sizeof(double));
|
||||
DEALLOC(tmp);
|
||||
}
|
||||
|
||||
void real_plan_forward_fftw (real_plan plan, double *data)
|
||||
{
|
||||
real_plan_forward_fftpack (plan, data);
|
||||
fftpack2halfcomplex (data,plan->length);
|
||||
}
|
||||
|
||||
void real_plan_backward_fftpack (real_plan plan, double *data)
|
||||
{
|
||||
if (plan->bluestein)
|
||||
{
|
||||
size_t m;
|
||||
size_t n=plan->length;
|
||||
double *tmp = RALLOC(double,2*n);
|
||||
tmp[0]=data[0];
|
||||
tmp[1]=0.;
|
||||
memcpy (tmp+2,data+1, (n-1)*sizeof(double));
|
||||
if ((n&1)==0) tmp[n+1]=0.;
|
||||
for (m=2; m<n; m+=2)
|
||||
{
|
||||
tmp[2*n-m]=tmp[m];
|
||||
tmp[2*n-m+1]=-tmp[m+1];
|
||||
}
|
||||
bluestein (n, tmp, plan->work, 1);
|
||||
for (m=0; m<n; ++m)
|
||||
data[m] = tmp[2*m];
|
||||
DEALLOC(tmp);
|
||||
}
|
||||
else
|
||||
rfftb (plan->length, data, plan->work);
|
||||
}
|
||||
|
||||
void real_plan_backward_fftw (real_plan plan, double *data)
|
||||
{
|
||||
halfcomplex2fftpack (data,plan->length);
|
||||
real_plan_backward_fftpack (plan, data);
|
||||
}
|
||||
|
||||
void real_plan_forward_c (real_plan plan, double *data)
|
||||
{
|
||||
size_t m;
|
||||
size_t n=plan->length;
|
||||
|
||||
if (plan->bluestein)
|
||||
{
|
||||
for (m=1; m<2*n; m+=2)
|
||||
data[m]=0;
|
||||
bluestein (plan->length, data, plan->work, -1);
|
||||
data[1]=0;
|
||||
for (m=2; m<n; m+=2)
|
||||
{
|
||||
double avg;
|
||||
avg = 0.5*(data[2*n-m]+data[m]);
|
||||
data[2*n-m] = data[m] = avg;
|
||||
avg = 0.5*(data[2*n-m+1]-data[m+1]);
|
||||
data[2*n-m+1] = avg;
|
||||
data[m+1] = -avg;
|
||||
}
|
||||
if ((n&1)==0) data[n+1] = 0.;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* using "m+m" instead of "2*m" to avoid a nasty bug in Intel's compiler */
|
||||
for (m=0; m<n; ++m) data[m+1] = data[m+m];
|
||||
rfftf (n, data+1, plan->work);
|
||||
data[0] = data[1];
|
||||
data[1] = 0;
|
||||
for (m=2; m<n; m+=2)
|
||||
{
|
||||
data[2*n-m] = data[m];
|
||||
data[2*n-m+1] = -data[m+1];
|
||||
}
|
||||
if ((n&1)==0) data[n+1] = 0.;
|
||||
}
|
||||
}
|
||||
|
||||
void real_plan_backward_c (real_plan plan, double *data)
|
||||
{
|
||||
size_t n=plan->length;
|
||||
|
||||
if (plan->bluestein)
|
||||
{
|
||||
size_t m;
|
||||
data[1]=0;
|
||||
for (m=2; m<n; m+=2)
|
||||
{
|
||||
double avg;
|
||||
avg = 0.5*(data[2*n-m]+data[m]);
|
||||
data[2*n-m] = data[m] = avg;
|
||||
avg = 0.5*(data[2*n-m+1]-data[m+1]);
|
||||
data[2*n-m+1] = avg;
|
||||
data[m+1] = -avg;
|
||||
}
|
||||
if ((n&1)==0) data[n+1] = 0.;
|
||||
bluestein (plan->length, data, plan->work, 1);
|
||||
for (m=1; m<2*n; m+=2)
|
||||
data[m]=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptrdiff_t m;
|
||||
data[1] = data[0];
|
||||
rfftb (n, data+1, plan->work);
|
||||
for (m=n-1; m>=0; --m)
|
||||
{
|
||||
data[2*m] = data[m+1];
|
||||
data[2*m+1] = 0.;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue