/* This file was generated by scramble.py. */
#include "wavelets/schneid.h"
#include "scramble.h"
static V _schneid_c_k(int k, int N, V const *alpha)
{
    if (N == 1)
    {
        if (k >= 0 && k <= N)
        {
            return 1.0 / sqrt(2);
        }
        return 0.0;
    }
    V a = _schneid_c_k(k - 2, N - 2, alpha);
    V b = _schneid_c_k(k, N - 2, alpha);
    V c = _schneid_c_k(N - k, N - 2, alpha);
    V d = _schneid_c_k(N - k - 2, N - 2, alpha);
    V e = 1.0;
    if (k & 1)
    {
        e = -1.0;
    }
    return 0.5 * (a + b) + 0.5 * (a - b) * cos(alpha[(N - 1) / 2 - 1]) + 0.5 * (c - d) * e * sin(alpha[(N - 1) / 2 - 1]);
}
void scaling_to_wavelet_coefficients(int n, V *scaling, V *wavelet)
{
    V d = 1.0;
    for (int i = 0; i < n; i++)
    {
        int j = 1 - i;
        if (j < 0)
        {
            j += n;
        }
        wavelet[i] = scaling[j] * d;
        d *= -1.0;
    }
}
static void _filter_recurse(Filter f, int n, V const *alpha)
{
    for (int i = 0; i < f.hn; i++)
    {
        f.h[i] = _schneid_c_k(i, 2 * n + 1, alpha);
    }
    scaling_to_wavelet_coefficients(f.hn, f.h, f.g);
}
Filter * schneid_get_filter(int n, V *alpha)
{
    Filter *f = ALLOCATE0(sizeof *f);
    f->hn = 2 * (n + 1);
    f->gn = 2 * (n + 1);
    f->h = malloc(f->hn * sizeof(V));
    f->g = malloc(f->gn * sizeof(V));
    _filter_recurse(*f, n, alpha);
    return f;
}
void schneid_nosubsample_param(V const *indata, int n, int instep, V *outlow, int lowstep, V *outhigh, int highstep, int scale, int pn, V const *alpha)
{
    Filter f;
    f.hn = f.gn = 2 * (pn + 1);
    /* scaling */
    V h[f.hn];
    /* wavelet */
    V g[f.gn];
    f.h = h;
    f.g = g;
    _filter_recurse(f, pn, alpha);
    filter(indata, n, instep, g, f.gn, outlow, lowstep, 1 << scale);
    filter(indata, n, instep, h, f.hn, outhigh, highstep, 1 << scale);
}
V ** schneid(V const *s, int n, char const *key)
{
    /* 
     * This expects a signal of n samples, and will return (full-length, not
     * downsampled) low and high pass results for each subdivision level.
     * 
     * 0 2 4.../log2(n)\ * 2 - 2 are the low pass results
     * 1 3 5.../log2(n)\ * 2 - 1 the high pass results
     *  */
    int l = ceil(log2(n));;
    V **r = ALLOCATE(l * 2 * sizeof(V *));
    int kn = strlen(key) / 2;
    V *a = malloc(kn * sizeof *a);
    for (int i = 0; i < kn; i++)
    {
        a[i] = ((key[i * 2] - '0') * 10 + key[i * 2 + 1] - '0') / 99.0 * 2 * pi - pi;
    }
    V const *p = s;
    for (int i = 0; i < l; i++)
    {
        r[i * 2] = ALLOCATE(n * sizeof(V));
        r[i * 2 + 1] = ALLOCATE(n * sizeof(V));
        schneid_nosubsample_param(p, n, 1, r[i * 2], 1, r[i * 2 + 1], 1, i, kn, a);
        /* right now, we always use the lowband for further analysis. */
        p = r[i * 2];
    }
    return r;
}
/* This file was generated by scramble.py. */
