es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Scipy FFT y Numpy FFT difieren en el espectro de tren de pulsos?

Estoy haciendo una FFT en una serie de pulsos. La serie es un pulso de amplitud 1 cada 7 días durante un total de 367 días.

Cuando ejecuto el siguiente código:

import numpy as np
import pandas as pd
from scipy.fft import fft, fftfreq, fftshift, ifft
from scipy.signal import blackman
from matplotlib import pyplot as plt
import random

Señal

num_samples = 367

tiempo en días

t = np.arange(int(num_samples))

Amplitud y posición del pulso. La amplitud aquí es 0 o 1 pero puede generar valores aleatorios.

La posición aquí es cada 7mo día.

signal = [random.randint(1,1) if (i%7 == 0) else 0 for i, x in enumerate(t)]#[random.randint(1,1) if (i%7 == 0) else 0 for i, x in enumerate(t)]#

FFT e IFFT utilizando Numpy

sr = 367
X = np.fft.fft(signal)
n = np.arange(num_samples)
T = num_samples/sr
freq = n/T

`plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.title(‘FFT using Numpy’)
plt.stem(freq, np.abs(X), ‘b’, markerfmt=” “, basefmt=”-b”)
plt.xlabel(‘Freq (Hz)’)
plt.ylabel(‘FFT Amplitude |X(freq)|’)

plt.subplot(122)
plt.title(‘IFFT using Numpy’)
plt.plot(t, np.fft.ifft(X), ‘r’)
plt.xlabel(‘Time (s)’)
plt.ylabel(‘Amplitude’)
plt.tight_layout()
plt.show()`

FFT e IFFT utilizando Scipy

sp = fft(signal)
freq = fftfreq(t.shape[-1])

`plt.figure(figsize = (12, 6))
plt.subplot(121)
plt.title(‘FFT using Scipy’)
plt.stem(freq, np.abs(sp), ‘b’, markerfmt=” “, basefmt=”-b”)
plt.xlabel(‘Freq (Hz)’)
plt.ylabel(‘FFT Amplitude |sp(freq)|’)

plt.subplot(122)
plt.title(‘IFFT using Scipy’)
plt.plot(t, ifft(sp), ‘r’)
plt.xlabel(‘Time (s)’)
plt.ylabel(‘Amplitude’)
plt.tight_layout()
plt.show()`

Claramente hay problemas de desplazamiento y escala, pero lo más importante es que esperaba que la FFT de un tren de pulsos fuera una serie de picos uniformes en el espectro de frecuencia. No entiendo los picos que se obtienen, lo que significa que probablemente estoy entendiendo mal cómo las funciones interpretan la señal. Cualquier orientación sería apreciada.

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Los picos en el espectro de frecuencia se deben a que la señal de tren de pulsos no es una onda senoidal pura, sino más bien una onda cuadrada con un periodo de 7 días. El algoritmo FFT descompone la señal en componentes sinusoidales con diferentes frecuencias, y la presencia de transiciones abruptas en la señal (en los bordes de los pulsos) hace que las componentes de alta frecuencia dominen en el espectro de Fourier. Por lo tanto, el espectro consiste en una serie de armónicos (múltiplos) de la frecuencia fundamental, que es 1/7 Hz (correspondiente a un periodo de 7 días).

    Para obtener un espectro de Fourier más claro con picos discretos en los armónicos de la frecuencia del pulso, se puede aplicar una función de ventana a la señal antes de calcular la FFT. Esto suavizará las transiciones abruptas y reducirá la fuga espectral. Una función de ventana comúnmente utilizada es la ventana de Blackman (disponible en SciPy), que tiene una buena resolución de frecuencia y niveles bajos de lóbulos laterales. Aquí tienes un ejemplo de código:

    window = np.blackman(num_samples)
    signal_windowed = signal * window
    sp = fft(signal_windowed)
    freq = fftfreq(num_samples)
    
    plt.figure(figsize=(8, 4))
    plt.stem(freq, np.abs(sp), 'b', markerfmt=" ", basefmt="-b")
    plt.xlabel("Frecuencia (Hz)")
    plt.ylabel("Amplitud FFT")
    plt.xlim(-0.1, 0.3)
    plt.show()
    

    Esto debería darte un espectro más claro con picos en los armónicos de 1/7 Hz.

Comments are closed.