
LTI 连续系统可以用常系数线性微分方程描述:

经典解分为齐次解和特解:
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义微分方程:y''(t) + 3y'(t) + 2y(t) = x(t)
def system_ode(t, y, x_func):
"""
定义系统的微分方程
y: [y, y']
返回: [y', y'']
"""
dydt = np.zeros_like(y)
dydt[0] = y[1] # y'
dydt[1] = -3*y[1] - 2*y[0] + x_func(t) # y'' = -3y' - 2y + x(t)
return dydt
# 输入信号:阶跃函数 u(t)
def x(t):
return np.heaviside(t, 1)
# 初始条件
y0 = [0, 0] # y(0-), y'(0-)
# 求解微分方程
t_span = [0, 10] # 时间范围
t_eval = np.linspace(0, 10, 1000) # 评估点
sol = solve_ivp(lambda t, y: system_ode(t, y, x), t_span, y0, t_eval=t_eval)
# 绘制结果
plt.figure(figsize=(10, 6))
plt.plot(sol.t, sol.y[0], 'b-', label='系统响应 y(t)')
plt.plot(sol.t, x(sol.t), 'r--', label='输入信号 x(t)')
plt.title('LTI系统的阶跃响应')
plt.xlabel('时间 t')
plt.ylabel('幅度')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 1:LTI 系统的阶跃响应
import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义微分方程:y''(t) + 3y'(t) + 2y(t) = x(t)
def system_ode(t, y, x_func):
"""
定义系统的微分方程
y: [y, y']
返回: [y', y'']
"""
dydt = np.zeros_like(y)
dydt[0] = y[1] # y'
dydt[1] = -3*y[1] - 2*y[0] + x_func(t) # y'' = -3y' - 2y + x(t)
return dydt
# 时间范围和评估点
t_span = [0, 10] # 时间范围
t_eval = np.linspace(0, 10, 1000) # 评估点
# 计算0-到0+的跳变
# 对于方程 y'' + 3y' + 2y = δ(t),当y(0-)=0, y'(0-)=0时
# 两边积分得 y'(0+) - y'(0-) = 1,故y'(0+)=1
# 重新求解,考虑跳变
y0_plus = [0, 1] # y(0+)=0, y'(0+)=1
sol_jump = solve_ivp(lambda t, y: system_ode(t, y, lambda t: 0), t_span, y0_plus, t_eval=t_eval)
plt.figure(figsize=(10, 6))
plt.plot(sol_jump.t, sol_jump.y[0], 'g-', label='冲激响应 h(t)')
plt.title('系统对冲激输入的响应(考虑0+跳变)')
plt.xlabel('时间 t')
plt.ylabel('幅度')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 2:考虑 0 + 跳变的系统响应

import matplotlib.pyplot as plt
from scipy.integrate import solve_ivp
import numpy as np
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 定义系统微分方程
def system_ode(t, y, x_func):
"""
定义系统的微分方程: y'' + 3y' + 2y = x(t)
y: [y, y']
返回: [y', y'']
"""
dydt = np.zeros_like(y)
dydt[0] = y[1] # y'
dydt[1] = -3*y[1] - 2*y[0] + x_func(t) # y'' = -3y' - 2y + x(t)
return dydt
# 定义输入信号(阶跃函数)
def x(t):
"""输入信号: 阶跃函数 u(t)"""
return np.heaviside(t, 1)
# 设置时间范围
t_span = [0, 10] # 时间范围
t_eval = np.linspace(0, 10, 1000) # 评估点
# 计算零输入响应、零状态响应和全响应
# 系统特征根:r^2 + 3r + 2 = 0 => r1=-1, r2=-2
# 零输入响应:y_zi(t) = C1e^(-t) + C2e^(-2t)
# 初始条件:y(0+)=1, y'(0+)=2
# 解得:C1=4, C2=-3
def y_zi(t):
"""零输入响应"""
return 4*np.exp(-t) - 3*np.exp(-2*t)
# 零状态响应(数值解)
sol_zs = solve_ivp(lambda t, y: system_ode(t, y, x), t_span, [0, 0], t_eval=t_eval)
# 全响应
y_total = y_zi(sol_zs.t) + sol_zs.y[0]
plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(sol_zs.t, y_zi(sol_zs.t), 'r-', label='零输入响应')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 2)
plt.plot(sol_zs.t, sol_zs.y[0], 'g-', label='零状态响应')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 3)
plt.plot(sol_zs.t, y_total, 'b-', label='全响应')
plt.legend()
plt.grid(True)
plt.xlabel('时间 t')
plt.tight_layout()
plt.show()
图 3:零输入响应、零状态响应和全响应对比
冲激响应 h (t):系统对单位冲激输入 δ(t) 的零状态响应
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 系统传递函数:H(s) = 1/(s^2 + 3s + 2)
num = [1] # 分子系数
den = [1, 3, 2] # 分母系数
# 计算冲激响应
t_impulse = np.linspace(0, 10, 1000)
t_impulse, h = signal.impulse((num, den), T=t_impulse)
plt.figure(figsize=(10, 6))
plt.plot(t_impulse, h, 'b-', label='冲激响应 h(t)')
plt.title('系统的冲激响应')
plt.xlabel('时间 t')
plt.ylabel('幅度')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 4:系统的冲激响应
阶跃响应 s (t):系统对单位阶跃输入 u (t) 的零状态响应
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 系统传递函数:H(s) = 1/(s^2 + 3s + 2)
num = [1] # 分子系数
den = [1, 3, 2] # 分母系数
# 计算阶跃响应
t_step = np.linspace(0, 10, 1000)
t_step, s = signal.step((num, den), T=t_step)
plt.figure(figsize=(10, 6))
plt.plot(t_step, s, 'r-', label='阶跃响应 s(t)')
plt.title('系统的阶跃响应')
plt.xlabel('时间 t')
plt.ylabel('幅度')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 5:系统的阶跃响应
零状态响应可表示为输入信号与冲激响应的卷积:

import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 卷积积分示例
def x(t):
"""矩形脉冲信号"""
return np.where((t >= 0) & (t <= 2), 1, 0)
def h(t):
"""指数衰减冲激响应"""
return np.where(t >= 0, np.exp(-t), 0)
# 计算卷积
dt = 0.01
t = np.arange(-5, 10, dt)
x_vals = x(t)
h_vals = h(t)
# 使用numpy的convolve函数
y_conv = np.convolve(x_vals, h_vals, mode='same') * dt
plt.figure(figsize=(12, 10))
plt.subplot(3, 1, 1)
plt.plot(t, x_vals, 'b-', label='输入信号 x(t)')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 2)
plt.plot(t, h_vals, 'r-', label='冲激响应 h(t)')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 3)
plt.plot(t, y_conv, 'g-', label='卷积结果 y(t) = x(t)*h(t)')
plt.legend()
plt.grid(True)
plt.xlabel('时间 t')
plt.tight_layout()
plt.show()
图 6:卷积积分示例
import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义信号函数
def x(t):
"""矩形脉冲信号"""
return np.where((t >= 0) & (t <= 2), 1, 0)
def h(t):
"""指数衰减冲激响应"""
return np.where(t >= 0, np.exp(-t), 0)
# 计算卷积
dt = 0.01
t = np.arange(-5, 10, dt)
x_vals = x(t)
h_vals = h(t)
# 验证卷积交换律
# 计算 x(t)*h(t) 和 h(t)*x(t)
y_conv1 = np.convolve(x_vals, h_vals, mode='same') * dt
y_conv2 = np.convolve(h_vals, x_vals, mode='same') * dt
# 计算误差
error = np.max(np.abs(y_conv1 - y_conv2))
print(f"卷积交换律验证误差: {error:.10f}")
plt.figure(figsize=(10, 6))
plt.plot(t, y_conv1, 'b-', label='x(t)*h(t)')
plt.plot(t, y_conv2, 'r--', label='h(t)*x(t)')
plt.title(f'卷积交换律验证 (误差: {error:.10f})')
plt.xlabel('时间 t')
plt.ylabel('幅度')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 7:卷积交换律验证

import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义信号函数
def x(t):
"""矩形脉冲信号"""
return np.where((t >= 0) & (t <= 2), 1, 0)
def delta_approx(t, t0=0, width=0.02):
"""近似冲激函数"""
return np.where(np.abs(t-t0) < width/2, 1/width, 0)
# 计算卷积
dt = 0.01
t = np.arange(-5, 10, dt)
x_vals = x(t)
# 函数与冲激函数的卷积示例
t0 = 1 # 冲激函数的位置
delta_vals = delta_approx(t, t0) # 近似冲激函数
y_conv_delta = np.convolve(x_vals, delta_vals, mode='same') * dt # 计算卷积
plt.figure(figsize=(12, 8))
plt.subplot(3, 1, 1)
plt.plot(t, x_vals, 'b-', label='x(t)')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 2)
plt.plot(t, delta_vals, 'r-', label='δ(t-1) (近似)')
plt.legend()
plt.grid(True)
plt.subplot(3, 1, 3)
plt.plot(t, y_conv_delta, 'g-', label='x(t) * δ(t-1) = x(t-1)')
plt.plot(t, x(t-t0), 'k--', label='理论值 x(t-1)')
plt.legend()
plt.grid(True)
plt.xlabel('时间 t')
plt.tight_layout()
plt.show()
图 8:函数与冲激函数的卷积

import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义信号函数
def x(t):
"""矩形脉冲信号"""
return np.where((t >= 0) & (t <= 2), 1, 0)
def h(t):
"""指数衰减冲激响应"""
return np.where(t >= 0, np.exp(-t), 0)
# 计算卷积
dt = 0.01
t = np.arange(-5, 10, dt)
x_vals = x(t)
h_vals = h(t)
# 卷积的微分性质验证
# 计算导数
dx_dt = np.gradient(x_vals, dt)
dh_dt = np.gradient(h_vals, dt)
# 计算卷积
y_conv_dx = np.convolve(dx_dt, h_vals, mode='same') * dt
y_conv_dh = np.convolve(x_vals, dh_dt, mode='same') * dt
plt.figure(figsize=(12, 8))
plt.subplot(2, 1, 1)
plt.plot(t, y_conv_dx, 'b-', label='dx/dt * h(t)')
plt.legend()
plt.grid(True)
plt.subplot(2, 1, 2)
plt.plot(t, y_conv_dh, 'r-', label='x(t) * dh/dt')
plt.plot(t, y_conv_dx, 'g--', label='dx/dt * h(t) (参考)')
plt.legend()
plt.grid(True)
plt.xlabel('时间 t')
plt.tight_layout()
plt.show()
图 9:卷积的微分性质验证

import numpy as np
import matplotlib.pyplot as plt
# 设置中文字体
plt.rcParams["font.family"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False # 解决负号显示问题
# 定义信号函数
def x(t):
"""矩形脉冲信号"""
return np.where((t >= 0) & (t <= 2), 1, 0)
def h(t):
"""指数衰减冲激响应"""
return np.where(t >= 0, np.exp(-t), 0)
# 计算相关函数
def correlate(x, y, mode='same'):
"""计算相关函数 R_xy(τ)"""
return np.correlate(x, y, mode=mode)
# 计算卷积和相关
dt = 0.01
t = np.arange(-5, 10, dt)
x_vals = x(t)
h_vals = h(t)
# 计算自相关和互相关
R_xx = correlate(x_vals, x_vals, mode='same') * dt
R_xy = correlate(x_vals, h_vals, mode='same') * dt
R_yx = correlate(h_vals, x_vals, mode='same') * dt
R_yy = correlate(h_vals, h_vals, mode='same') * dt
# 构建相关时间轴
tau = np.arange(-len(t)//2, len(t)//2) * dt
plt.figure(figsize=(12, 10))
plt.subplot(2, 2, 1)
plt.plot(tau, R_xx, 'b-', label='R_xx(τ)')
plt.title('x(t)的自相关函数')
plt.xlabel('τ')
plt.legend()
plt.grid(True)
plt.subplot(2, 2, 2)
plt.plot(tau, R_xy, 'r-', label='R_xy(τ)')
plt.title('x(t)与h(t)的互相关函数')
plt.xlabel('τ')
plt.legend()
plt.grid(True)
plt.subplot(2, 2, 3)
plt.plot(tau, R_yx, 'g-', label='R_yx(τ)')
plt.title('h(t)与x(t)的互相关函数')
plt.xlabel('τ')
plt.legend()
plt.grid(True)
plt.subplot(2, 2, 4)
plt.plot(tau, R_yy, 'm-', label='R_yy(τ)')
plt.title('h(t)的自相关函数')
plt.xlabel('τ')
plt.legend()
plt.grid(True)
plt.tight_layout()
plt.show()
图 10:相关函数计算结果

图 11:LTI 系统时域分析思维导图
通过本章学习,我们掌握了 LTI 连续系统的时域分析方法,包括微分方程求解、零输入响应与零状态响应的计算、冲激响应与阶跃响应的概念,以及卷积积分及其性质。这些方法为后续频域和复频域分析奠定了基础。