The same integrand, written factored instead of expanded, goes from answered-in-milliseconds to not finishing in 20 seconds.
"5 * sin(a+f*x)^4 - 6 * sin(a+f*x)^6".ToEntity().Integrate("x") // answered, ~2 ms
"sin(a+f*x)^4 * (5 - 6 * sin(a+f*x)^2)".ToEntity().Integrate("x") // no answer in 20 s
These are the same function. Each piece is integrable on its own — sin(a+f*x)^4 and sin(a+f*x)^6 are both answered instantly by the power-reduction entry — and the sum of them is answered. Only the product with a sum is not.
It does not fail, either. It spends the whole budget, so it costs a caller twenty seconds to learn nothing, where the numeric version of the same shape gives up in 272 ms:
"sin(x)^4 * (5 - 6 * sin(x)^2)".ToEntity().Integrate("x") // unevaluated, 272 ms
"sin(2*x)^4".ToEntity().Integrate("x") // answered, 1 ms
Where this showed up
Running the integrator against family 4 of Rubi's test-suite (Trig functions) via work/intbench — 22551 problems read, 13690 of them fair (Rubi's antiderivative is elementary), 696 sampled by stride at a 3 second budget:
|
|
| answered |
55 (7.9%) |
| unevaluated |
269 |
| timeout |
372 (53%) |
| wrong |
0 |
The zero is worth saying plainly: nothing in that sample answered incorrectly. The problem is entirely that over half the sample spends its whole budget. For comparison, the same harness over family 0 (the textbook problems — Stewart, Apostol, Timofeev and the rest) times out on 30 of 1774, which is 1.7%.
Several of the sampled timeouts are this shape, a product of a trig power with a sum of trig powers. I have not measured what fraction of the 372 are, so please do not read the 53% as being all one cause.
Suggested direction
SolveBySplittingSum gives the integrator linearity over a sum, but A * (B + C) is a product at the top level, so it never fires. Distributing over a sum before giving up would answer this class using rules that already exist.
Failing faster looks worth separating from answering more. A shape that cannot be integrated is better declined in milliseconds than at the end of a budget, and the numeric case above shows the machinery can decline quickly — it is the symbolic constants that make it search instead.
Note that Expand() on this integrand also expands the angle, giving 5*(sin(a)cos(f*x) + sin(f*x)cos(a))^4 - ..., which is not the form that integrates well. The useful step is distributing the product over the sum while leaving sin(a + f*x) intact.
The same integrand, written factored instead of expanded, goes from answered-in-milliseconds to not finishing in 20 seconds.
These are the same function. Each piece is integrable on its own —
sin(a+f*x)^4andsin(a+f*x)^6are both answered instantly by the power-reduction entry — and the sum of them is answered. Only the product with a sum is not.It does not fail, either. It spends the whole budget, so it costs a caller twenty seconds to learn nothing, where the numeric version of the same shape gives up in 272 ms:
Where this showed up
Running the integrator against family 4 of Rubi's test-suite (Trig functions) via
work/intbench— 22551 problems read, 13690 of them fair (Rubi's antiderivative is elementary), 696 sampled by stride at a 3 second budget:The zero is worth saying plainly: nothing in that sample answered incorrectly. The problem is entirely that over half the sample spends its whole budget. For comparison, the same harness over family 0 (the textbook problems — Stewart, Apostol, Timofeev and the rest) times out on 30 of 1774, which is 1.7%.
Several of the sampled timeouts are this shape, a product of a trig power with a sum of trig powers. I have not measured what fraction of the 372 are, so please do not read the 53% as being all one cause.
Suggested direction
SolveBySplittingSumgives the integrator linearity over a sum, butA * (B + C)is a product at the top level, so it never fires. Distributing over a sum before giving up would answer this class using rules that already exist.Failing faster looks worth separating from answering more. A shape that cannot be integrated is better declined in milliseconds than at the end of a budget, and the numeric case above shows the machinery can decline quickly — it is the symbolic constants that make it search instead.
Note that
Expand()on this integrand also expands the angle, giving5*(sin(a)cos(f*x) + sin(f*x)cos(a))^4 - ..., which is not the form that integrates well. The useful step is distributing the product over the sum while leavingsin(a + f*x)intact.