SymPy 用 Symbol 代替 Vector [英] SymPy substitute Symbol for Vector
问题描述
我在下面的代码中有一个 Mul
类型的表达式,称为 term
.在term
中是一个类型Symbol
,称为zhat
.我想执行类似 term.subs(zhat, vec)
的操作,其中 vec
是 BaseVector
类型.我正在为向量添加一个符号.输出分配给代码中的 out_actual
.
I have an expression of type Mul
called term
in the code below. Within term
is a type Symbol
called zhat
. I want to perform something like term.subs(zhat, vec)
where vec
is of type BaseVector
. I am subbing a symbol for a vector. The output is assigned to out_actual
in the code.
问题是当我需要 VectorMul
类型时 out_actual
是 Mul
类型.变量 out_ideal
是我对替换的期望.有什么方法可以获得out_ideal
?
The issue is that out_actual
is of type Mul
when I need it to be of type VectorMul
. The variable out_ideal
is what I would expect from the substitution. Any way to obtain out_ideal
?
import sympy as sp
from sympy.vector import CoordSys3D
N = CoordSys3D('N')
Q, eps, zhat = sp.symbols('Q \epsilon_0 \\hat{\\mathbf{z}}')
vec = N.k
term = Q*eps*zhat
out_ideal = Q*eps*vec
out_actual = term.subs(zhat, vec)
推荐答案
它不是特别令人愉快或通用,但您可以执行以下操作将任何 Mul
转换为 VectorMul
在适当的时候(否则将其保留为 Mul
):
It's not particularly pleasant or generalizable, but you could do the following to convert any Mul
into a VectorMul
whenever appropriate (and leaving it as a Mul
otherwise):
import sympy as sp
from sympy.vector import CoordSys3D
from sympy.core.mul import Mul
N = CoordSys3D('N')
def multiply_args(obj):
'''Gets the result of multiplying all of the Mul's args together.'''
if not isinstance(obj, Mul):
raise ValueError('Input must be an instance of Mul')
args = obj.args
prod = args[0]
for e in args[1:]:
prod = prod * e
return prod
Q, eps, zhat = sp.symbols('Q \epsilon_0 \\hat{\\mathbf{z}}')
vec = N.k
term = Q*eps*zhat
sub_result = term.subs(zhat, vec)
sub_result = multiply_args(sub_result)
这是必要的原因是 subs
,一个属于 Basic
类的方法,只查看所有参数(例如 Q
code>, eps
, zhat
) 的 Mul
对象 (term
) 并替换与替换目标匹配的每个, 并以 Mul
的形式给出结果,但带有修改后的 args
列表(即 zhat
已被替换为 vec
>).它不会对结果做任何进一步的评估,并将参数保留为 Mul
.
The reason this is necessary is that subs
, a method which belongs to the Basic
class, simply looks at all of the arguments (e.g. Q
, eps
, zhat
) of the Mul
object (term
) and replaces each that matches the substitution target, and gives the result as a Mul
but with an amended list of args
(i.e. zhat
has been replaced with vec
). It doesn't do any further evaluation on the result, and leaves the argument as a Mul
.
要将其转换为 VectorMul
,您只需手动将结果参数相乘,就像获得 out_ideal
一样.multiply_args
所做的就是手动将这些参数相乘,如果其中任何一个参数是 Vector
,则将其提升为 VectorMul
.显然这只是因为你知道你已经开始使用 Mul
;如果需要,您需要对此进行概括以处理其他类型.
To convert it to a VectorMul
, you can just multiply the resulting arguments together manually, like you did to get out_ideal
. All multiply_args
does is manually multiplies the arguments together, which then promotes to a VectorMul
if any of the arguments is a Vector
. Obviously this only works because you know you have started with a Mul
; you'd need to generalize this to deal with other types if you needed to.
如果值得为此功能向 SymPy Github 存储库提交功能请求.
If could be worth putting in a feature reqeust to the SymPy Github repository for this functionality.
这篇关于SymPy 用 Symbol 代替 Vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!