首页 文章

用矩阵代替SymPy中的标量

提问于
浏览
1

这是我在SymPy会话中所做的事情:

from sympy import *
xi1,xi2,xi3 = symbols('xi_1,xi_2,xi_3')
N1 = 1-xi1-xi2-xi3
N2 = xi3
N3 = xi1
N4 = xi2
x1,x2,x3,x4 = symbols('x_1, x_2, x_3, x_4')
x = N1*x1+N2*x2+N3*x3+N2*x4
subdict = {x1:Matrix([0.025,1.0,0.0]), x2 : Matrix([0,1,0]), x3:Matrix([0, 0.975, 0]), x4:Matrix([0,0.975,0.025])}
x.subs(subdict)
test.subs({xi1:1, xi2:0,xi3:0})

对我来说,我们只是将一些标量与一些向量相乘,然后将它们相加 . 然而,SymPy会不同意并抛出一个巨大的错误,最后一行是:

TypeError: cannot add <class 'sympy.matrices.immutable.ImmutableDenseMatrix'> and <class 'sympy.core.numbers.Zero'>

为什么这是个问题?我正在尝试做什么的解决方法?

1 回答

  • 1

    我怀疑发生的事情是在矩阵被替换之前你用0代替 0*matrix_symbol = 0 而不是零的矩阵 . 最终为矩阵的术语不能添加到0,从而导致错误 . 我尝试使用 simultaneous 标志或xreplace而不是subs给出了相同的结果(在sympy.live.org上) . 然后我尝试以相反的顺序进行替换,首先将它们作为带有矩阵的列表传递 . 仍然没有奏效 . 看起来sub假设 0*foo 为0.如果尚未存在问题,则应该引发sympy issues的问题 .

    解决方法是首先进行标量替换,允许零项消失 . 然后用矩阵做一个子 . 所以这需要2次调用潜艇 .

    使用0替换的真正的,hackish变通方法是这样的:

    def remul(m):
      rv = 1
      for i in m.args:
        rv *= i
      return rv
    
    expr = x*y
    mat = expr.subs(x, randMatrix(2)) # replace x with matrix
    expr = mat.replace( # replace y with scalar 0
        lambda m: m.is_Mul,
        lambda m: remul(Mul(*[i.subs(y, 0) for i in m.args], evaluate=False)))
    

相关问题