2015-08-20 2 views
4

Я выполнил некоторые вычисления в sympy, и результат, в конце концов, представляет собой набор констант. Один из них вставляется непосредственно в поле ниже фрагмент кода:Как упростить выражение для комплексной константы с помощью sympy?

from sympy import * 
expr = (18**(Rational(1, 3))/(6*(3 + sqrt(3)*I)**(Rational(1, 3))) 
     + 12**(Rational(1, 3))*(3 + sqrt(3)*I)**(Rational(1, 3))/12) 
print(expr.evalf()) 
print(expr.simplify()) 

Это возвращает

0.56857902130163 + 0.e-22*I 
18**(1/3)/(6*(3 + sqrt(3)*I)**(1/3)) + (36 + 12*sqrt(3)*I)**(1/3)/12 

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

cos(pi/18)/sqrt(3) 

что согласуется с численным значением, возвращенным evalf().

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

expr.subs(3 + sqrt(3)*I, sqrt(12) * exp(I*pi/6)) 

улучшает выражение, но по-прежнему SymPy не может сделать вывод, что это реально. Используя формулу Эйлера для замещения,

expr.subs(3 + sqrt(3)*I, sqrt(12) * (cos(pi/6) + I*sin(pi/6))) 

SymPy наконец-то может сделать вывод, что выражение является реальным, но само выражение взрывает размер при печати (даже если я попытаюсь simplify после замены).

Есть ли лучший способ попытаться уменьшить это? У меня много похожих выражений для сложных констант, которые я хотел бы знать наверняка, являются реальными (или нет).

ответ

4

Для выражения вы дали, команда

(expr.conjugate().conjugate() - expr.conjugate()).simplify() 

возвращает 0, что означает, что выражение является реальным. (Двойное применение сопряжения возвращает к исходному значению, но оно расширяется по пути, что дает возможность последующего упрощения.) В общем случае приведенная выше формула возвращает мнимую часть, умноженную на 2i.

Чтобы найти действительную часть выражения, вы можете использовать подобный трюк: добавить его в конъюгату и упростить (и разделить на 2):

((expr.conjugate().conjugate()+expr.conjugate())/2).simplify() 

возвращается sqrt(3)*cos(pi/18)/3.

+1

Это хорошо работает для выражения, которое я привел в качестве примера. Еще проще: 'expr.conjugate() .contugate(). Simplify(). Trigsimp()' ', которому удается напрямую выводить результат. Однако для более сложных выражений этот сопряженный метод работает не так хорошо, но он по-прежнему полезен. – josteinb

2

Метод as_real_imag часто помогает упростить комплексное число, даже если оно отсутствует в методах упрощения. В вашем примере,

expr.as_real_imag() 

возвращает (sqrt(3)*cos(pi/18)/3, 0)

Если комплексное число желательно (а не кортеж, как описано выше), нельзя просто назвать complex на этом наборе, так как это может создать объект Python complex класс, включающий числовую оценку. Вместо этого я напишу

pair = expr.as_real_imag() 
result = pair[0] + pair[1]*I 
Смежные вопросы