complex numbers – Inverse FFT at non-integer points

I’m running into something confusing. I have this python code that does an FFT of a real signal, and then reconstructs it by manually summing the complex exponentials:

import numpy as np

original_signal = np.array([1, -4, 5, 3, 2, -1, 0, 7])


def fft_components(values):
    # Perform FFT
    fft_result = np.fft.fft(values)
    n = len(values)  # Number of sample points
    freq = np.fft.fftfreq(n)  # Frequencies
    
    # Calculate magnitude and phase
    magnitude = np.abs(fft_result) / n  # divide by n to normalize
    phase = np.angle(fft_result)
    
    # Combine frequency, magnitude, and phase into tuples
    components = list(zip(freq, magnitude, phase))
    
    return components

# Example usage
sines = fft_components(original_signal)


def get_sin_sum(components, t):
    # Corrected: Include phase in the reconstruction and use correct formula
    return sum(
        mag * np.exp(1j * (2 * np.pi * freq * t + phase))
        for freq, mag, phase in components
    )  # Taking the real part as the original signal is real


for t in range(8):
    print(get_sin_sum(sines, t))

This give me effectively the same signal back, minus some floating point accuracy errors:

(1-1.734723475976807e-18j)
(-4+8.326672684688674e-17j)
(4.999999999999998+5.551115123125783e-17j)
(3-1.1102230246251565e-16j)
(2+2.2811613709095013e-16j)
(-0.9999999999999961-2.185751579730777e-16j)
(-3.1285737889241716e-15+6.106226635438361e-16j)
(7.000000000000003-3.0878077872387166e-16j)

But if I ask for the values at non-integers, in between the sample points…

for t in range(8):
    print(get_sin_sum(sines, t + 0.5))

I get noticeably non-real values:

(-3.9044580102481476-0.37500000000000006j)
(0.6566795687646556+0.37500000000000033j)
(5.227442611335023-0.375j)
(1.8607826149066014+0.37500000000000006j)
(1.144050370162492-0.37499999999999994j)
(-2.002873646477218+0.3749999999999999j)
(4.03296502875063-0.3750000000000002j)
(5.985411462805959+0.37499999999999994j)

I would have thought that it would remain real at all times due to the symmetry of positive and negative frequency components. What gives?

Apologies, by the way, if this turns out to be a Python question, and not a math question. I’m asking it here because I want to understand if theoretically we should expect the result to be real, or if I have a misconception.

Read more here: Source link