关键词:复数,欧拉公式,正弦波,复数正弦波

概述

傅里叶变换在科学计算、图像处理、信号等方面有着广泛的应用,也是作为一个进阶的程序员所必须要了解的。傅里叶变换听起来非常复杂,但实际上在计算机上实现和理解都非常简单。

我整理出几篇笔记,以Python实现为主,不考虑太多数学公式,方便自己,也方便大家自学。

注:早期的科学科学计算大多数都是MATLAB实现的,所以国内外很多课程代码都是MATLAB实现的。本着“人生苦短,我学Python”的精神,这篇文章中的所有代码都是Python实现的,看起来也要方便一些。

我整理出了一个顺序:

- (一)准备篇 Python和数学基础

  • (二)画图篇 傅里叶变换 DFT
  • (三)进阶篇 快速傅里叶变换 FFT

去逐步的理解和学习~

一些必要条件

首先,你必须要知道什么是数学意义上的“傅里叶变换”
在此笔者推荐一篇文章↓↓↓
傅里叶分析之掐死教程(完整版)——知乎专栏
如果你不愿意看文章,那你可以看B站上李永乐老师的科普视频
傅立叶变换如何理解?美颜和变声都是什么原理?——bilibili
如果你已经具备了一些基础知识,那么我们可以看下面这张图再回顾一下(可以跳过)

其次,你需要有Python环境,以及安装一些必要的库:

numpy,pandas,scipy,matplotlib

  • numpy 封装了常用的科学计算,比如傅里叶变换/高斯消元/三角函数
    numpy中还提供了重要的数据结构ndarray
  • pandas 重要的数据结构DateFrame
  • scipy 科学计算库 Gamma/Comb
  • matplotlib 主流的数据可视化的包

一般来讲,Python中,采用numpy+matplotlab就能够代替MATLAB
matlplotlab能够帮助我们画出各种各样的数学图表,学好它是非常重要的。

因为Python语法非常简单,第三方库众多,我们可以边学边做,这样效率会比较高。在此↓↓↓也附上一片简单易懂的Python教程(包括numpy和matplotlab的使用)

Python基础教程(有目录、有标签)

学傅里叶变换前,还需要一定的《线性代数》基础,因为快速傅里叶变换,需要将所有的复数正弦波放入到矩阵中,对矩阵进行处理
如果比较了解《数据结构》中矩阵和稀疏矩阵的知识,学习起来也没有什么难度。

进入正题

傅里叶想做的事:时域信号转化为频域信号
傅里叶在数学上做的事:复数正弦波与复数点积=傅里叶系数
所以复数、欧拉公式、正弦波、复数正弦波是重要的基础部分。

复数

复数是在实数的基础进行的拓展,有实部(real)+虚部(imag)

Python中自带complex()来处理复数问题

class complex(real, imag)

欧拉公式

欧拉公式,也被称作最美的公式,用泰勒展开可以推到,有兴趣的同学可以去了解一下,我们关注一个重要的结论:无论k取何值,都在一个单位圆上。
换言之,k代表的是线段与正实数轴的夹角,k的取值与线段长度无关。

在后续的学习中,我们可以做这样一个转换(现在可以忽略这段话)

距离——振幅/能量
与正实数轴的夹角——相位

最终,我们会发现:在复数范围内做变换,距离——振幅/能量是我们要的结果,夹角——相位 的变化不影响结果。这也是我们为什么要在复数范围内做傅里叶变换的原因。

下面我们在Python去看一下欧拉公式

我们先要import相关的包

import numpy as np
import math
import matplotlib.pyplot as plt

我们再定义欧拉公式中的k,k可以为全体实数
接下来我们定义欧拉公式的左边,构造e^ik
(调用numpy中封装好的exp(),意思是 构造以e为底的指数函数)

#k(any real number)
k=100
#Euler‘s notation
euler=np.exp(1j*k)

然后,我们把欧拉公式等号右边的部分画出来,cos(k)+i*sin(k)
这里在图上体现出的应该是一个点
(这个点必然会在一个单位圆上)

#plot dot
plt.plot(np.cos(k),np.sin(k),'ro')

我们画完了欧拉公式等号右边代表的某个点
我们就来画一个单位元,来验证下,
是否k去任意实数,都必然在单位圆上

#drwa unit circle for reference
x=np.linspace(-np.pi,np.pi,num=100)
y=np.linspace(-10,10,num=1000)
plt.plot(np.cos(x),np.sin(x))

我们再做一些画图的其他工作,把标签添加到上面
(此处的代码不写也是可以的)

# some plotting touch-ups
plt.axis('square')
plt.xlabel('Real axis')
plt.ylabel('Imaginary axis')

最后我们调用show函数,把它展示出来:

plt.show()

我们来看一下这张图:

当然,k的取值是任意的,但是这个红点(欧拉公式上的解的一点)必然会在这个单位圆上。

正弦波

正弦波,我们在数学/物理上都学过,我们脑海中也都有印象,就是sin函数。
下面我们尝试在Python中去实现一下。

首先,我们import相应的数学和绘图包

import numpy as np
import math
import matplotlib.pyplot as plt

接下来,我们需要设置一些模拟的参数(这里的代码现在可以不必理解)
这里其实并不是正弦波的参数
我们都知道,计算机中的数学是离散的
但是我们画的sin函数是连续的曲线
我们就需要一些手段,用离散的方法(足够密集)来表示连续的变量

#simulation paramenters
srate =500;     #频率/frequency
time=np.arange(0.,2.,1./srate)      #time in second

我们开始最重要的部分,设置正弦波的参数
正弦波:asin(2πft+θ) 参数:频率/相位/能量

#sine wave param.eters
freq=3; #频率
ampl=2; #能量
phas=np.pi/3;   #相位

正弦波函数

#generate the sine wave
sinewave=ampl*np.sin(2*np.pi*freq*time+phas)

最后,我们把图像画出来
注:这里grid()函数是画网格用的,True会在图像中显示网格

plt.plot(time,sinewave,'k')
plt.xlabel('Time(sec.)')
plt.ylabel('Amplitude(a.u.)')
plt.grid(True)
plt.show()

把代码在Python中合并就可以画出图像了
我们也可以调整一些参数,去看看图像变化的样子

复数正弦波

正弦波公式中,有一个很烦的东西,就是相位。相信我们在物理中都遇到过,如果我们把相位移动一点,信号就会产生变化,但其实这个变化,我们从频域信号的角度看意义不大。
如果我们在附属范围内,对正弦波进行运算,就可以规避掉相位的问题,相位代表角度,角度在复平面内,并不影响复数的长度(振幅)
因此,复数正弦波的想法油然而生。

我们把正弦波作为参数,带入到欧拉公式中,也就形成了复数正弦波
换言之,实数正弦波+虚数正弦波=复数正弦波



由于篇幅所限,一篇文章太多内容不便于理解。

我贴出Python绘制的,二维和三维复数正弦波的理解,我们可以先从不同的角度,比如实数轴和虚数轴,实数轴和时间,或是3D的角度,进行一些观察和思考。

下一篇文章中,我们再探讨复数正弦波和傅里叶变换的有关内容。

最后的话

1.Jupter
网上许多示例代码,(尤其是外国的教程),许多都是在Jupter Notebook(IPython notebook)下编写的。这也是一个非常好的Python学习环境。但是,如果你和我一样,喜欢在本地Python环境中编写代码,这里我也提供一种.ipynb文件转换为.py文件的方法:

#会在当前目录自动生成.py文件
jupyter nbconvert --to script 文件名.ipynb

2.结束语
文章中主要内容,笔记,代码,图像都是我一点点敲出来的,在这方面,我也是个初学者,如果你喜欢我的文章或有任何指教,欢迎在下面评论或联系我!

更多推荐

傅里叶变换的Python实现 自学笔记(一)准备篇(Python和数学基础)零基础入门