You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求解微分方程时如何正确拼接4个矩阵为正常显示的大矩阵?

问题描述

在以矩阵形式求解微分方程时,尝试将4个小矩阵拼接为一个大矩阵,打印结果格式混乱,无法判断拼接是否正确。

代码示例

import numpy as np
from sympy import *
from sympy import init_printing
# from scipy.integrate import odeint
from scipy.integrate import solve_ivp
init_printing()

params = {'m1': 1, 'm2': 2, 'k1': 1, 'k2': 2, 'c1': 0.1, 'c2': 0.1} 
params.update({'N' : 3}) 
params['dimM'] = 4*params['N'] 


##---------------------------------------## M1 和 M2 ##--------------------------------------------------##
M1 = np.zeros([2*params['N'],2*params['N']])
print('M1 = \n', M1)

M2 = np.eye(2*params['N'])
print('M2 = \n', M2)

# 偶数索引使用m1
# 奇数索引使用m2

##---------------------------------------## M3 ##--------------------------------------------------------##

v3 = np.zeros(2*params['N'])
v3[::2]= -(params['k1']/params['m2'] - params['k2']/params['m2'])
v3[1::2]= -(params['k1']/params['m1'] - params['k2']/params['m1'])
print("向量v3:", v3, "\n")

v3_b = np.zeros(2*params['N']-1)
v3_b[::2] = params['k2']/params['m1']
v3_b[1::2] = params['k1']/params['m2']
print("向量v3_b:", v3_b, "\n")

M3 = np.diag(v3, 0) + np.diag(v3_b, +1) + np.diag(v3_b, -1)
print('M3 = \n', M3)

##---------------------------------------## M4 ##--------------------------------------------------------##

v4 = np.zeros(2*params['N'])
v4[::2]= -(params['c1']/params['m2'] - params['c2']/params['m2'])
v4[1::2]= -(params['c1']/params['m1'] - params['c2']/params['m1'])
print("向量v4:", v4, "\n")

v4_b = np.zeros(2*params['N']-1)
v4_b[::2] = params['c2']/params['m1']
v4_b[1::2] = params['c1']/params['m2']
print("向量v4_b:", v4_b, "\n")

M4 = np.diag(v4, 0) + np.diag(v4_b, +1) + np.diag(v4_b, -1)
print('M4 = \n', M4)

##---------------------------------------## 完整矩阵 M ##----------------------------------------##

M = [[M1, M2], [M3,M4]]
print('M = \n', M)

错误输出

M = 
 [[array([[0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0., 0.]]), array([[1., 0., 0., 0., 0., 0.],
       [0., 1., 0., 0., 0., 0.],
       [0., 0., 1., 0., 0., 0.],
       [0., 0., 0., 1., 0., 0.],
       [0., 0., 0., 0., 1., 0.],
       [0., 0., 0., 0., 0., 1.]])], [array([[0.5, 2. , 0. , 0. , 0. , 0. ],
       [2. , 1. , 0.5, 0. , 0. , 0. ],
       [0. , 0.5, 0.5, 2. , 0. , 0. ],
       [0. , 0. , 2. , 1. , 0.5, 0. ],
       [0. , 0. , 0. , 0.5, 0.5, 2. ],
       [0. , 0. , 0. , 0. , 2. , 1. ]]), array([[0.  , 0.1 , 0.  , 0.  , 0.  , 0.  ],
       [0.1 , 0.  , 0.05, 0.  , 0.  , 0.  ],
       [0.  , 0.05, 0.  , 0.1 , 0.  , 0.  ],
       [0.  , 0.  , 0.1 , 0.  , 0.05, 0.  ],
       [0.  , 0.  , 0.  , 0.05, 0.  , 0.1 ],
       [0.  , 0.  , 0.  , 0.  , 0.1 , 0.  ]])]]
解决方案

1. 错误原因

[[M1, M2], [M3,M4]]创建的是嵌套列表,并非真正的numpy矩阵,打印时会显示每个子矩阵的array标识,导致格式混乱。必须使用numpy提供的矩阵拼接函数生成完整大矩阵。

2. 正确拼接方法

方法一:使用np.block()(推荐)

该函数支持直观的块拼接语法,和你写的嵌套列表结构完全一致:

# 替换原有的M定义
M = np.block([[M1, M2], [M3, M4]])

方法二:组合np.hstack和np.vstack

先横向拼接每行的子矩阵,再纵向拼接两行:

top_row = np.hstack([M1, M2])  # 拼接第一行的M1和M2
bottom_row = np.hstack([M3, M4])  # 拼接第二行的M3和M4
M = np.vstack([top_row, bottom_row])  # 拼接两行成大矩阵

3. 优化显示格式

方式一:设置numpy打印选项

控制小数位数、对齐方式,让输出更整洁:

# 设置打印格式:保留2位小数,对齐显示,抑制科学计数法
np.set_printoptions(precision=2, suppress=True, formatter={'float': '{:>6.2f}'.format})
print('M = \n', M)

方式二:用sympy转换为数学格式打印

如果需要更美观的数学排版,可将numpy矩阵转为sympy的Matrix:

from sympy import Matrix
print('M = \n', Matrix(M))

修改后的完整代码片段

##---------------------------------------## 完整矩阵 M ##----------------------------------------##

# 正确拼接大矩阵
M = np.block([[M1, M2], [M3, M4]])

# 设置numpy打印格式
np.set_printoptions(precision=2, suppress=True, formatter={'float': '{:>6.2f}'.format})

print('M = \n', M)

内容的提问来源于stack exchange,提问作者Nicolas Eveno EnfantNicolas

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:59:55