lasp/fftpack/fftpack.h

112 lines
2.6 KiB
C
Raw Normal View History

2018-01-29 15:14:50 +00:00
// fftpack.h
//
// Author: J.A. de Jong - ASCEE
//
// Description:
// Header file for FFT routines of fftpack
//////////////////////////////////////////////////////////////////////
#pragma once
#ifndef FFTPACK_H
#define FFTPACK_H
#include "ascee_tracer.h"
2018-01-29 15:14:50 +00:00
#include "ascee_alloc.h"
#include "npy_fftpack.h"
/*
* Fortran has two kind of routines: functions and subroutines. A
Fortran function is a C function that returns a single value.
A * subroutine called from C is in fact a C function
which returns void.
*/
#if ASCEE_DOUBLE_PRECISION
// These are all subroutines
extern void dffti_ (int *nfft,d* wsave);
extern void dfftf_ (int *nfft,d* r,d* wsave);
#else
extern void rffti_ (int *nfft,d* wsave);
extern void rfftf_ (int *nfft,d* r,d* wsave);
#endif // ASCEE_DOUBLE_PRECISION
typedef struct Fftr_s {
d *work_area;
d* wsave_ptr;
int nfft;
} Fftr;
/**
*
*
* @param nfft the length of the sequence to be transformed
* @param wsave a work array which must be dimensioned at least
* 2*nfft+15. the same work array can be used for both rfftf and
* rfftb as long as n remains unchanged. different wsave arrays
* are required for different values of n. the contents of wsave
* must not be changed between calls of rfftf or rfftb.
*/
Fftr* Fftr_alloc(int nfft) {
fsTRACE(15);
Fftr* fftr = a_malloc(sizeof(fftr));
dbgassert(nfft>0,"Invalid nfft")
dbgassert(fftr,ALLOCFAILED "Fftr_alloc");
fftr->work_area = a_malloc(sizeof(d)*(3*nfft+15));
fftr->wsave_ptr = &fftr->work_area[nfft];
fftr->nfft = nfft;
#if ASCEE_DOUBLE_PRECISION
// dffti_(&nfft,fftr->wsave);
npy_rffti(nfft,fftr->wsave_ptr);
#else
// rffti_(&nfft,fftr->wsave);
#endif
feTRACE(15);
return fftr;
}
void Fftr_free(Fftr* fftr) {
dbgassert(fftr,NULLPTRDEREF "Fftr_free");
a_free(fftr->work_area);
a_free(fftr);
}
/**
*
*
* @param nfft
* @param wsave
* @param input
* @param work
* @param result
*/
static inline void Fftr_fftr(Fftr* fftr,d* input,c* result) {
// Copy contents of input to the work area
d_copy(fftr->work_area,input,fftr->nfft);
int nfft = fftr->nfft;
#if ASCEE_DOUBLE_PRECISION
// dfftf_(&nfft,fftr->work,fftr->wsave);
npy_rfftf(nfft,fftr->work_area,fftr->wsave_ptr);
#else
NOT TESTED
rfftf_(&nfft,fftr->work_area,fftr->wsave_ptr);
#endif
result[0] = fftr->work_area[0];
d_copy((d*) (&result[1]),&fftr->work_area[1],nfft);
// Not portable way of setting imaginary part to zero. Works with
// gcc, though.
__imag__ result[nfft/2] = 0;
}
#endif // FFTPACK_H
//////////////////////////////////////////////////////////////////////