سؤال

I have the following code:

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

The result is:

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

Now I want to distribute the integral to obtain this:

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

Anyone knows how to do this?
Using a2.expand() only expands the inner expression of the integral.

هل كانت مفيدة؟

المحلول

There isn't a function in SymPy to do this directly (yet), but it's not hard to do it yourself.

The easiest way would be to just do it manually. If you know what the integral is, you can replace it using subs.

That way is annoying if you don't know what the integral is, and you don't want to type it out. A better way, which is not particularly general, would be

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

This only splits an integral in two, so if you want to split by more than that, you will need to make it more general, or else apply it multiple times. And if the integral is with respect to a different variable, you'll need to change that.

For a more general version, we can use an underdocumented feature in SymPy, the Transform object (in fact, the documentation isn't even in Sphinx, I have to point you to the source code for more information):

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 creates an object that converts expressions into other expressions using a rule. The rule here is split, which decomposes an integral using .args and splits it up over an addition using Add.make_args, and then creates new integrals using the remaining arguments (which are the variables and limits of integration). The lambda i: isinstance(i, Integral) tells the Transform to only apply to Integral objects. Transform returns an object that is suitable to pass in to xreplace, which does a replacement.

Here's an example

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
⌡        ⌡        ⌡
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top