Sympy Collect() в триггерном выражении

Я новичок в sympy, и у меня возникли проблемы с использованием collect() внутри тригонометрической функции. Я не использую упрощение () или тригсимп (), потому что мое реальное выражение более сложное, а они его чрезмерно упрощают. Я пытаюсь шаг за шагом упростить его до определенной формы. Почему collect(sin(xy+xz),x) не группирует x терминов? Спасибо.

x, y, z = symbols('x y z')

print(collect(sin(2*x + 3*x),x))
sin(5*x)  #Works

print(collect(x*y + x*z, x))
x*(y + z)  #Works

print(collect(sin(x*y+x*z),x))
sin(x*y + x*z)  #Doesn’t work - Expected sin(x(y+z))

person Mark    schedule 25.06.2021    source источник
comment
Функция collect предполагает, что ваше выражение является полиномом верхнего уровня. Вы можете использовать, например. factor_terms для рекурсивного применения такого упрощения к подвыражениям.   -  person Oscar Benjamin    schedule 26.06.2021
comment
Это как раз то, что мне было нужно. Благодарю вас!   -  person Mark    schedule 28.06.2021


Ответы (2)


Если вы хотите применить функцию к аргументам выражения, а функция не имеет опции deep, вы можете попробовать создать лямбду, которая будет применять функцию к произвольному выражению, и использовать ее с bottom_up:

>>> from sympy.abc import *
>>> from sympy import *
>>> bottom_up(sin(x+x*y), lambda e: collect(e, x))
sin(x*(y + 1))

Целенаправленная замена также будет работать:

>>> sin(x+x*y).replace(lambda e: e.is_Add and e.has(x), lambda e: collect(e,x))
sin(x*(y + 1))
person smichr    schedule 26.06.2021
comment
Аккуратный подход. Спасибо за чаевые. - person Mark; 28.06.2021

Для сбора:

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

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

t = collect(x*y + x*z, x)
print(collect(sin(t),x))

Это даст вам sin(x*(y + z))

person Zichzheng    schedule 25.06.2021
comment
Спасибо за предложение. Я вижу, что это работает в случае, который я представил, но в моем реальном приложении я не строю аргумент греха с нуля. Это происходит из других триггерных упрощений. Поэтому я не уверен, как применить это решение. - person Mark; 28.06.2021