Сбор выражения дроби внутри большей дроби (симпи)

Я использую IPython (дистрибутив Anaconda) с символьной математической библиотекой.

У меня есть такое выражение:

       t⋅(h + l)       
───────────────────────
l⋅(h + l⋅sin(θ))⋅cos(θ)

Я хотел бы изменить это, чтобы получить его в терминах (h/l) и (t/l):

    (t/l)⋅((h/l)+1)
─────────────────────
((h/l)+sin(θ))⋅cos(θ)

Это довольно легко сделать вручную; просто разделите обе части дроби на l и переставьте.

До сих пор мне не везло со встроенными функциями sympy.

Я пробовал использовать expand, за которым следует collect(expr,h/l), но это не меняет выражения. Я подозреваю, что это не сработает, потому что нет h/l терминов, которые нужно было бы собирать.

Как мне добиться этого?

Код Python для первого выражения, чтобы сэкономить ваше время: t*(h + l)/(l*(h + l*sin(theta))*cos(theta))


person binnev    schedule 16.09.2015    source источник


Ответы (3)


Основываясь на идее Страббли:

In [2]: expr = t *(h +l )/(l *(h +l *sin (theta ))*cos (theta ))

In [3]: expr
Out[3]: 
           t*(h + l)           
-------------------------------
l*(h + l*sin(theta))*cos(theta)

In [4]: repl1 = [x-h/l, y-t/l]

In [7]: repl2 = solve(repl1, t, l)

In [8]: repl2
Out[8]: 
    h     h*y 
{l: -, t: ---}
    x      x  
In [9]: simplify(expr.subs(repl2)).subs({x: h/l, y: t/l})
Out[9]: 
            /h    \          
          t*|- + 1|          
            \l    /          
-----------------------------
  /h             \           
l*|- + sin(theta)|*cos(theta)
  \l             /   

То есть введите две переменные x и y, чтобы заменить h / l и t / l (в [4 ]), инвертируйте равенства, чтобы получить словарь замены (В [7]). Замените, упростите (чтобы избавиться от l), затем верните исходные значения для x и y. Одна переменная все еще упрощается.

Следует указать .subs (...) не оценивать выражение после замены. Я не знаю, поддерживается ли это в настоящее время.

person Francesco Bonazzi    schedule 17.09.2015
comment
Хорошо, это определенно работает, но я хочу убедиться, что понимаю, что происходит, прежде чем полностью доверять этому. Если я правильно понимаю, вы (1) создаете подстановки x = h/l и y = t/l, (2) используете solve, чтобы переставить их так, чтобы t или l было предметом, (3) замените на expr и используйте simplify, чтобы отменить любые не _8 _ / _ 9_ переменные и (4) заменить x = h/l и y = t/l. Я попробую это сделать с некоторыми из более сложных выражений, с которыми я работаю, и, если это сработает, я отмечу этот ответ как принятый. - person binnev; 17.09.2015
comment
Кстати, я не знал, что solve может принимать целый список уравнений, и я не знал, что вы можете использовать словари с subs. Я все время использую вложенные списки! С ума сойти! - person binnev; 17.09.2015
comment
Да вот что я имел в виду. Хотя я решил немного вручную. (Кстати, это сложно). - person strubbly; 17.09.2015
comment
Работает также и с более сложными выражениями. Требуется немного больше поиграть с expand, simplify и т. Д., Но sympy довольно хорошо справляется с этим, когда мы используем x,y,z. Спасибо! - person binnev; 17.09.2015
comment
Открыт как проблема, предлагающая добавить функцию, упрощающую эту процедуру: github.com/sympy/sympy/ issues / 9925 - person Francesco Bonazzi; 18.09.2015

Поэтому я использовал x = h/l и y = t/l и заменил. Потом упростили. Это дало мне

       x*(y + 1)/((y + sin(theta))*cos(theta))

Я думаю, это то, что вам нужно. Я не понимаю, как упростить "по отношению к" h/l, но это работает ...

person strubbly    schedule 16.09.2015
comment
Не могли бы вы рассказать, как вы провели замену? Из вашего ответа похоже, что вы подставили x=h/l и y=t/l во второе выражение, но я не это имел в виду. Я хочу перейти ко второму выражению, и мы должны предположить, что я не знаю, как оно выглядит. - person binnev; 17.09.2015

Я действительно не знаю, можете ли вы использовать регулярное выражение, но если можете, вы можете использовать re.sub для замены всех экземпляров h на (h/1). или, если выражение является строкой, вы можете использовать str.replace, чтобы сделать то же самое.

person R Nar    schedule 16.09.2015
comment
Это не просто случай подстановки строк; это тоже должно иметь математический смысл. Полагаю, я мог бы взломать его так, чтобы добавить /l к обеим сторонам дроби, но это не совсем то, что я ищу. В sympy должен быть способ сделать это. - person binnev; 16.09.2015