简化 sympy 积分表达式

Simplify sympy integral expressions

x, a, b, c = symbols ('x a b c')
f = Function ('f') (x)

有没有办法简化

integrate (f, (x, a, b)) + integrate (f, (x, b, a))

integrate (f, (x, a, c)) + integrate (f, (x, c, b)) - integrate (f, (x, a, b))

归零?

参考:https://en.wikipedia.org/wiki/Integral#Conventions

第一种情况可以通过使用将限制按规范顺序排列的遍历来处理:

def iss(i):
   if isinstance(i, Integral):
     s = 1
     lim = list(i.limits)
     for j, xab in enumerate(lim):
         if len(xab) == 3:
             x, a, b = xab
             if [a,b]!=list(ordered([a,b])):
                 lim[j] = (x, b, a)
                 s *= -1
     return i.func(i.function, lim).simplify()*s
   return i

>>> eq = integrate (f, (x, a, b)) + integrate (f, (x, b, a))
>>> bottom_up(eq, iss)
0

对于第二种情况,有很多可能的表达式需要处理。但要处理您所展示的类型,以下方法可能会起作用:

def collapse_integrals(a):
    from collections import defaultdict
    if not a.is_Add: return a
    i, d = a.as_independent(Integral)
    if not d.is_Add:
        return a
    if i:
        return i + collapse_integrals(d)
    igls = defaultdict(list)
    other = []
    for ai in a.args:
        c, i = ai.as_independent(Integral, as_Add=False)
        if abs(c) != 1:
            other.append(ai)
            continue
        if not isinstance(i,Integral) or not (len(i.limits) == 1 and len(i.limits[0])==3):
            other.append(ai)
        else:
            igls[(c, i.function)].append(i.limits[0][1:])
    for k in igls:
        if len(igls[k]) > 1:
            n = len(igls[k])
            lims = igls[k]
            cond = []
            nul = (None, None)
            for i in range(n):
                if lims[i] == nul:continue
                for j in range(i + 1, n):
                    if lims[i][0] == lims[j][1]:
                        cond.append((lims[j][0],lims[i][1]))
                    elif lims[i][1] == lims[j][0]:
                        cond.append((lims[i][0],lims[j][1]))
                    else:
                        continue
                    lims[i] = lims[j] = nul
            if cond:
                igls[k] = cond + [i for i in lims if i != nul]
        c, f = k
        other.extend([c*Integral(f, l) for l in igls[k]])
    return Add(*other)

>>> eq = integrate (f, (x, a, c)) + integrate (f, (x, c, b)) - integrate (f, (x, a, b))
collapse_integrals(bottom_up(eq,iss))
0