import config

def fft(int n, complex *x, complex *y):
    """
    Perform y = fft(x). x and y must point to arrays of n complex values.
    n must be a power of 2. x and y may be the same array.
    """

    if n == 1:
        y[0] = x[0]
        return

    assert(n % 2 == 0)

    complex half[n / 2], q[n / 2], r[n / 2]
    # q is fft of even terms
    for int k = 0; k < n / 2; k++: half[k] = x[2 * k]
    fft(n / 2, half, q)
    # r is fft of odd terms
    for int k = 0; k < n / 2; k++: half[k] = x[2 * k + 1]
    fft(n / 2, half, r)

    for int k = 0; k < n / 2; k++:
        double kth = -2 * k * pi / n
        complex wk = cos(kth) + I * sin(kth)
        y[k] = q[k] + wk * r[k]
        y[k + n / 2] = q[k] - wk * r[k]

def ifft(int n, complex *x, complex *y):
    for int i = 0; i < n; i++: y[i] = conj(x[i])
    fft(n, y, y)
    for int i = 0; i < n; i++: y[i] = conj(y[i]) / n
