sympy / sympy

A computer algebra system written in pure Python
https://sympy.org/
Other
12.77k stars 4.38k forks source link

Run simplification on unevaluated integrals #22081

Open oscargus opened 3 years ago

oscargus commented 3 years ago

The following is to collect cases where an integral currently cannot be solved, but it can be solved after simplification is performed. The goal is to keep it condensed and efficient, so ideally we should not run simplify, but conditionally one specific simplification if the original integral does not evaluate and the simplification gives a different objective function.

Of course, there is a trade-off between trying the integral again, which may not lead to evaluation and the probability that it actually does evaluate.

In general, I do not think that it is a good idea to always simplify as this may take quite a bit of time and in some cases rewrite expressions into a form that actually cannot be evaluated.

trigsimp

19738

https://github.com/sympy/sympy/blob/3f8c8c2377cb8e0daaf8073e8d03ac7d87580813/sympy/utilities/tests/test_wester.py#L2422-L2426

expand

21711

smichr commented 2 years ago

There are some sign-related simplifications that can happen. e.g. signsimp(Integral(-f(x), (x, b, a))) does nothing but could give Integral(f(x), (x, a, b)) where the function has been signsimp'ed and the limits have been made canonical. see this SO post.

oscargus commented 2 years ago

There are some cases where rewrites do help, e.g. #11254 This seems to be related to (at least) particular trigonometric functions.

Trigsimp: #22343

asmeurer commented 2 years ago

I would try to do targeted simplifications/rewritings in the specific algorithms, if it is known that they can potentially help for that algorithm. I don't think it's wise to do this in a way that treats the integration algorithms as black boxes. Sometimes simplifications can help and algorithm and sometimes they can hurt it, and the situation for the same simplification will differ depending on which algorithm is used.

To take a simple example, the trigintegrate and manualintegrate both work by pattern matching expressions, so if the integrand looks like something that be rewritten into something that might be pattern matched, then it should do that (of course, that could also just mean the pattern matching expression should be expanded so that the rewrite is not needed in the first place).

For heurisch and meijerg, this requires a bit more domain knowledge of the algorithms to understand just what sorts of simplifications are likely to help. For example, heurisch can benefit from Weierstrass substitutions (I can't remember if it is already doing that).

For risch, simplifications like expand() or cancel() are a complete waste of time, since the algorithm already does its on internal canonicalization of the integrand. The only thing that could help risch in its current state is rewriting an expression it cannot handle into one it can handle (right now that's just exponentials and logs, with no algebraic functions). So for instance it could integrate hyperbolic trig functions if you rewrite them (or even normal trig functions if you don't mind the complex numbers).