[Python]信号与系统实验[1]-周期信号的分解与合成

摘要

使用Python进行信号与系统实验-信号的分解与合成。

实验目的

  1. 熟悉信号的合成、分解原理,加深对傅里叶级数的理解。
  2. 了解和认识吉布斯现象(Gibbs)。
  3. 学会使用 Python 分析傅立叶级数展开。

实验环境

Python+Jupyter notebook

第一题

绘制函数的傅立叶级数展开式的谐波叠加的图像。

代码

# -*- encoding:utf-8 -*-
import matplotlib.pyplot as plt
import numpy as np
import sympy as sp
from sympy import *

# plt 显示中文
plt.rcParams['font.sans-serif'] = ['FZXiYuan-M01S']
plt.rcParams['axes.unicode_minus'] = False

t = np.arange(-1, 1.001, 0.001)
w = 2 * np.pi
y = np.sign(np.sin(2 * np.pi * t))

plt.grid(True)
plt.xlabel('t')
plt.ylabel('周期方波信号')
plt.axis([-1, 1, -1.5, 1.5])

n_max = [1, 3, 5, 11, 47]
N = len(n_max)

for k in range(N):
    n = np.arange(1, n_max[k] + 1, 2)
    xx = (4 / (np.pi * n))[:, np.newaxis]  # 添加矩阵维度
    x = (xx * np.sin(np.outer(w * n, t)))

    plt.figure()
    plt.plot(t, y)
    plt.plot(t, np.sum(x, axis=0))
    plt.xlabel('t')
    plt.ylabel('部分和的波形')
    plt.axis([-1, 1, -1.5, 1.5])
    plt.grid(True)
    plt.title('最大谐波数=' + str(n_max[k]))

plt.show()

效果




第二题

看图使用代码合成信号.

代码

import numpy as np
import matplotlib.pyplot as plt

# 定义函数
def f(t):
    T = 2
    w0 = 2 * np.pi / T
    return np.abs(np.mod(w0 * t + np.pi, 2 * np.pi) - np.pi) / np.pi * 2


# 设置参数
t = np.arange(-2.5, 2.5, 0.001)

# 绘制坐标轴
fig = plt.figure()
ax = fig.gca()

# 不显示右侧和顶部的直线
ax.spines['right'].set_color("none")
ax.spines['top'].set_color('none')

# 设置左边直线(y 轴)的属性
# 坐标轴颜色
ax.spines['left'].set_color('red')
# 坐标轴宽度
ax.spines['left'].set_linewidth(2)
# 刻度在轴线左侧
ax.yaxis.set_ticks_position('left')
# 刻度的位置
ax.yaxis.set_ticks([-1, -0.5, 0, 0.5, 1])
# 刻度显示为红色
ax.tick_params(axis='y', colors='red')
# 设置左侧轴线位置
# 参数必须是元组(type, amount)
# ('data', 0)表示数据为 0 的位置
ax.spines['left'].set_position(('data', 0))
# 使用 annotate 在 y 轴顶端创建箭头
ax.annotate("", (0, 1), xytext=(0, 1.2), arrowprops={'arrowstyle': '<-', 'color': 'red', 'linewidth': 2})

# 设置底部直线(x 轴)的属性
ax.spines['bottom'].set_color('green')
ax.spines['bottom'].set_linewidth(2)
ax.spines['bottom'].set_position(('data', 0))
ax.annotate('', (6, 0), xytext=(7.5, 0), arrowprops={'arrowstyle': '<-', 'color': 'green', 'linewidth': 2})
ax.tick_params(axis='x', colors='green')

# 绘制波形
ax.plot(t, f(t + 0.5) - 1)

plt.title('过原点周期三角信号')
plt.xlabel('t')
plt.ylabel('幅值')
plt.grid(True)
plt.show()

效果

第三题

合成谐波波形.

代码

import numpy as np
import matplotlib.pyplot as plt


def f(t, w0, E, n):
    result = 2 * E / np.pi
    for i in range(1, n + 1):
        result += (-1) ** (n - 1) * 4 * E / np.pi / (4 * i ** 2 - 1) * np.cos(2 * i * w0)
    return result


w0 = 2 * np.pi
E = 1.0
t = np.arange(0, 2 * np.pi / w0, 0.001)

plt.figure(figsize=(8, 8))
plt.subplot(2, 2, 1)
plt.plot(t, f(t, w0, E, 3))
plt.title('3 次谐波')
plt.grid(True)

plt.subplot(2, 2, 2)
plt.plot(t, f(t, w0, E, 5))
plt.title('5 次谐波')
plt.grid(True)

plt.subplot(2, 2, 3)
plt.plot(t, f(t, w0, E, 9))
plt.title('9 次谐波')
plt.grid(True)

plt.subplot(2, 2, 4)
plt.plot(t, f(t, w0, E, 25))
plt.title('25 次谐波')
plt.grid(True)

plt.show()

效果

(可能有误)

第四题

合成三角波信号.

代码

import numpy as np
import matplotlib.pyplot as plt # 定义函数
def f(t):
    T=1
    return np.mod(t, T) / T * 2 - 1 # 设置参数
t = np.arange(-0.99, 2.01, 0.001) # 绘制波形
plt.plot(t, 0.5*f(t)+0.5) plt.title('周期锯齿信号') plt.xlabel('t') plt.ylabel('幅值')
plt.grid(True)
plt.show()

效果

总结

需要注意的是,Python 中没有内置的 sawtooth 函数,可以使用 np.mod 函数来实现,实现方 式如上。
需要注意的是,Python 中也没有内置的 square 函数,可以使用 sign 和 sin 函数实现,同时在绘制部分和的波形时,需要使用 np.sum 函数对所有的部分和进行求和。
分析实验一,随着谐波次数的增大,方波的傅立叶级数波形展开越来越接近原函数。 分析实验三,可以发现随着谐波次数的增大,傅立叶级数图像接近余弦信号,曲线越平滑。

报错:ValueError: operands could not be broadcast together with shapes (2,) (2,2001)

  1. 改变数组形状:
    在对矩阵进行相乘时,使用 np.dot(a,b)
    通过修改 shape 属性来改变数组的形状。
  2. 数组转置:
    numpy.transpose(a, axes=None) Permute the dimensions of an array. numpy.ndarray.T Same as self.transpose(), except that self is returned if self.ndim < 2.
  3. 更改维度: 当创建一个数组之后,还可以给它增加一个维度,这在矩阵计算中经常会用到。 numpy.newaxis = None None 的别名,对索引数组很有用。 很多工具包在进行计算时都会先判断输入数据的维度是否满足要求,如果输入数据达不到指 定的维度时,可以使用 newaxis 参数来增加一个维度。

从信号的合成、分解原理角度,解释傅里叶级数

吉布斯现象

吉布斯现象是指在傅里叶级数逼近周期函数时,如果级数中包含了跳跃点,会出现级数的振 荡现象。这个现象通常在跳跃点处出现,即在函数出现突变的位置,傅里叶级数逼近的误差 会出现振荡现象。 在下图中,我们可以看到,当级数包含跳跃点时,如在方波函数的跳跃点位置,级数逼近的 结果(橙红色线条)会出现振荡现象。尽管级数逼近的结果在跳跃点附近出现了误差,但在 其他位置,级数逼近的结果是非常接近原函数的。

信号的变换

  1. 线性变换:将信号的幅度或相位进行线性变换,包括放大、缩小、移位、翻转等。
  2. 非线性变换:通过对信号的幅度或相位进行非线性变换,可以实现对信号的各种形态变换,如对数变换、指数变换、幂次变换、根号变换等。
  3. 时域变换:通过对信号在时间轴上进行变换,可以实现对信号时域特性的变换,如平移、 卷积、微分、积分、加窗等。
  4. 频域变换:通过对信号在频率轴上进行变换,可以实现对信号频域特性的变换,如傅里 叶变换、离散傅里叶变换、小波变换等。
  5. 相位变换:改变信号的相位,可以实现对信号的周期和相位特性进行变换,如相位调制、 相位平移、相位旋转等。
  6. 频率变换:改变信号的频率,可以实现对信号的频谱特性进行变换,如频率调制、频率 平移、频率扩展等。
  7. 滤波变换:通过对信号进行滤波操作,可以实现对信号频谱的特定频率成分的增强或抑制,如低通滤波、高通滤波、带通滤波、带阻滤波等。
  8. 变换域组合:通过将不同的变换域进行组合,可以实现对信号的多种特性进行变换,如时频域变换、小波变换等。
posted @ 2023-07-17 00:50  qsBye  阅读(485)  评论(0编辑  收藏  举报