// -*- C++ -*-
// automatically generated by autodoc

// ========== HEADER FILE src/convolution/complexconvolution.h: ==========

// Complex convolution:
// ----- SRCFILE=src/convolution/fftcocnvl.cc: -----
// tuning parameter:
#define  USE_SPLRX  0  // whether split-radix DIF/DIT FFTs are used (default=0)
#if ( USE_SPLRX==1 )
//#warning 'FYI: complex_(auto)_convolution() use split-radix FFTs'
#define  DIT_FFT_CORE  split_radix_fft_dit_core  // isign = -1
#define  DIF_FFT_CORE  split_radix_fft_dif_core  // isign = +1
#else
//#warning 'FYI: complex_(auto)_convolution() use radix-4 FFTs'
#define  DIT_FFT_CORE  fft_dit4_core_m1  // isign = -1
#define  DIF_FFT_CORE  fft_dif4_core_p1  // isign = +1
#endif

void fft_complex_auto_convolution(Complex *f, ulong ldn,
                             double v/*=0.0*/);
// (complex, cyclic) self-convolution:  f[] :=  f[] (*) f[]
// Use zero padded data for linear convolution.
// ldn := base-2 logarithm of the array length.
// Supply a value for v if the normalization factor
//   shall differ from 1/n

void fft_complex_convolution(Complex * restrict f, Complex * restrict g,
                        ulong ldn, double v/*=0.0*/);
// (complex, cyclic) convolution:  g[] :=  f[] (*) g[]
// Use zero padded data for usual convolution.
// ldn := base-2 logarithm of the array length.
// Supply a value for v if the normalization factor
//   shall differ from 1/n

void fft_complex_auto_convolution(double * restrict fr, double * restrict fi,
                             ulong ldn, double v/*=0.0*/);
// (complex, cyclic) self-convolution:  (fr,fi)[] :=  (fr,fi)[] (*) (fr,fi)[]
// Use zero padded data for linear convolution.
// ldn := base-2 logarithm of the array length.
// Supply a value for v if the normalization factor
//   shall differ from 1/n

void fft_complex_convolution(double * restrict fr, double * restrict fi,
                        double * restrict gr, double * restrict gi,
                        ulong ldn, double v/*=0.0*/);
// (complex, cyclic) convolution:  (gr,gi)[] :=  (fr,fi)[] (*) (gr,gi)[]
// Use zero padded data for usual convolution.
// ldn := base-2 logarithm of the array length.
// Supply a value for v if the normalization factor
//   shall differ from 1/n

// ----- SRCFILE=src/convolution/matrixfftcocnvla.cc: -----
// tuning parameter:
#define  USE_OLD_ALGORITHM    0  // 0 (default, revbin_permute for transpose)  or 1
#define  USE_SPLRX  0  // whether split-radix DIF/DIT FFTs are used (default=0)
//
#if  ( USE_OLD_ALGORITHM==1 )
//#warning "FYI: using simple algorithm for matrix_fft_auto_convolution(Complex *f, ...)"
#else  // USE_OLD_ALGORITHM
//#warning "FYI: using revbin_permute for transpose for matrix_fft_auto_convolution(Complex *f, ...)"
#if  ( USE_SPLRX==1 )
//#warning 'FYI: matrix_fft_complex_auto_convolution() uses split-radix FFTs'
#define  DIT_FFT_CORE  split_radix_fft_dit_core  // isign = -1
#define  DIF_FFT_CORE  split_radix_fft_dif_core  // isign = +1
#else
//#warning 'FYI: matrix_fft_complex_auto_convolution() uses radix-4 FFTs'
#define  DIT_FFT_CORE  fft_dit4_core_m1  // isign = -1
#define  DIF_FFT_CORE  fft_dif4_core_p1  // isign = +1
#endif
#endif  // USE_OLD_ALGORITHM

void matrix_fft_auto_convolution(Complex *f, ulong ldn);
// (complex, cyclic) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void matrix_fft_auto_convolution0(Complex *f, ulong ldn);
// (complex, linear) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// Input data must be zero padded:  f[n/2] .. f[n-1] == 0
// n = 2**ldn,  must be >=2

void matrix_fft_auto_convolution(Complex *f, ulong nr, ulong nc, int zp/*=0*/);
// Auxiliary routine for complex self-convolutions via matrix FFT.
// Call with zp==1 if high half of data is zero (for linear convolution).

void matrix_fft_complex_auto_convolution(double *fr, double *fi, ulong ldn);
// (complex, cyclic) self-convolution:  (fr,fi)[] :=  (fr,fi)[] (*) (fr,fi)[]
// ldn := base-2 logarithm of the array length.

void matrix_fft_complex_auto_convolution0(double *fr, double *fi, ulong ldn);
// (complex, linear) self-convolution:  (fr,fi)[] :=  (fr,fi)[] (*0) (fr,fi)[]
// ldn := base-2 logarithm of the array length.
// Input data must be zero padded:  f[n/2] .. f[n-1] == 0
// n = 2**ldn,  must be >=2

void matrix_fft_complex_auto_convolution(double *fr, double *fi, ulong nr, ulong nc, int zp/*=0*/);
// Auxiliary routine for the computation of complex convolutions via matrix FFT.
// Call with zp==1 if high half of data is zero (for linear convolution)

// ----- SRCFILE=src/convolution/cfhtcnvlcore.cc: -----
void fht_convolution_core(const Complex * restrict f, Complex * restrict g, ulong ldn,
                     double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
//   via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length.
// v!=0.0 chooses alternative normalization.

void fht_convolution_revbin_permuted_core(const Complex * restrict f,
                                     Complex * restrict g,
                                     ulong ldn,
                                     double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
//   via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length.
// v!=0.0 chooses alternative normalization.
// Same as fht_convolution_core() but with data access in revbin order.
// This version avoids calls to revbin_permute().
// Same as:
//    revbin_permute(f, n);
//    revbin_permute(g, n);
//    fht_convolution_core(f, g, ldn);
//    revbin_permute(g, n);

// ----- SRCFILE=src/convolution/cfhtcnvlacore.cc: -----
void fht_auto_convolution_core(Complex *f, ulong ldn,
                          double v/*=0.0*/); // aux
// Auxiliary routine for the computation of self-convolutions
// via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length
// v!=0.0 chooses alternative normalization

void fht_auto_convolution_revbin_permuted_core(Complex *f, ulong ldn,
                                          double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
// via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length
// v!=0.0 chooses alternative normalization
// Same as fht_auto_convolution_core() but with data access in revbin order.
// This version avoids two calls to revbin_permute().

// ----- SRCFILE=src/convolution/cfhtcnvl.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE  // default: yes
#ifdef  USE_REVBIN_CORE
//#warning 'FYI: fht_convolution(double *, ulong) using revbin_permuted_core'
#else
#warning 'fht_convolution(Complex *, ulong) using normal core'
#endif

void fht_convolution(Complex * restrict f, Complex * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length

void fht_convolution0(Complex * restrict f, Complex * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

// ----- SRCFILE=src/convolution/cfhtcnvla.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE
//
#ifdef  USE_REVBIN_CORE
//#warning 'FYI: fht_auto_convolution(double *, ulong) using revbin_permuted_core'
#else
#warning 'fht_auto_convolution(Complex *, ulong) using normal core'
#endif

void fht_auto_convolution(Complex *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void fht_auto_convolution0(Complex *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// version for zero padded data:
//   f[k] == 0 for k=n/2 ... n-1
// n = 2**ldn  must be >=2

// ========== HEADER FILE src/convolution/fhtmulsqr.h: ==========

// Auxiliary routines for FHT based convolutions.
static inline  void fht_sqr(Type &xi, Type &xj, double v);
// xi <-- v*( 2*xi*xj + xi*xi - xj*xj )
// xj <-- v*( 2*xi*xj - xi*xi + xj*xj )

static inline  void fht_mul(Type xi, Type xj, Type &yi, Type &yj, double v);
// yi <-- v*( (yi + yj)*xi + (yi - yj)*xj )   == v*( (xi + xj)*yi + (xi - xj)*yj )
// yj <-- v*( (-yi + yj)*xi + (yi + yj)*xj )  == v*( (-xi + xj)*yi + (xi + xj)*yj )

// ========== HEADER FILE src/convolution/realconvolution.h: ==========

// REAL CONVOLUTION
// ----- SRCFILE=src/convolution/fhtcnvlcore.cc: -----
void fht_convolution_core(const double * restrict f, double * restrict g, ulong ldn,
                     double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
//   via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length.
// v!=0.0 chooses alternative normalization.

void fht_convolution_revbin_permuted_core(const double * restrict f,
                                     double * restrict g,
                                     ulong ldn,
                                     double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
//   via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length.
// v!=0.0 chooses alternative normalization.
// Same as fht_convolution_core() but with data access in revbin order.
// This version avoids calls to revbin_permute().
// Same as:
//    revbin_permute(f, n);
//    revbin_permute(g, n);
//    fht_convolution_core(f, g, ldn);
//    revbin_permute(g, n);

// ----- SRCFILE=src/convolution/fhtcnvlacore.cc: -----
void fht_auto_convolution_core(double *f, ulong ldn,
                          double v/*=0.0*/); // aux
// Auxiliary routine for the computation of self-convolutions
// via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length
// v!=0.0 chooses alternative normalization

void fht_auto_convolution_revbin_permuted_core(double *f, ulong ldn,
                                          double v/*=0.0*/); // aux
// Auxiliary routine for the computation of convolutions
// via Fast Hartley Transforms.
// ldn := base-2 logarithm of the array length
// v!=0.0 chooses alternative normalization
// Same as fht_auto_convolution_core() but with data access in revbin order.
// This version avoids two calls to revbin_permute().

// ----- SRCFILE=src/convolution/fhtcnvl.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE  // default: yes
#ifdef  USE_REVBIN_CORE
//#warning 'FYI: fht_convolution(double *, ulong) using revbin_permuted_core'
#else
#warning 'fht_convolution(double *, ulong) using normal core'
#endif

void fht_convolution(double * restrict f, double * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length

void fht_convolution0(double * restrict f, double * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

// ----- SRCFILE=src/convolution/fhtcnvla.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE
//
#ifdef  USE_REVBIN_CORE
//#warning 'FYI: fht_auto_convolution(double *, ulong) using revbin_permuted_core'
#else
#warning 'fht_auto_convolution(double *, ulong) using normal core'
#endif

void fht_auto_convolution(double *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void fht_auto_convolution0(double *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// version for zero padded data:
//   f[k] == 0 for k=n/2 ... n-1
// n = 2**ldn  must be >=2

// ----- SRCFILE=src/convolution/fhtloccnvl.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE  // default: yes
#define  ZP_USE_REVBIN_CORE  // default: yes

void loc_fht_convolution(double * restrict f, double * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length

void loc_fht_convolution0(double * restrict f, double * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

// ----- SRCFILE=src/convolution/fhtloccnvla.cc: -----
// tuning parameter:
#define  USE_REVBIN_CORE  // default: yes
#define  ZP_USE_REVBIN_CORE  // default: yes

void loc_fht_auto_convolution(double *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void loc_fht_auto_convolution0(double *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// version for zero padded data:
//   f[k] == 0 for k=n/2 ... n-1
// n = 2**ldn  must be >=2

// ----- SRCFILE=src/convolution/fftcnvl.cc: -----
void fht_fft_convolution(double * restrict f, double * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length

void split_radix_fft_convolution(double * restrict f, double * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// n = 2**ldn  must be >=2

void fht_fft_convolution0(double * restrict f, double * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

void split_radix_fft_convolution0(double * restrict f, double * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

void fft_convolution_core1(const double * restrict f, double * restrict g,
                      ulong ldn, double v/*=0.0*/); // aux
// Auxiliary routine for FFT based convolutions.
// Supply a value for v for a normalization factor != 1/n

void fft_convolution_core2(const double * restrict f, double * restrict g,
                      ulong ldn, double v/*=0.0*/); // aux
// Auxiliary routine for FFT based convolutions.
// Supply a value for v for a normalization factor != 1/n

// ----- SRCFILE=src/convolution/fftcnvla.cc: -----
void fht_fft_auto_convolution(double *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void split_radix_fft_auto_convolution(double *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void fht_fft_auto_convolution0(double *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded: f[n/2] .. f[n-1] == 0
// n = 2**ldn  must be >=2

void split_radix_fft_auto_convolution0(double *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded: f[n/2] .. f[n-1] == 0
// n = 2**ldn  must be >=2

void fft_auto_convolution_core1(double *f, ulong ldn, double v/*=0.0*/); // aux
// auxiliary routine for FFT based (real) self-convolutions
// supply a value for v for a normalization factor != 1/n

void fft_auto_convolution_core2(double *f, ulong ldn, double v/*=0.0*/); // aux
// auxiliary routine for FFT based (real) self-convolutions
// supply a value for v for a normalization factor != 1/n

// ----- SRCFILE=src/convolution/twodimfhtcnvl.cc: -----
inline void fht_cnvl_core_core(const double *fp, const double *fm, double *gp, double *gm); // aux
// auxiliary routine for twodim_fht_convolution_core()

void twodim_fht_convolution_core(const double *f, double *g, ulong nr, ulong nc); // aux
// convolution core for 2dim convolution using FHT
// nr := number of rows
// nc := number of columns

// ----- SRCFILE=src/convolution/matrixfftcnvla.cc: -----
void matrix_fft_auto_convolution(double *f, ulong ldn);
// (cyclic, real) self-convolution:  f[] :=  f[] (*) f[]
// ldn := base-2 logarithm of the array length

void matrix_fft_auto_convolution0(double *f, ulong ldn);
// (linear, real) self-convolution:  f[] :=  f[] (*0) f[]
// ldn := base-2 logarithm of the array length
// version for zero padded data:
//   f[k] == 0 for k=n/2 ... n-1
// n = 2**ldn  must be >=2

// tuning parameter, define to use scratch space:
#define  CP_ROWS  // default on, avoids cache problems

void matrix_fft_auto_convolution(double *f, ulong nr, ulong nc, int zp/*=0*/);
// auxiliary routine for real self-convolutions via matrix FFT
// call with zp==1 if high half of data is zero (for linear convolution)

// ----- SRCFILE=src/convolution/matrixfftcnvl.cc: -----
void matrix_fft_convolution(double * restrict f, double * restrict g, ulong ldn);
// (cyclic, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length

void matrix_fft_convolution0(double * restrict f, double * restrict g, ulong ldn);
// (linear, real) convolution:  g[] :=  f[] (*) g[]
// ldn := base-2 logarithm of the array length
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n = 2**ldn  must be >=2

// tuning parameter:
#define  CP_ROWS  1  // 0 or 1 (use scratch space, default)

void matrix_fft_convolution(double * restrict f, double * restrict g,
                       ulong nr, ulong nc, int zp/*=0*/);
// auxiliary routine for real convolutions via matrix FFT
// call with zp==1 if high half of data is zero (for linear convolution)

// ========== HEADER FILE src/convolution/slowcnvl-lin.h: ==========

void slow_linear_convolution(const Type *f, const Type *g, Type *h, ulong n);
// Linear (acyclic) convolution.
// n := array length of a[] and b[]
// The array h[] must have 2*n elements.

// ========== HEADER FILE src/convolution/slowcnvl.h: ==========

void slow_convolution(const Type *f, const Type *g, Type *h, ulong n);
// (cyclic) convolution:  h[] :=  f[] (*) g[]
// n := array length

void slow_auto_convolution(const Type *f, Type *g, ulong n);
// (cyclic) convolution:  g[] :=  f[] (*) g[]
// n := array length

void slow_convolution(const Type *f, Type *g, ulong n);
// (cyclic) convolution:  g[] :=  f[] (*) g[]
// n := array length

void slow_auto_convolution(Type *f, ulong n);
// (cyclic) self-convolution:  f[] :=  f[] (*) f[]
// n := array length

// ========== HEADER FILE src/convolution/slowcnvla.h: ==========

void slow_convolution0(const Type *f, const Type *g, Type *h, ulong n);
// (linear) convolution:  h[] :=  f[] (*0) g[]
// n := array length
// Input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0

void slow_auto_convolution0(const Type *f, Type *g, ulong n);
// (linear) self-convolution:  g[] :=  f[] (*0) g[]
// n := array length
// Input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n  must be >=2

void slow_convolution0(const Type *f, Type *g, ulong n);
// (linear) convolution:  g[] :=  f[] (*0) g[]
// n := array length
//
// input data must be zero padded:
//   f[n/2] .. f[n-1] == 0 and g[n/2] .. g[n-1] == 0
// n  must be >=2

void slow_auto_convolution0(Type *f, ulong n);
// (linear) self-convolution:  g[] :=  f[] (*0) g[]
// n := array length
// Input data must be zero padded:
//   f[n/2] .. f[n-1] == 0
// n  must be >=2

// ========== HEADER FILE src/convolution/slowcnvlhalf.h: ==========

void slow_half_convolution(const Type *f, const Type *g, Type *h, ulong n, int h01);
// Half cyclic convolution.
// Part determined by h01 which must be 0 or 1.
// n := array length

void slow_half_auto_convolution(const Type *f, Type *g, ulong n, int h01);
// Half cyclic self-convolution.
// Part determined by h01 which must be 0 or 1.
// n := array length
// (cyclic) convolution:  g[] :=  f[] (*) g[]
// n := array length

void slow_half_convolution(const Type *f, Type *g, ulong n, int h01);
// Half cyclic convolution.
// Part determined by h01 which must be 0 or 1.
// n := array length

void slow_half_auto_convolution(Type *f, ulong n, int h01);
// Half cyclic self-convolution.
// Part determined by h01 which must be 0 or 1.
// n := array length

// ========== HEADER FILE src/convolution/slowconvolution.h: ==========

// ----- SRCFILE=src/convolution/slowcocnvl.cc: -----
void slow_complex_convolution(const double *fr, const double *fi,
                         double *gr, double *gi, ulong n);
// (cyclic, complex) convolution:  (gr, gi)[] :=  (fr,fi)[] (*) (gr,gi)[]
// (use zero padded data for linear convolution)

void slow_complex_auto_convolution(double *fr, double *fi, ulong n);
// (cyclic, complex) self-convolution:  (fr,fi)[] := (fr,fi)[] (*) (fr,fi)[]
// (use zero padded data for linear convolution)

// ========== HEADER FILE src/convolution/slowtwodimcnvl.h: ==========

void slow_twodim_convolution(const Type *f, const Type *g,;
                             Type * restrict h,
                             ulong nr, ulong nc)
// (cyclic) two-dimensional convolution:  h[][] :=  f[][] (*) g[][]
// nr := number of rows,  nc := number of columns
// Use zero padded data for linear convolution.

void slow_twodim_convolution(const Type *f, Type *g, ulong nr, ulong nc);
// (cyclic) two-dimensional convolution:  g[][] :=  f[][] (*) g[][]
// nr := number of rows,  nc := number of columns
// Use zero padded data for linear convolution.
// f may overlap with g

// ========== HEADER FILE src/convolution/slowweightedcnvl.h: ==========

void slow_weighted_convolution(const Type *f, const Type *g, Type *h, ulong n, Type w);
// Weighted (cyclic) convolution:  h[] :=  f[] (*)_w g[]
// n := array length

void slow_weighted_auto_convolution(const Type *f, Type *g, ulong n);
// Weighted (cyclic) convolution:  g[] :=  f[] (*)_w g[]
// n := array length

void slow_weighted_convolution(const Type *f, Type *g, ulong n);
// Weighted (cyclic) convolution:  g[] :=  f[] (*)_w g[]
// n := array length

void slow_weighted_auto_convolution(Type *f, ulong n);
// Weighted (cyclic) self-convolution:  f[] :=  f[] (*)_w f[]
// n := array length

// ========== HEADER FILE src/convolution/weightedconvolution.h: ==========

// ----- SRCFILE=src/convolution/fhtnegacnvl.cc: -----
void fht_negacyclic_auto_convolution(double *f, ulong ldn, double v/*=0.0*/);
// Negacyclic (real) self-convolution using FHT.
// ldn := base-2 logarithm of the array length.
// v!=0.0 chooses alternative normalization.

void fht_negacyclic_convolution(double * restrict f, double * restrict g, ulong ldn);
// Negacyclic (real) convolution using FHT.
// ldn := base-2 logarithm of the array length.

// ----- SRCFILE=src/convolution/weightedconv.cc: -----
void weighted_complex_auto_convolution(double *fr, double *fi, ulong ldn,
                                  double w, double v/*=0.0*/);
// w = weight:
// +0.25 for right angle convolution (-0.25 negates result in fi[])
// +0.5  for negacyclic  convolution (also -0.5)
// +1.0  for cyclic  convolution (also -1.0)
// v!=0.0 chooses alternative normalization

void negacyclic_complex_auto_convolution(double *fr, double *fi, ulong ldn,
                                    double v/*=0.0*/);
// negacyclic autoconvolution of fr[],fi[]
// v!=0.0 chooses alternative normalization

void right_angle_complex_auto_convolution(double *fr, double *fi, ulong ldn,
                                     double v/*=0.0*/);
// right angle autoconvolution of fr[],fi[]
// useful if fi[] all zero: then the result is the
//   acyclic autoconvolution of fr[]
//   result is in fr[] (index 0,1,...,n-1) and fi[] (index n,...,2*n-1)
// v!=0.0 chooses alternative normalization

void weighted_complex_auto_convolution(Complex *f, ulong ldn, double w, double v/*=0.0*/);
// w = weight:
// +0.25 for right angle convolution (-0.25 negates result in fi[])
// +0.5  for negacyclic  convolution (also -0.5)
// +1.0  for cyclic  convolution (also -1.0)
// v!=0.0 chooses alternative normalization

void negacyclic_complex_auto_convolution(Complex *f, ulong ldn, double v/*=0.0*/);
// negacyclic autoconvolution of f[]
// v!=0.0 chooses alternative normalization

void right_angle_complex_auto_convolution(Complex *f, ulong ldn, double v/*=0.0*/);
// right angle autoconvolution of f[]
// v!=0.0 chooses alternative normalization

