Как упростить векторы симпты? - PullRequest
4 голосов
/ 21 мая 2019

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

from sympy.physics.mechanics import ReferenceFrame, dot, cross
from sympy import symbols, sin, cos, simplify

alpha, theta, l = symbols('alpha theta l')

def Rodrigues(v, k, angle):
    return cos(angle) * v + cross(k, v) * sin(angle) + k * dot(k, v) * (1- cos(angle))

N = ReferenceFrame('N')
P0 = -l * N.y

P2 = Rodrigues(
    Rodrigues(P0, -N.z, alpha), 
    Rodrigues(N.x, -N.z, alpha), 
    theta)

, который возвращает:

         <img src="https://i.stack.imgur.com/23bEd.png" width="500" />

пробуя simplify(P2) я получаю ошибку:

AttributeError: у объекта 'function' нет атрибута 'x'

Я считаю, что simplify требует объекта выражения sympy. при попытке dir(P2) существует метод simplify, который возвращает:

<bound method Vector.simplify of - l*sin(alpha)*cos(theta)*N.x - l*cos(alpha)*cos(theta)*N.y + (-l*sin(alpha)**2 - l*cos(alpha)**2)*sin(theta)*N.z>

который я понятия не имею, что это такое! пытаясь P2.args я получаю:

[(Matrix([
  [                       -l*sin(alpha)*cos(theta)],
  [                       -l*cos(alpha)*cos(theta)],
  [(-l*sin(alpha)**2 - l*cos(alpha)**2)*sin(theta)]]), N)]

, который является одномерным списком двумерного кортежа с вложенной матрицей 3x1 sympy! Я не знаю, чей выбор состоял в том, чтобы сделать векторный класс таким неясным, но теперь я могу упростить последний элемент с помощью simplify(P2.args[0][0][2]) и изменить функцию на:

def Rodrigues(v, k, angle):
    tmpVec = cos(angle) * v + cross(k, v) * sin(angle) + k * dot(k, v) * (1- cos(angle))
    tmpFrame = tmpVec.args[0][1]
    return simplify(tmpVec.args[0][0][0]) * tmpFrame.x + simplify(tmpVec.args[0][0][1]) * tmpFrame.y + simplify(tmpVec.args[0][0][2]) * tmpFrame.z

что мне кажется очень плохим решением.

Мне было интересно, не могли бы вы помочь мне узнать, есть ли более Pythonic способ сделать это. Например, заставьте sympy упростить все выражения по умолчанию. Или, может быть, я неправильно использую метод vector.simplify? Заранее спасибо за вашу поддержку.

P.S. Родригес формула вращения

Ответы [ 2 ]

1 голос
/ 22 мая 2019

Вместо print(P2.simplify) вам нужно вызвать этот метод как print(P2.simplify()).После этого вы получите - l*sin(alpha)*cos(theta)*N.x - l*cos(alpha)*cos(theta)*N.y - l*sin(theta)*N.z как вывод, который совпадает с последней версией вашего def Rodrigues.

0 голосов
/ 29 мая 2019

Альтернативное решение состоит в том, чтобы заставить sympy упростить все векторы по умолчанию:

from sympy.physics.vector import Vector
Vector.simp = True

подробнее здесь

...