将Matlab矩阵转换为numpy数组时遇到值错误问题求解
Matlab转Python后含参矩阵条件数计算报错的排查与修复
错误根因
- 核心问题是NumPy数组与SymPy符号对象混用:
np.array()是为数值计算设计的,当数组元素包含SymPy符号表达式时,会被存为通用object类型数组,这类数组本身没有SymPy对象专属的.subs()变量替换方法,调用时直接触发ValueError。 - 自动转换生成的代码存在冗余问题:外层包裹的
eval()没有任何实际作用,只会增加解析出错的概率;如果目标是批量计算多个f取值下的矩阵条件数,用SymPy做符号替换的方案运算效率极低,完全不适合批量计算场景。 - 转换工具生成的
np.multiply属于冗余调用,标量乘法直接用*即可实现相同效果,不需要额外调用函数。
可行解决方案
方案1:保留符号矩阵形式(适合需要符号推导的场景)
不要用NumPy数组存储符号表达式,直接使用SymPy原生的Matrix类构造矩阵,原生支持符号替换操作,替换完成后再转为NumPy浮点数组即可计算条件数,示例代码如下:
import numpy as np from sympy import symbols, Matrix f = symbols('f') # 直接用SymPy Matrix构造符号矩阵,去掉无意义的eval和np.array包裹 Rarz = Matrix([ [(-640227.0) + 195.539*f**2, 4211.96 + (-6.45961e-14)*f**2, (-5469.12) + (-6.30001e-14)*f**2, (-7178.23) + (-1.0631e-12)*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.683542,0.0,0.151787], [4211.96 + (-6.45961e-14)*f**2, (-10147500.0) + 193.704*f**2, (-2958.16) + (-3.10464e-13)*f**2, (-3882.6) + 1.14274e-12*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.369718,0.0,(-0.947078)], [(-5469.12) + (-6.30001e-14)*f**2, (-2958.16) + (-3.10464e-13)*f**2, (-51372700.0) + 193.708*f**2, 5041.45 + (-2.10639e-12)*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-0.480068),0.0,(-1.22348)], [(-7178.23) + (-1.0631e-12)*f**2, (-3882.6) + 1.14274e-12*f**2, 5041.45 + (-2.10639e-12)*f**2, (-162352000.0) + 193.695*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-0.630091),0.0,1.0085], [0.0,0.0,0.0,0.0,(-1629440000.0) + 154.953*f**2, (-11753.4) + 0.000111686*f**2, 25800.5 + (-6.59562e-05)*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-9.50724e-06)], [0.0,0.0,0.0,0.0,(-11753.4) + 0.000111686*f**2, (-12381300000.0) + 154.953*f**2, (-73445.5) + 5.30086e-05*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,9.27121e-05], [0.0,0.0,0.0,0.0,25800.5 + (-6.59562e-05)*f**2, (-73445.5) + 5.30086e-05*f**2, (-47583200000.0) + 154.953*f**2, 0.0,0.0,0.0,0.0,0.0,0.0,3.63798e-12,(-0.000219237)], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-1239040000.0) + 194.525*f**2, 969793000.0 + (-151.126)*f**2, 0.0,0.0,0.0,0.0,(-0.680346),0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,969793000.0 + (-151.126)*f**2, (-4199830000.0) + 227.587*f**2, 0.0,0.0,0.0,0.0,1.33685e-12,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-12337000000.0) + 77.4764*f**2, 0.0,0.0,(-1.22465e-16),0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,(-49348000000.0) + 77.4764*f**2, 0.0,2.44929e-16,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,(-111033000000.0) + 77.4764*f**2, (-3.67394e-16),0.0,0.0], [0.683542,0.369718,(-0.480068),(-0.630091),0.0,0.0,0.0,0.0,0.0,(-1.22465e-16),2.44929e-16,(-3.67394e-16),0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,3.63798e-12,(-0.680346),1.33685e-12,0.0,0.0,0.0,0.0,0.0,0.0], [0.151787,(-0.947078),(-1.22348),1.0085,(-9.50724e-06),9.27121e-05,(-0.000219237),0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] ]) # 符号替换 kk_sym = Rarz.subs({f:2}) # 转为NumPy浮点数组 kk = np.array(kk_sym, dtype=np.float64) # 计算条件数 cond_num = np.linalg.cond(kk) print(cond_num)
方案2:纯数值实现(推荐,适合批量计算多f值的条件数)
你的矩阵所有元素都是f的二次函数,形式统一为常数项 + 二次项系数 * f²,完全没必要引入SymPy做符号运算。提前把所有常数项、二次项系数分别存为两个15*15的NumPy数组,任意f取值下的矩阵直接通过A0 + A2 * f**2就能算出,全是NumPy原生浮点运算,速度比符号替换方案快几个数量级,非常适合批量扫描f取值的需求,示例逻辑如下:
import numpy as np # 构造常数项矩阵A0,逐行填入每个元素不含f的常数部分 A0 = np.array([ [-640227.0, 4211.96, -5469.12, -7178.23, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.683542,0.0,0.151787], [4211.96, -10147500.0, -2958.16, -3882.6, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.369718,0.0,-0.947078], [-5469.12, -2958.16, -51372700.0, 5041.45, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.480068,0.0,-1.22348], [-7178.23, -3882.6, 5041.45, -162352000.0, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-0.630091,0.0,1.0085], [0.0,0.0,0.0,0.0,-1629440000.0, -11753.4, 25800.5, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,-9.50724e-06], [0.0,0.0,0.0,0.0,-11753.4, -12381300000.0, -73445.5, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,9.27121e-05], [0.0,0.0,0.0,0.0,25800.5, -73445.5, -47583200000.0, 0.0,0.0,0.0,0.0,0.0,0.0,3.63798e-12,-0.000219237], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1239040000.0, 969793000.0, 0.0,0.0,0.0,0.0,-0.680346,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,969793000.0, -4199830000.0, 0.0,0.0,0.0,0.0,1.33685e-12,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-12337000000.0, 0.0,0.0,-1.22465e-16,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-49348000000.0, 0.0,2.44929e-16,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,-111033000000.0, -3.67394e-16,0.0,0.0], [0.683542,0.369718,-0.480068,-0.630091,0.0,0.0,0.0,0.0,0.0,-1.22465e-16,2.44929e-16,-3.67394e-16,0.0,0.0,0.0], [0.0,0.0,0.0,0.0,0.0,0.0,3.63798e-12,-0.680346,1.33685e-12,0.0,0.0,0.0,0.0,0.0,0.0], [0.151787,-0.947078,-1.22348,1.0085,-9.50724e-06,9.27121e-05,-0.000219237,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0] ], dtype=np.float64) # 构造f²项系数矩阵A2,逐行填入每个元素f²对应的系数 A2 = np.array([ [195.539, -6.45961e-14, -6.30001e-14, -1.0631e-12, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [-6.45961e-14, 193.704, -3.10464e-13, 1.14274e-12, 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0], [-6.30001e-14, -3.104
相关产品推荐
相关产品推荐

