如何用Numpy实现类Matlab的矩阵迭代?解决代码报错与绘图疑问
问题1:矩阵迭代的形状不匹配报错
你的报错核心是运算结果形状与目标数组形状不兼容:
np.dot(Ad, x[:, k])的结果是(2,)(假设Ad是2×2矩阵,x[:,k]是(2,)的一维数组)- 但
Bd*u[k]的运算结果是(2,2),两者相加后得到(2,2)的数组,而x[:, k+1]是(2,)的位置,自然无法完成广播赋值。
大概率是以下两种情况之一:
- Bd维度错误:离散系统中Bd应为「状态维度×输入维度」的矩阵(比如单输入系统对应2×1),如果误定义成2×2,乘以标量
u[k]后会变成2×2数组。 - u[k]形状错误:如果u是
(N,1)的二维数组,u[k]会是(1,)的一维数组,当Bd是2×1时,Bd*u[k]会广播成2×1数组,和np.dot(Ad, x[:,k])的(2,)形状无法直接相加。
修正方案:
- 先确认Bd维度:单输入系统下,Bd必须是
(2,1)的矩阵(而非(2,)或(2,2))。 - 对
u[k]做降维处理:用u[k, 0]或u[k].item()获取标量值;或者初始化u时直接用一维数组(比如u = np.zeros(N)而非np.zeros((N,1)))。
修正后的迭代代码示例:
# 假设Ad是2×2,Bd是2×1,x是(2, N+1)的状态矩阵,u是(N,)的一维输入数组 x[:, k+1] = np.dot(Ad, x[:, k]) + Bd * u[k] # 若u是(N,1)的二维数组,改用: x[:, k+1] = np.dot(Ad, x[:, k]) + Bd * u[k, 0]
问题2:绘图时为何需要
u[:, 0] 这是因为matplotlib的plot函数对一维、二维数组的处理逻辑不同:
- 如果u是
(N,1)的二维列向量(矩阵式初始化的常见结果),直接传入u的话,matplotlib会将其视为「包含1个数据集的二维数组」(每一列对应一条曲线),虽然能运行,但不符合plot对y轴输入的最优格式要求。 u[:, 0]是把二维列向量转换成(N,)的一维数组,和x轴的tk一维数组形状完全匹配,是plot函数最期望的输入形式。
如果不想用索引,也可以用u.flatten()或u.squeeze()直接将二维数组转成一维:
plt.plot(tk, u.squeeze(), label='u')
内容的提问来源于stack exchange,提问作者Ricardo
相关产品推荐
相关产品推荐

