信号是随时间和空间变化的某种物理量,它一般是时间变量t的函数。信号随时间变量t变化的函数曲线成为信号的波形。
本部分主要内容包括两块:
下面我将用Python+matplotlib的方式绘制动态图,从而直观地展示效果
信号在时域中的变换基本包括:
下面来具体看一下这三种变换该如何实现,在这之前,先确定一个原来信号,下面的变换将在原信号的基础上进行:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax = plt.axes(xlim=(0, 4), ylim=(-4, 4))
line, = ax.plot([], [], lw=2)
# initialization function: plot the background of each frame
def init():
line.set_data([], [])
return line,
# animation function. This is called sequentially
def animate(i):
x = np.linspace(0, 4, 1000)
y = np.sin(np.pi * (x - 0.01 * i))
line.set_data(x,3*y)
return line,
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
plt.show()
静态图如下:
为了更好地展示,这里最好是一个子图放两个信号做对比,所以我把代码优化了一下:
import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
# First set up the figure, the axis, and the plot element we want to animate
fig = plt.figure()
ax1 = plt.axes(xlim=(0, 4), ylim=(-4, 4))
ax2 = plt.axes(xlim=(0, 4), ylim=(-4, 4))
line1, = ax1.plot([], [], lw=2, label='Original signal',color="green")
line2, = ax2.plot([], [], lw=2, label='Transformed signal',color="red")
# initialization function: plot the background of each frame
def init():
line1.set_data([], [])
line2.set_data([], [])
return line1,line2
# animation function. This is called sequentially
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = -(np.cos(np.pi * (x - 0.01 * i))) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
# call the animator. blit=True means only re-draw the parts that have changed.
anim = animation.FuncAnimation(fig, animate, init_func=init,
frames=200, interval=20, blit=True)
plt.legend()
plt.show()
加以说明一下:
下面主要展示的是animate方法里的代码,因为其余部分是不变的,实现以下信号变换,只需要修改几个参数即可,难度也不是很大
反转是以纵轴为中心180度反转,即左右对折
很简单,在x前加个负号即可:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = np.sin(np.pi * ((-1) * x - 0.01 * i)) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
这里要把子图的大小稍微改一下:
ax1 = plt.axes(xlim=(-25, 25), ylim=(-4, 100))
ax2 = plt.axes(xlim=(-25, 25), ylim=(-4, 100))
然后再来修改animate方法:
def animate(i):
x = np.linspace(-4, 4, 1000)
y1 = 2**x * i #绿色
y2 = 2**(x*(-1)) * i #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
这里我们给定一个值吧,将原信号左移1个单位 :
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = np.cos(np.pi * (x - 0.01 * i) + 1) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = np.cos(np.pi * (x - 0.01 * i) - 2) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
将原信号压缩成原来的一半:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = np.cos(np.pi * (x - 0.01 * i) * 2) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
用动图展示:
如果要展宽,只需要把值改成小于1的值即可,如展宽成原来的2倍:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y2 = np.cos(np.pi * (x - 0.01 * i) * 1/2) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
信号在时域中的运算有相加、相减、相乘、数乘、微分、积分等。
相加:信号在时域中相加时,其横坐标(时间轴)不变,仅是将横坐标所对应的值相加。两输入加法器:
加法器完成功能:OUT=IN1+IN2
相减:信号在时域相减时,其横坐标不变,仅是将横坐标值对应的纵坐标值相减。减法器的电路如图所示:
减法器完成功能:OUT=IN2-IN1
数乘:信号在时域倍乘时,其横坐标不变,仅是将横坐标值所对应的纵坐标值扩大n倍(n>1时扩大;0
数乘器完成功能:OUT=(RP/R)*IN
反相:信号在时域反相时,其横坐标不变,仅是将横坐标值所对应的纵坐标值乘负号。反相器电路如图所示:
反相器完成功能:OUT=-IN
上面这些运算是通过电子元件来实现的,下面我们看一下如何用python实现相加、相减、相乘、数乘、微分、积分
有了上面的基础,下面这几个基本运算其实也很好理解了,不就是多一个信号嘛:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y21 = np.sin(np.pi * (x - 0.01 * i))
y22 = np.sin(np.pi * (x - 0.01 * i))
y2 = y21 + y22 #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
这里不需要多说了吧?大家可以尝试改成其他的参数,试一下效果
两个相同的信号相减会得到什么呢:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y21 = np.sin(np.pi * (x - 0.01 * i))
y22 = np.sin(np.pi * (x - 0.01 * i))
y2 = y22 - y21 #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
那如果是这种情况,其中一个信号缩减为原来的一半:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.cos(np.pi * (x - 0.01 * i)) #绿色
y21 = np.sin(np.pi * (x - 0.01 * i))
y22 = np.sin(np.pi * (x - 0.01 * i) * 2)
y2 = y22 - y21 #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
当然,这里可以调的参数也有很多,这里就不一一举例了
这里的数乘不是两个信号相乘,对于某一信号在时域倍乘时,其横坐标不变,仅是将横坐标值所对应的纵坐标值扩大n倍
举个例子,原信号乘2:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = np.sin(np.pi * (x - 0.01 * i)) #绿色
y2 = 2 * np.sin(np.pi * (x - 0.01 * i))
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
信号的横坐标不变,仅是将横坐标值所对应的纵坐标值乘负号:
def animate(i):
x = np.linspace(-4, 4, 1000)
y1 = np.sin(np.pi * (x - 0.01 * i)) #绿色
y2 = (-1) * np.sin(np.pi * (x - 0.01 * i)) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
这里要注意区分跟反转的区别,我们拿最简单的幂函数举例:
def animate(i):
x = np.linspace(0, 4, 1000)
y1 = x * i #绿色
y2 = x * i * (-1) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
我们知道sin(x)的微分是cos(x),所以这里直接改一下即可:
def animate(i):
x = np.linspace(-4, 4, 1000)
y1 = np.sin(np.pi * (x - 0.01 * i)) #绿色
y2 = np.cos(np.pi * (x - 0.01 * i)) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2
同理,sin(x)在(-∞,t)的积分是-cos(t):
这样一来就好办了:
def animate(i):
x = np.linspace(-4, 4, 1000)
y1 = np.sin(np.pi * (x - 0.01 * i)) #绿色
y2 = (-1) * np.cos(np.pi * (x - 0.01 * i)) #红色
line1.set_data(x, y1)
line2.set_data(x, y2)
return line1,line2