SymPy заменяет символ на вектор - PullRequest
1 голос
/ 11 июля 2020

У меня есть выражение типа Mul с именем term в приведенном ниже коде. Внутри term находится тип Symbol, называемый zhat. Я хочу выполнить что-то вроде term.subs(zhat, vec), где vec имеет тип BaseVector. Я заменяю символ вектором. В коде выходу назначается out_actual.

Проблема в том, что out_actual имеет тип Mul, когда мне нужно, чтобы он был типа VectorMul. Переменная out_ideal - это то, что я ожидал от замены. Любым способом получить 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)

1 Ответ

1 голос
/ 11 июля 2020

Это не особенно приятно или обобщать, но вы можете сделать следующее, чтобы преобразовать любой Mul в VectorMul, когда это необходимо (и оставить его как Mul в противном случае):

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, eps, zhat) объекта Mul ( term) и заменяет каждый, который соответствует цели замены, и дает результат как Mul, но с измененным списком args (т.е. zhat был заменен на vec). Он не выполняет никакой дальнейшей оценки результата и оставляет аргумент как Mul.

Чтобы преобразовать его в VectorMul, вы можете просто вручную перемножить полученные аргументы вместе, как вы это делали. чтобы получить out_ideal. Все, что делает multiply_args, - это вручную умножает аргументы вместе, что затем увеличивает до VectorMul, если какой-либо из аргументов равен Vector. Очевидно, это работает только потому, что вы знаете, что начали с Mul; вам нужно будет обобщить это, чтобы иметь дело с другими типами, если вам нужно.

Может, стоит добавить функцию reqeust в репозиторий SymPy Github для этой функции.

...