SymPy: разобрать строку как функцию на многообразии

Я пытаюсь определить уравнение на многообразии, используя SymPy и пакет SygePy diffgeom. Поскольку это уравнение вводится пользователем, оно отправляется в программу в виде строки и поэтому определяется до определения многообразия в коде. Чтобы выполнить осмысленные вычисления, я пытаюсь заменить "упрощенные" символы символами, определенными на коллекторе.

Вот функция, предоставленная пользователем.

H = sympify('m*a - f')

Координаты для коллектора также предоставляются пользователем в виде строк.

# Variables defined as symbols (non-diffgeom)
a = Symbol('a')
f = Symbol('f')

И все впоследствии автоматизировано.

from sympy.diffgeom import Manifold, Patch, CoordSystem
from sympy import sympify, Symbol
# Standard manifold definitions
M = Manifold(name='Temp', dim=2)
P = Patch('P', M)
R = CoordSystem('R', P, ['a','f'])
coords = R.coord_functions()
Dx = R.base_vectors()

print(H.diff(a)) # Returns 'm' as expected
print(Differential(H)(Dx[0])) # Returns '0' as expected

Первая замена отлично работает. Я могу взять производные, как и ожидалось, используя Дифференциал ().

H = H.subs(a,coords[0])

print(H.diff(a)) # Returns '0' as expected
print(Differential(H)(Dx[0])) # Returns 'm' as expected
print(Differential(H)(Dx[1])) # Returns '0' as expected

Вторая замена - то, где вещи становятся странными. Команда ().diff() работает нормально и возвращает 0, так как новые координаты определены на многообразии, а не как стандартные символы, но я больше не могу брать производные с помощью Differential().

H = H.subs(f,coords[1])

print(H.diff(f)) # Returns '0' as expected
print(Differential(H)(Dx[0])) # Crashes code
print(Differential(H)(Dx[1])) # Also crashes code

Похоже, что diffgeom пытается выполнить преобразование для вычисления производных, но на самом деле преобразование не должно происходить, поскольку все они находятся в одной и той же системе координат. Я что-то здесь упускаю? Или есть более простой способ разбирать строки как выражения на многообразиях?

Вот полная ошибка. Я действительно не могу извлечь из этого ничего, кроме того, что SymPy пытается преобразовать координаты, когда я этого не ожидаю.

Traceback (most recent call last):
  File "/Users/msparapa/Documents/Python/gprops/examples/test.py", line 37, in <module>
    print(Differential(H)(Dx[0])) # Crashes code
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/diffgeom/diffgeom.py", line 765, in __call__
    return vector_fields[0].rcall(self._form_field)
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/core/basic.py", line 538, in rcall
    return Basic._recursive_call(self, args)
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/core/basic.py", line 552, in _recursive_call
    return expr_to_call(*on_args)
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/diffgeom/diffgeom.py", line 592, in __call__
    jac = self._coord_sys.jacobian(b._coord_sys, coords)
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/diffgeom/diffgeom.py", line 277, in jacobian
    to_sys, self._dummies).jacobian(self._dummies)
  File "/Users/msparapa/anaconda/lib/python3.5/site-packages/sympy/diffgeom/diffgeom.py", line 270, in coord_tuple_transform_to
    transf = self.transforms[to_sys]
KeyError: CoordSystem(R, Patch(P, Manifold(Temp, 2)), (a, f))

1 ответ

Решение

После дальнейшего расследования причиной были символы с тем же именем. Исправление заключается в том, чтобы по существу заменить с помощью методов, описанных здесь, или использовать различные соглашения об именах.

Чтобы выполнить замену, мне нужно было поменять местами все переменные одновременно. Это было сделано с помощью следующего блока кода.

set = dict(zip([a,f],coords))
H = H.subs(set, simultaneous=True)

Где "а" и "f" - основные символы, а "координаты" - это список символов на многообразии. Замены не выполняются одновременно, а скорее последовательно, такие как

set = dict(zip([a,f],coords))
H = H.subs(set)

кинь ту же ошибку. Я полагаю, что это связано с тем, что и "а", и "f" скрыты в каждой координате многообразия. Чтобы увидеть, где это происходит, мы можем посмотреть на вывод Repr для ords[0].

BaseScalarField(CoordSystem(Symbol('R'), Patch(Symbol('P'), Manifold(Symbol('M'), Integer(2))), Tuple(Symbol('f'), Symbol('a'))), Integer(0))

Символ ('f') и Символ ('a') отображаются в системе координат. Здесь происходит то, что, когда я подставлял вторую переменную f в своем выражении, SymPy просматривал переменную моего многообразия a и видел переменную с тем же именем. Таким образом, он попытался заменить не только базовый символ f, но и символ f, скрытый в моем определении CoordSystem, возможно, затем вызвав преобразование системы координат.

Другие вопросы по тегам