Я видел, как кто-то делал это в презентации, но мне трудно воспроизвести то, что он смог сделать. Вот слайд из его презентации:
![Sinewave decomposition via FFT](https://i.stack.imgur.com/EVAzm.png)
Довольно круто. Он разложил набор данных с использованием БПФ, а затем нанес на график соответствующие синусоидальные волны, указанные в БПФ.
Поэтому, чтобы воссоздать то, что он сделал, я создал серию точек, которые соответствуют комбинации из двух синусоид:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
x = np.arange(0, 10, 0.01)
x2 = np.arange(0, 20, 0.02)
sin1 = np.sin(x)
sin2 = np.sin(x2)
x2 /= 2
sin3 = sin1 + sin2
plt.plot(x, sin3)
plt.show()
![Composed wave](https://i.stack.imgur.com/JSXKl.png)
Теперь я хочу разложить эту волну (или, скорее, волну, которую подразумевают точки) обратно на исходные 2 волны синуса:
# goal: sin3 -> sin1, sin2
# sin3
array([ 0.00000000e+00, 2.99985000e-02, ... 3.68998236e-01])
# sin1
array([ 0. , 0.00999983, 0.01999867, ... -0.53560333])
# sin2
array([ 0. , 0.01999867, 0.03998933, ... 0.90460157])
Я начинаю с импорта numpy
и получения fft
из sin3
:
import numpy as np
fft3 = np.fft.fft(sin3)
ОК, это примерно так, как я получаю. Теперь у меня есть массив с комплексными числами:
array([ 2.13316069e+02+0.00000000e+00j, 3.36520138e+02+4.05677438e+01j,...])
и, если я наивно нарисую его, я вижу:
plt.plot(fft3)
plt.show()
![fft naively plotted](https://i.stack.imgur.com/AqhP7.png)
Хорошо, не уверен, что с этим делать.
Я хочу перейти отсюда к наборам данных, которые выглядят как sin1 и sin2:
plt.plot(sin1)
plt.show()
plt.plot(sin2)
plt.show()
![sin2 data plotted](https://i.stack.imgur.com/xLuPJ.png)
Я понимаю действительную и мнимую часть комплексных чисел в наборе данных fft3
, я просто не конечно, что с ними делать, чтобы извлечь из него наборы данных sin1
и sin2
.
Я знаю, что это связано не столько с программированием, сколько с математикой, но может ли кто-нибудь дать мне подсказку?
РЕДАКТИРОВАТЬ: обновить ответ Марка Снайдера:
Используя код Марка, я смог получить то, что ожидал, и в итоге получил следующий метод:
def decompose_fft(data: list, threshold: float = 0.0):
fft3 = np.fft.fft(data)
x = np.arange(0, 10, 10 / len(data))
freqs = np.fft.fftfreq(len(x), .01)
recomb = np.zeros((len(x),))
for i in range(len(fft3)):
if abs(fft3[i]) / len(x) > threshold:
sinewave = (
1
/ len(x)
* (
fft3[i].real
* np.cos(freqs[i] * 2 * np.pi * x)
- fft3[i].imag
* np.sin(freqs[i] * 2 * np.pi * x)))
recomb += sinewave
plt.plot(x, sinewave)
plt.show()
plt.plot(x, recomb, x, data)
plt.show()
позже я ' заставлю его вернуть рекомбинированный список волн, но сейчас я получаю аномальное ie, я не совсем понимаю. Прежде всего, я называю это так, просто передавая набор данных.
decompose_fft(sin3, threshold=0.0)
Но выглядит великолепно, но я получаю эту странную строку в y=0.2
Кто-нибудь знает, что это может быть или что это вызывает?
![Looks really good](https://i.stack.imgur.com/2tiW5.png)
РЕДАКТИРОВАТЬ:
Марк ответил на вопрос выше, спасибо!