Распределить интеграл по сумме в sympy

У меня есть следующий код:

a2 = Rational(1, alpha2)*integrate(phi2*wx12, (x,-1,1))

Результат:

  1                     
  ⌠                     
  ⎮  ⎛ 2   1⎞           
5⋅⎮  ⎜x  - ─⎟⋅wx₁₂(x) dx
  ⎮  ⎝     3⎠           
  ⌡                     
  -1                    
────────────────────────
           2            

Теперь я хочу распределить интеграл, чтобы получить это:

                       1            
  1                    ⌠            
  ⌠                    ⎮  wx₁₂(x)   
  ⎮   2              5⋅⎮  ─────── dx
5⋅⎮  x ⋅wx₁₂(x) dx     ⎮     3      
  ⌡                    ⌡            
  -1                   -1           
────────────────── - ───────────────
        2                   2       

Кто-нибудь знает, как это сделать?
Использование a2.expand() только расширяет внутреннее выражение интеграла.


person Cristóbal Ganter    schedule 25.08.2013    source источник
comment
Залезть в эту тему было непросто :-)   -  person Egor Skriptunoff    schedule 26.08.2013
comment
Почему? Заголовок недостаточно информативен?   -  person Cristóbal Ganter    schedule 26.08.2013
comment
Просто перейдите на главную страницу и попробуйте нажать на свою тему :-)   -  person Egor Skriptunoff    schedule 26.08.2013
comment
ничего особенного не увидел...   -  person Cristóbal Ganter    schedule 27.08.2013
comment
В FireFox нельзя войти в вашу тему, нажав на ее заголовок.   -  person Egor Skriptunoff    schedule 27.08.2013
comment
Я использую Firefox 23 на Ubuntu. Возможно, будет лучше использовать только символы ascii. Или, если вы можете публиковать изображения, вы можете добавить эти изображения: krhps.dyndns.org/static/f1 .png krhps.dyndns.org/static/f2.png   -  person Cristóbal Ganter    schedule 27.08.2013
comment
Да, ФФ23. Но похоже проблема только в винде.   -  person Egor Skriptunoff    schedule 27.08.2013


Ответы (1)


В SymPy нет функции, позволяющей сделать это напрямую (пока), но это не сложно сделать самому.

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

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

a, b = symbols('a b', cls=Wild)
expr.replace(Integral(a + b, x), Integral(a, x) + Integral(b, x))

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

Для более общей версии мы можем использовать недостаточно документированную функцию в SymPy, объект Transform (на самом деле документации нет даже в Sphinx, я должен указать вам на исходный код для получения дополнительной информации):

from sympy.core.rules import Transform
def split(integ):
    return Add(*[integ.func(term, *integ.args[1:]) for term in Add.make_args(integ.args[0])])
expr.xreplace(Transform(split, lambda i: isinstance(i, Integral))

Transform создает объект, который преобразует выражения в другие выражения с помощью правила. Здесь действует правило split, которое разлагает интеграл, используя .args, и разбивает его на сложение, используя Add.make_args, а затем создает новые интегралы, используя оставшиеся аргументы (которые являются переменными и пределами интегрирования). lambda i: isinstance(i, Integral) указывает Transform применять только к интегральным объектам. Transform возвращает объект, подходящий для передачи в xreplace, который выполняет замену.

Вот пример

In [20]: expr
Out[20]:
⌠
⎮ ⎛ 2        ⎞
⎮ ⎝x  + x + 1⎠ dx + 3
⌡

In [21]: expr.xreplace(Transform(split, lambda i: isinstance(i, Integral)))
Out[21]:
                  ⌠
⌠        ⌠        ⎮  2
⎮ 1 dx + ⎮ x dx + ⎮ x  dx + 3
⌡        ⌡        ⌡
person asmeurer    schedule 27.08.2013
comment
Спасибо @asmeurer! Наконец-то я сделал это вручную, несмотря на то, что интегралов было много :) . Объект Transform кажется очень полезным. - person Cristóbal Ganter; 28.08.2013