#if !defined  HAVE_SLOWWEIGHTEDCNVL_H__
#define       HAVE_SLOWWEIGHTEDCNVL_H__


#include "fxttypes.h"
#include "fxtalloca.h"

#include "aux1/copy.h"
#define copy fxtaux::copy // avoid unwanted std::copy

template <typename Type>
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
{
    for (ulong tau=0;  tau<n;  ++tau)
    {
        ulong k = 0;
        Type s0 = 0;
        for (ulong k2=tau;  k<=tau;  ++k, --k2)  s0 += (f[k]*g[k2]);
        Type s1 = 0;
        for (ulong k2=n-1;  k<n;     ++k, --k2)  s1 += (f[k]*g[k2]);  // wrapped around
        h[tau] = s0 + s1*w;
    }
}
// -------------------------

template <typename Type>
void slow_weighted_auto_convolution(const Type *f, Type *g, ulong n)
// Weighted (cyclic) convolution:  g[] :=  f[] (*)_w g[]
// n := array length
{
    slow_weighted_convolution(f, f, g, n);
}
// -------------------------

template <typename Type>
void slow_weighted_convolution(const Type *f, Type *g, ulong n)
// Weighted (cyclic) convolution:  g[] :=  f[] (*)_w g[]
// n := array length
{
    ALLOCA(Type, h, n);
    slow_weighted_convolution(f, g, h, n);
    copy(h, g, n);
}
// -------------------------

template <typename Type>
void slow_weighted_auto_convolution(Type *f, ulong n)
// Weighted (cyclic) self-convolution:  f[] :=  f[] (*)_w f[]
// n := array length
{
    ALLOCA(Type, h, n);
    slow_weighted_convolution(f, f, h, n);
    copy(h, f, n);
}
// -------------------------

#undef copy  // avoid unwanted std::copy


#endif  // !defined HAVE_SLOWWEIGHTEDCNVL_H__
