求解微分方程时如何正确拼接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
相关产品推荐
相关产品推荐

