将Sympy表达式因式分解为矩阵系数?

4
我已经努力查看文档,但却毫无结果。
我正在尝试将一个表达式因式分解或消除项,转换为矩阵形式。我的问题似乎与多项式因式分解不同(因为我计划实现一个函数 phi(x,y,z) = a_1 + a_2*x + a_3*y + a_4*z)。
import sympy
from sympy import symbols, pprint
from sympy.solvers import solve

phi_1, phi_2, x, a_1, a_2, L = symbols("phi_1, phi_2, x, a_1, a_2, L")

#Linear Interpolation function: phi(x)
phi = a_1 + a_2*x
#Solve for coefficients (a_1, a_2) with BC's: phi(x) @ x=0, x=L
shape_coeffs = solve([Eq(phi_1, phi).subs({x:0}), Eq(phi_2, phi).subs({x:L})], (a_1, a_2))
pprint(shape_coeffs)
#Substitute known coefficients
phi = phi.subs(shape_coeffs)
pprint(phi)

这段代码的功能正常,但我希望把它转换成矩阵形式,其中:

Current and Desired

我尝试使用factor()cancel()as_coefficient()但都没有成功。在纸上,这是一个微不足道的问题。请问sympy解决方案中我漏掉了什么?谢谢。

一种有效的方法:作为答案采纳

C_1, C_2 = symbols("C_1, C_2", cls=Wild)
N = Matrix(1,2, [C_1, C_2])
N = N.subs(phi.match(C_1*phi_1 + C_2*phi_2))
phi_i = Matrix([phi_1, phi_2])
display(Math("\phi(x)_{answered} = " + latex(N) + "\ * " + latex(phi_i)))

Correct Answer Output

2个回答

5

我的第一个答案使用phi.match(form)来查找系数,但是当匹配许多Wild符号时似乎不太好用。因此,我认为更好的方法是使用phi = collect(expand(...)),然后使用phi.coeff来查找系数:

import sympy as sy

phi_1, phi_2, x, a_1, a_2, L = sy.symbols("phi_1, phi_2, x, a_1, a_2, L")

phi = a_1 + a_2*x
shape_coeffs = sy.solve([sy.Eq(phi_1, phi).subs({x:0}), sy.Eq(phi_2, phi).subs({x:L})], (a_1, a_2))
phi = phi.subs(shape_coeffs)

phi = sy.collect(sy.expand(phi), phi_1)
N = sy.Matrix([phi.coeff(v) for v in (phi_1, phi_2)]).transpose()
print(N)

产量
Matrix([[1 - x/L, x/L]])

我将其标记为答案,但在尝试使用更多的通配符和符号实现解决方案时,匹配返回None。我发布了一个新问题,因为我不确定'SO'的惯例:https://dev59.com/z4rda4cB1Zd3GeqPRMsr - OnStrike

1

这是基于此帖子中先前答案的内容。此处的函数接受一个向量(sympy.Matrix)作为输入,并且对应的系数也表示为向量(sympy.Matrix),以分解和提取矩阵A,使得vec = A @ coeffs

import sympy as sp 

def factorize_vec(vec:sp.Matrix, coeffs:sp.Matrix):
    '''
    Factorize a vector into the product of a matrix and its coefficients. 

    Parameters
    ----------
    - `vec` : column vector of equations
    - `coeffs` : column vector of coefficients to factorize 

    Return
    ------
    - `A` : vec = A@coeffs
    '''
    A = sp.zeros(len(vec),len(coeffs))
    for i,v in enumerate(vec):
        expr = sp.collect(sp.expand(v), syms=coeffs[:])
        for j,c in enumerate(coeffs):
            A[i,j] = expr.coeff(coeffs[j]) 
    return A 


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接