SymPy 用 Symbol 代替 Vector [英] SymPy substitute Symbol for Vector

查看:32
本文介绍了SymPy 用 Symbol 代替 Vector的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在下面的代码中有一个 Mul 类型的表达式,称为 term.在term 中是一个类型Symbol,称为zhat.我想执行类似 term.subs(zhat, vec) 的操作,其中 vecBaseVector 类型.我正在为向量添加一个符号.输出分配给代码中的 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_actualMul 类型.变量 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 类的方法,只查看所有参数(例如 Qcode>, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆