Skip to content

Commit 94c9ab9

Browse files
Leave a power of x past the second beside a high power of a binomial in x^2 to the binomial rules (#2041)
SolveARationalFunctionOverAPowerOfASymbolicQuadratic already declined an odd integrand beside a power of x and a binomial in x^2 to the sixth power or past it, leaving it to the substitution in x^2. An even one is the binomial rules' x^m (a + b x^2)^p, and here it was peeled: Rubi's 1.1.2.2 1/(x^4 (a + b x^2)^10) took the power of x off four times, over ten levels of the recurrence each, and came back in 75,607 characters with its like terms never gathered. Past the second power of x it now declines, and the binomial rules write 8,559; 1/(x^6 (a + b x^2)^8) goes from 33,638 to 6,063. Beside x^2 the binomial rules are shorter at four times the cost, 1/(x^2 (a + b x^2)^10) in 8,322 characters and 0.49 GB against 15,658 and 0.10, and that is left as it was. Chain against master 78cd31b, before the narrowing to past x^2: pocket of 7,790 rows 7,788 -> 7,789 solved, 0 wrong; every family's sample unchanged; the one move, 1.1.2.2:236, partial -> solved; of 13,328 rows compared for allocation one grew past 1.3x and 300 MB, 1.1.2.2:235, the x^2 trade above, which the narrowing returns to master's answer. Part of #233. Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent a8f503b commit 94c9ab9

3 files changed

Lines changed: 71 additions & 6 deletions

File tree

‎BREAKING-CHANGES.md‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,6 +2277,19 @@ is written in closed form. A quadratic that factors over linears is left to the
22772277
| `"(f + g*x)/((d + k*x)^2*(a + b*x + c*x^2)^3)".ToEntity().Integrate("x")` | `integral(...)` | 21,943 characters |
22782278
| `"(A + B*x + C*x^2)/((d + k*x)^3*(a + c*x^2)^3)".ToEntity().Integrate("x")` | `integral(...)` | 25,201 characters |
22792279

2280+
### A power of x beside a high power of a binomial in x^2 is left to the binomial rules
2281+
2282+
**Shorter answers.** The rule above took a power of x off `1/(x^4 (a + b x^2)^10)`, Rubi's 1.1.2.2, four times, over ten
2283+
levels of its recurrence each, and the answer's like terms were never gathered. Beside a power of x past the second
2284+
and a binomial in `x^2` to the sixth power or past it, it now declines, as it already did where the integrand is odd,
2285+
and the rules for `x^m (a + b x^2)^p` answer it. Beside `x^2` the two are a trade, shorter there at four times the
2286+
cost, and it is left as it was ([#233](https://github.com/asc-community/AngouriMath/issues/233)).
2287+
2288+
| Input | Was (2.5.0) | Now |
2289+
|---|---|---|
2290+
| `"1/(x^4*(a+b*x^2)^10)".ToEntity().Integrate("x")` | `integral(...)`; 75,607 characters on the unreleased master | 8,559 characters |
2291+
| `"1/(x^6*(a+b*x^2)^8)".ToEntity().Integrate("x")` | `integral(...)`; 33,638 characters on the unreleased master | 6,063 characters |
2292+
22802293
### An odd power of a quadratic's derivative over a power of the quadratic is integrated in the quadratic
22812294

22822295
**Shorter answers, and answers where there were none.** `(b + 2c x)^9/(a + b x + c x^2)^3` was answered through the

‎Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs‎

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26204,14 +26204,19 @@ Entity TakeOut(Entity node)
2620426204
// a second and ten levels of this ran past the budget.
2620526205
if (Functions.PartialFractions.HoldsTheImaginaryUnit(quadratic) || linear is null && VanishesIdentically(a1))
2620626206
return null;
26207-
// Nor beside a power of x where the integrand is odd and the power of the quadratic high:
26208-
// it is then x times a function of x^2, the substitution's under u = x^2, and peeling
26209-
// fifteen powers of x off `(b + 2 c x^2)/(x^15 (b + c x^2)^8)` here ran past the budget,
26210-
// where in u it is two linears. An even one, and a low power, are left here, where they
26211-
// were answered.
26207+
// Nor beside a power of x where the power of the quadratic is high. Odd, the integrand is
26208+
// x times a function of x^2, the substitution's under u = x^2, and peeling fifteen powers
26209+
// of x off `(b + 2 c x^2)/(x^15 (b + c x^2)^8)` here ran past the budget, where in u it is
26210+
// two linears. Even, and peeled past the second power of x, it is the binomial rules'
26211+
// `x^m (a + b x^2)^p`: peeled here four times over ten levels of the recurrence, Rubi's
26212+
// 1.1.2.2 `1/(x^4 (a + b x^2)^10)` came back in 75,607 characters, its like terms never
26213+
// gathered, and the binomial rules write 8,559. Beside `x^2` the two are a trade, shorter
26214+
// there at four times the cost, and it stays here. A low power is left here, where it was
26215+
// answered.
2621226216
if (linear is not null && power >= 6 && VanishesIdentically(a1) && TreeAnalyzer.TryGetPolyLinear(linear, x, out _, out var interceptOfTheLinear)
2621326217
&& VanishesIdentically(interceptOfTheLinear)
26214-
&& top.Keys.All(degree => degree.IsEven != (linearPower % 2 == 0)))
26218+
&& (top.Keys.All(degree => degree.IsEven != (linearPower % 2 == 0))
26219+
|| linearPower >= 3 && top.Keys.All(degree => degree.IsEven == (linearPower % 2 == 0))))
2621526220
return null;
2621626221
// A quadratic that factors over linears is the partial fractions' to take apart, and
2621726222
// they do it cheaply: `(d + e x)^10/((d + e x) (a e + c d x))^4`, written out, went from
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// Copyright (c) 2019-2026 Angouri.
3+
// AngouriMath is licensed under MIT.
4+
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
5+
// Website: https://am.angouri.org.
6+
//
7+
8+
using System;
9+
using AngouriMath.Extensions;
10+
using Xunit;
11+
12+
namespace AngouriMath.Tests.Calculus
13+
{
14+
/// <summary>
15+
/// A power of x past the second beside a high power of a binomial in <c>x^2</c> is the binomial rules', even or odd:
16+
/// the reduction over a power of a symbolic quadratic took the power of x off Rubi's 1.1.2.2
17+
/// <c>1/(x^4 (a + b x^2)^10)</c> four times over ten levels each, and came back in 75,607 characters
18+
/// with its like terms never gathered, where the binomial rules write 8,559.
19+
/// <a href="https://github.com/asc-community/AngouriMath/issues/233">#233</a>
20+
/// </summary>
21+
[Trait("Area", "Calculus")]
22+
public sealed class APowerOfXBesideAHighPowerOfABinomialInXSquaredIntegralTest
23+
{
24+
[Theory]
25+
[InlineData("1/(x^4*(a+b*x^2)^10)", 12000)]
26+
[InlineData("1/(x^6*(a+b*x^2)^8)", 9000)]
27+
public void IsAnsweredInFewCharacters(string integrand, int characters)
28+
{
29+
var integral = integrand.ToEntity().Integrate("x");
30+
var text = integral.Stringize();
31+
Assert.DoesNotContain("integral(", text);
32+
Assert.True(text.Length < characters, $"the antiderivative of {integrand} is {text.Length} characters");
33+
Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("b", 0.7);
34+
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
35+
var original = Pinned(integrand.ToEntity());
36+
foreach (var at in new[] { -1.7, -0.6, 0.4, 1.3, 2.2 })
37+
{
38+
var want = original.Substitute("x", at).EvalNumerical();
39+
var got = derivative.Substitute("x", at).EvalNumerical();
40+
Assert.False(got.IsNaN, $"d/dx of the antiderivative of {integrand} has no value at x = {at}, where the integrand is {want}");
41+
Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
42+
< 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
43+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
44+
}
45+
}
46+
}
47+
}

0 commit comments

Comments
 (0)