【问题标题】:sympy: Collect symbols for matrix coefficients?sympy:收集矩阵系数的符号?
【发布时间】:2015-05-13 08:12:33
【问题描述】:

我正在尝试分解一个表达式,并将系数分离为矩阵形式,这样:

Factor sympy expression to matrix coefficients? 密切相关,其中Wild 符号与match(form) 一起用于确定其矩阵形式的系数。但是,我无法让 match(form) 方法适用于以下情况。

为什么match(form) 方法会失败?

有什么干净的替代方法可以做到这一点?

#Linear Interpolation function: V(x)
v_1, theta_1, v_2, theta_2, x, L = symbols("v_1, theta_1, v_2, theta_2, x, L")
a_1, a_2, a_3, a_4 = symbols("a_1, a_2, a_3, a_4", real=True)
V = a_1*x**0 + a_2*x**1 + a_3*x**2 + a_4*x**3
#Solve for coefficients (a_1, a_2, a_3, a_4) with BC's: V(x) @ x=0, x=L
shape_coeffs = solve([Eq(v_1, V.subs({x:0})), 
                      Eq(theta_1, V.diff(x).subs({x:0})), 
                      Eq(v_2, V.subs({x:L})), 
                      Eq(theta_2, V.diff(x).subs({x:L}))], 
                     (a_1, a_2, a_3, a_4))
V = V.subs(shape_coeffs)
#Factor to matrix
V = sympy.collect(sympy.expand(V), (v_1, theta_1, v_2, theta_2))

并收集术语,直到矩阵形式明显。匹配表格:

C_1, C_2, C_3, C_4 = symbols("C_1, C_2, C_3, C_4", cls=Wild)
form = c_1*v_1 + c_2*theta_1 + c_3*v_2 + c_4*theta_2
mat_coeffs = V.match(form)
N = Matrix([C_1, C_2, C_3, C_4]).transpose()
N = N.subs(mat_coeffs)
v = Matrix([v_1, theta_1, v_2, theta_2])

与引用的问题 V.match(form) 不同,它返回 None 而不是包含 {C_1:f(x), C_2:f(x), C_3:f(x), C_4:f(x)}dict()。为什么会失败? -- 通过检查,解决方案是显而易见的。

【问题讨论】:

    标签: matrix sympy symbolic-math polynomial-math


    【解决方案1】:

    由于collect(expand(V), ...) 已经将V 显示为变量v_1, theta_1, v_2, theta_2 中的线性多项式,而不是使用V.match(form),或许更简单、更直接的获取系数的方法是使用V.coeff 方法:

    N = sy.Matrix([V.coeff(v) for v in (v_1, theta_1, v_2, theta_2)]).transpose()
    

    import sympy as sy
    #Linear Interpolation function: V(x)
    v_1, theta_1, v_2, theta_2, x, L = sy.symbols(
        "v_1, theta_1, v_2, theta_2, x, L")
    a_1, a_2, a_3, a_4 = sy.symbols("a_1, a_2, a_3, a_4", real=True)
    V = a_1*x**0 + a_2*x**1 + a_3*x**2 + a_4*x**3
    #Solve for coefficients (a_1, a_2, a_3, a_4) with BC's: V(x) @ x=0, x=L
    shape_coeffs = sy.solve([sy.Eq(v_1, V.subs({x:0})), 
                          sy.Eq(theta_1, V.diff(x).subs({x:0})), 
                          sy.Eq(v_2, V.subs({x:L})), 
                          sy.Eq(theta_2, V.diff(x).subs({x:L}))], 
                         (a_1, a_2, a_3, a_4))
    V = V.subs(shape_coeffs)
    V = sy.collect(sy.expand(V), (v_1, theta_1, v_2, theta_2))
    N = sy.Matrix([V.coeff(v) for v in (v_1, theta_1, v_2, theta_2)]).transpose()
    print(N)
    

    产量

    Matrix([[1 - 3*x**2/L**2 + 2*x**3/L**3, x - 2*x**2/L + x**3/L**2, 3*x**2/L**2 - 2*x**3/L**3, -x**2/L + x**3/L**2]])
    

    【讨论】:

    • 优秀的解决方案:我有一个使用 .coeff() 的方法,但是如果没有您的列表理解,它有点混乱。 .coeff() 似乎是所有情况下最稳定的。不过,您猜到为什么.match(form) 会失败吗?任何一种方法都有优势吗?再次感谢。
    • 抱歉,我不太了解.match(form) 的实现方式。查找多项式的系数具有确定性(保证成功)算法。模式匹配是一个更开放的问题。因此,如果一个问题适用于这两种方法——只要V 可以表示为vtheta 变量中的多项式——我肯定会选择使用.coeff()
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-24
    • 1970-01-01
    • 1970-01-01
    • 2019-06-04
    • 1970-01-01
    相关资源
    最近更新 更多