// -*- C++ -*-

// ===== FUNCTIONS declared in include/fxt.h: =====
// ... matching "fht"

// ----- SRCFILE=fht/fhtsplitradixdit.cc: -----
void split_radix_dit_fht_core(double *f, ulong ldn); // aux
// fast hartley transform
// split radix decimation in time algorithm
// input data must be in revbin_permuted order

void split_radix_dit_fht(double *f, ulong ldn);
// fast hartley transform
// split radix decimation in time algorithm

// ----- SRCFILE=fht/fhtsplitradixdif.cc: -----
void split_radix_dif_fht_core(double *f, ulong ldn); // aux
// fast hartley transform
// split radix decimation in frequency algorithm
// output data is in revbin_permuted order

void split_radix_dif_fht(double *f, ulong ldn);
// fast hartley transform
// split radix decimation in frequency algorithm

// ----- SRCFILE=fht/cfhtsplitradixdit.cc: -----
void split_radix_dit_fht_core(Complex *f, ulong ldn); // aux
// fast hartley transform
// split radix decimation in time algorithm
// input data must be in revbin_permuted order

void split_radix_dit_fht(Complex *f, ulong ldn);
// fast hartley transform
// split radix decimation in time algorithm

// ----- SRCFILE=fht/cfhtsplitradixdif.cc: -----
void split_radix_dif_fht_core(Complex *f, ulong ldn); // aux
// fast hartley transform
// split radix decimation in frequency algorithm
// output data is in revbin_permuted order

void split_radix_dif_fht(Complex *f, ulong ldn);
// fast hartley transform
// split radix decimation in frequency algorithm

// ----- SRCFILE=fht/fht0.cc: -----
void fht0(double *f, ulong ldn);
// fast hartley transform
// version for zero padded data (i.e. f[n/2]...f[n-1] are zero)
// split radix decimation in time algorithm

// ----- SRCFILE=fht/cfht0.cc: -----
void fht0(Complex *f, ulong ldn);
// fast hartley transform
// version for zero padded data (i.e. f[n/2]...f[n-1] are zero)
// split radix decimation in time algorithm

// ----- SRCFILE=fht/skipfht.cc: -----
void skip_fht(double *f, ulong n, ulong d, double *w);
// compute fht of the n elements
// [0],[d],[2d],[3d],...,[(n-1)*d]

void skip_fht0(double *f, ulong n, ulong d, double *w);
// compute fht of the n elements
// [0],[d],[2d],[3d],...,[(n-1)*d]

// ----- SRCFILE=fht/twodimfht.cc: -----
void row_column_fht(double *f, ulong r, ulong c); // aux
// fht over rows and columns
// this is _not_ a two dimensional fht

void twodim_fht(double *f, ulong r, ulong c);
// two dimensional fast hartley transform

// ----- SRCFILE=fht/twodimfhtcnvl.cc: -----
inline void fht_cnvl_core_core(const double *fp, const double *fm, double *gp, double *gm);

void twodim_fht_convolution_core(const double *f, double *g, ulong r, ulong c);
//   ! UNTESTED !


// ----- SRCFILE=fht/fhtfft.cc: -----
void fht_fft(double *fr, double *fi, ulong ldn, int is);
// fft based on fht

void fht_fft0(double *fr, double *fi, ulong ldn, int is);
// fft based on fht
// version for zero padded data

void fht_fft_pre_processing(double *fr, double *fi, ulong ldn, int is); // aux
// preprocessing to use two length-n fhts
// to compute a length-n complex fft

void fht_fft_post_processing(double *fr, double *fi, ulong ldn, int is); // aux
// postprocessing to use two length-n fhts
// to compute a length-n complex fft

// ----- SRCFILE=fht/fhtcfft.cc: -----
void fht_fft(Complex *f, ulong ldn, int is);
// fft based on fht

void fht_fft0(Complex *f, ulong ldn, int is);
// fft based on fht
// version for zero padded data

void fht_fft_pre_processing(Complex *f, ulong ldn, int is); // aux
// preprocessing to one length-n (complex) fht
// to compute a length-n complex fft

void fht_fft_post_processing(Complex *f, ulong ldn, int is); // aux
// postprocessing to one length-n (complex) fht
// to compute a length-n complex fft

// ----- SRCFILE=realfft/realfftbyfht.cc: -----
void fht_real_complex_fft(double *f, ulong ldn);
// isign = +1
// ordering on output:
// f[0]     = re[0]
// f[1]     = re[1]
// f[n/2-1] = re[n/2-1]
// f[n/2]   = re[n/2](==nyquist freq)
// f[n/2+1] = im[n/2-1]  (wrt. complex fft with is=+1)
// f[n/2+2] = im[n/2-2]
// f[n-1]   = im[1]
// corresponding real and imag parts (with the exception of
// zero and nyquist freq) are found in f[i] and f[n-i]
// note that the order of imaginary parts
// is reversed wrt. fft_real_complex_fft()

void fht_real_complex_fft0(double *f, ulong ldn);
// version for zero padded data
// ordering on output:
// see fht_real_complex_fft()

void fht_complex_real_fft(double *f, ulong ldn);
// isign = +1
// ordering on input:
// like the output of fht_real_complex_fft()

// ----- SRCFILE=fht/fhtcnvl.cc: -----
void fht_convolution(double *x, double *y, ulong ldn);
// y[] = x[] (*) y[]

void fht_convolution0(double *x, double *y, ulong ldn);
// y[] = x[] (*) y[]
// version for zero padded data (i.e. linear convolution)

void fht_convolution_core(double *x, double *y, ulong ldn,
                     double v/*=0.0*/); // aux
// v!=0.0 chooses alternative normalization

void fht_convolution_revbin_permuted_core(double *f, double *g, ulong ldn,
                               double v/*=0.0*/); // aux
// as fht_convolution_core() with data access in revbin order

// ----- SRCFILE=fht/fhtcnvla.cc: -----
void fht_auto_convolution(double *x, ulong ldn);
// y[] = x[] (*) x[]

void fht_auto_convolution0(double *x, ulong ldn);
// y[] = x[] (*) x[]
// version for zero padded data (i.e. linear convolution)

void fht_auto_convolution_core(double *x, ulong ldn,
                          double v/*=0.0*/); // aux
// v!=0.0 chooses alternative normalization

void fht_auto_convolution_revbin_permuted_core(double *f, ulong ldn,
                                    double v/*=0.0*/); // aux
// as above with data access in revbin order

// ----- SRCFILE=fht/fhtnegacnvla.cc: -----
void fht_negacyclic_auto_convolution(double *x, ulong ldn, double v/*=0.0*/);
// v!=0.0 chooses alternative normalization

void fht_negacyclic_auto_convolution_core(double *x, ulong ldn, double v/*=0.0*/); // aux
// v!=0.0 chooses alternative normalization

// ----- SRCFILE=fft/fftcnvl.cc: -----
void fht_fft_convolution(double *f, double *g, ulong ldn);
// g[] = f[] (*) g[]

void fht_fft_convolution0(double *f, double *g, ulong ldn);
// g[] = f[] (*) g[]

// ----- SRCFILE=fft/fftcnvla.cc: -----
void fht_fft_auto_convolution(double *f, ulong ldn);
// f[] = f[] (*) f[]

void fht_fft_auto_convolution0(double *f, ulong ldn);
// f[] = f[] (*) f[]

// ----- SRCFILE=fht/fhtcorr.cc: -----
void fht_correlation0(double *f, double *g, ulong ldn);
// result in g

void fht_auto_correlation0(double *f, ulong ldn);

// ----- SRCFILE=fht/cfhtcnvl.cc: -----
void fht_convolution(Complex *x, Complex *y, ulong ldn);
// y[] = x[] (*) y[]

void fht_convolution0(Complex *x, Complex *y, ulong ldn);
// y[] = x[] (*) y[]
// version for zero padded data (i.e. linear convolution)

void fht_convolution_core(Complex *x, Complex *y, ulong ldn,
                     double v/*=0.0*/); // aux
// v!=0.0 chooses alternative normalization

void fht_convolution_revbin_permuted_core(Complex *f, Complex *g, ulong ldn,
                               double v/*=0.0*/); // aux
// as fht_convolution_core() with data access in revbin order

// ----- SRCFILE=fht/cfhtcnvla.cc: -----
void fht_auto_convolution(Complex *x, ulong ldn);
// y[] = x[] (*) x[]

void fht_auto_convolution0(Complex *x, ulong ldn);
// y[] = x[] (*) x[]
// version for zero padded data (i.e. linear convolution)

void fht_auto_convolution_core(Complex *x, ulong ldn,
                          double v/*=0.0*/); // aux
// v!=0.0 chooses alternative normalization

void fht_auto_convolution_revbin_permuted_core(Complex *f, ulong ldn,
                                    double v/*=0.0*/); // aux
// as above with data access in revbin order

// ----- SRCFILE=fht/fhtspect.cc: -----
void  fht_spectrum(double *f, ulong ldn, int phasesq/*=0*/);
// power_spectrum computed with fht
// phasesq != 0  requests computation of phases
// phase[i] is in f[n-1]  (i=1...n/2-1)
// phase[0] == 0,  phase[n/2] == 0
// output is not normalized


// ----- SRCFILE=learn/fhtdit2.cc: -----
void dit2_fht_localized(double *f, ulong ldn);
// decimation in time radix 2 fht
// depth-first version
// compared to usual fht this one
// - does more trig computations
// - is (far) better memory local

// ----- SRCFILE=learn/fhtdif2.cc: -----
void dif2_fht_localized(double *f, ulong ldn);
// decimation in frequency radix 2 fht
// depth-first version
// compared to usual fht this one
// - does more trig computations
// - is (far) better memory local

// ----- SRCFILE=learn/recfhtdit2.cc: -----
static void evenodd_permute(const double *a, double *ev, double *od, ulong n);

static void recursive_dit2_fht_core(const double *a, ulong n, double *x);

void recursive_dit2_fht(double *a, ulong ldn);
// very inefficient, just here to demonstrate the
// recursive fast hartley transform

// ----- SRCFILE=learn/recfhtdif2.cc: -----
static void leftright(const double *a, double *le, double *ri, ulong n);

static void recursive_dif2_fht_core(const double *a, ulong n, double *x);

void recursive_dif2_fht(double *a, ulong ldn);
// very inefficient, just here to demonstrate the
// recursive fast hartley transform

inline void fht(double *f, ulong ldn);

inline void fht(Complex *f, ulong ldn);

