第二篇主要介绍了傅立叶的核心:“傅里叶级数就是函数在某个函数空间中各个基底的投影和“,然后基于这个核心,我们做了一个数值模拟:如何去拟合一个任意函数。
但是在实际应用的时候,我们并不会去直接的按照原理,写代码去实现。而是直接调用非常稳定的、安全的api,帮助我们解决问题。
在这次第三篇中,将给你展示一个非常神奇的傅立叶应用。而这个应用,也会帮助你进一步了解傅立叶的核心。
那我们直接开始吧。
如果你对科学计算感兴趣,你在numpy
、scipy
、pytorch
、tensorflow
包里面会发现一个叫fft
模块。
而fft
全称为Fast Fourier Transform
,中文翻译的也很直接,就叫快速傅里叶变换。
numpy
: https://numpy.org/doc/stable/reference/generated/numpy.fft.fft.htmlscipy
:https://docs.scipy.org/doc/scipy/reference/generated/scipy.fft.fft.html#scipy.fft.fftpytorch
:https://pytorch.org/docs/stable/fft.htmltensorflow
: https://www.tensorflow.org/api_docs/python/tf/signal/fft虽然属于不同的包,但是本质上都差不多,对数据做快速傅立叶变换。从离散数据中提取出信息。
那么到底怎么处理离散的数据,能提取出什么信息?其实这些包的文档里面都没说。那么我接下来将要分享一个案例,带大家打开傅立叶应用的大门。
就暂时使用scipy
的fft
模块来做演示。
import numpy as np
from scipy.fft import fft
import matplotlib.pyplot as plt
Fs = 1000 #Sampling frequency
T = 1 / Fs #Sampling period
L = 1500; #Length of signal
t = np.arange(L) * T #Time vector
S = 0.7 * np.sin(2 * np.pi * 50 * t) + np.sin(2 * np.pi * 120 * t) + 0.2 * np.sin(2 * np.pi * 10 * t)
X = S + 2 * np.random.rand(S.shape[0])
fig, ax = plt.subplots(figsize=(10, 5), dpi=120)
ax.plot(1000 * t[:100], X[:100])
ax.set_title("Signal Corrupted with Zero-Mean Random Noise")
ax.set_xlabel("t (milliseconds)")
ax.set_ylabel("X(t)")
可以看出来,下面什么信息都看不到,杂乱无章的数据而已。
Y = fft(X)
P2 = np.abs(Y / L)
P1 = P2[1:np.int32(L / 2 + 1)]
P1[1:] = 2 * P1[1:]
P1
数据可视化看一下:f = Fs * np.arange(L / 2) / L
fig, ax = plt.subplots(figsize=(10, 5), dpi=120)
ax.plot(f, P1)
ax.set_title('Single-Sided Amplitude Spectrum of X(t)')
ax.set_xlabel('f (Hz)')
ax.set_ylabel('|P1(f)|')
# ax.set_xlim([0, 150])
这个图看起来,好像有3个高峰,然后好像有很多噪声。那么我们重点放在三个峰那里,看看能不能从三个峰那里发现有用的信息。
f = Fs * np.arange(L / 2) / L
fig, ax = plt.subplots(figsize=(10, 5), dpi=120)
ax.plot(f, P1)
ax.set_title('Single-Sided Amplitude Spectrum of X(t)')
ax.set_xlabel('f (Hz)')
ax.set_ylabel('|P1(f)|')
ax.set_xlim([0, 150])
for temp_y in [0.2, 0.7, 1.0]:
ax.hlines(temp_y, xmin=0, xmax=150, colors='gray', linestyles='-.')
for temp_x in [10, 50, 120]:
ax.vlines(x=temp_x, ymin=0, ymax=1,colors='red', linestyles='-.' )
从上面图可以看到:
这三个数值到底是什么意思?
其实你只要把文章翻到最前面就可以看到了。在文字最前面的构建样本数据的时候,写了这样的话:“其中包含幅值为 0.7 的 50 Hz 正弦、幅值为 1 的 120 Hz 正弦量、幅值为 0.2 的 10 Hz 正弦量”
可以得出来了:x轴的位置对应的是频率部分,y轴对应的是震幅部分。
是不是破案了!!
我们通过傅立叶变换,然后对数据简单做了计算,竟然能求出来原始数据的参数!!!
在最后,牢记这句话:傅里叶级数就是函数在某个函数空间中各个基底的投影和
那么这就是本期的全部内容,如果想看更多,点击下方的代码链接和文章list,下期再见!
傅立叶及其python应用所有的代码和数据全部都免费共享!
03
开头的ipynb
格式文件list
list