Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,19 @@ case is most of its length ([#718](https://github.com/asc-community/AngouriMath/
| `"x^4/((a + b*x^2 + c*x^4)*sqrt(d + k*x^2))".ToEntity().Integrate("x")` | `integral(...)` | 28,551 characters |
| `"1/(x^2*(a + b*x^2 + c*x^4)*sqrt(d + k*x^2))".ToEntity().Integrate("x")` | `integral(...)` | 10,194 characters |

### A polynomial of degree six with a large leading coefficient is factored

**Answers where there were none.** The factoring clears a leading coefficient by rescaling the variable, and declined
when that raised it past 2^512. Over the square of `(x^2 + 6)^3 + 324 x^3` the resultant the integrator factors is a sextic
with a 107-bit leading coefficient, which needs 2^535. Up to degree six the bound is now 2^1024; past it, it stays
([#718](https://github.com/asc-community/AngouriMath/issues/718)).

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"x^8/(216+108*x^2+324*x^3+18*x^4+x^6)^2".ToEntity().Integrate("x")` | `integral(...)` | 381 characters, a sum over the roots of the sextic |
| `"x^5/(216+108*x^2+324*x^3+18*x^4+x^6)^2".ToEntity().Integrate("x")` | `integral(...)` | 377 characters |
| `"x^2/(216+108*x^2+324*x^3+18*x^4+x^6)^2".ToEntity().Integrate("x")` | `integral(...)` | 394 characters |

### A rational function past the twelfth degree is reduced by Hermite's method

**Answers where there were none.** The integrator read a denominator of degree twelve at most, so a derivative over
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ internal static class PolynomialFactorization
[ConstantField]
private static readonly EInteger MaxMonicScale = EInteger.FromInt32(2).Pow(512);

/// <summary>
/// The same, up to <see cref="MaxLowDegree"/>: a sextic of Rubi's 1.3.1 whose leading
/// coefficient is 107 bits needs 2^535, and is factored in a quarter of a second. Past
/// that degree the bound stays: <c>1/(1 + cosh(x)^5)</c> asks for a hundred and twenty
/// polynomials of degree eight and nine at 2^580 to 2^880, a second each and none of them
/// needed, and went from 7 seconds to 72 with the higher bound for every degree.
/// </summary>
[ConstantField]
private static readonly EInteger MaxLowDegreeMonicScale = EInteger.FromInt32(2).Pow(1024);

private const int MaxLowDegree = 6;

/// <summary>
/// <paramref name="expr"/> written as a product of powers of irreducible polynomials
/// over <c>Q</c>, or <see langword="false"/> where it is not a polynomial in
Expand Down Expand Up @@ -267,7 +279,7 @@ internal static bool IsWorthFactoringToSolve(Entity expr, Variable x)
return FactorMonic(primitive);

var degree = primitive.Degree;
if (lead.Abs().Pow(degree - 1).CompareTo(MaxMonicScale) > 0)
if (lead.Abs().Pow(degree - 1).CompareTo(degree <= MaxLowDegree ? MaxLowDegreeMonicScale : MaxMonicScale) > 0)
return null;

var scaled = new EInteger[degree + 1];
Expand Down
12 changes: 12 additions & 0 deletions Sources/Tests/UnitTests/Calculus/RothsteinTragerTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,17 @@ public void TheArctangentsAreContinuous()
[InlineData("x^2/(x^4 + x^3 + 1)")]
public void AResidueOfDegreeThreeIsASumOverRoots(string integrand)
=> Assert.Contains(DifferentiatesBack(integrand, TheLine).Nodes, node => node is Entity.SumOverSetf);

/// <summary>
/// Over a square, the resultant of what Hermite's reduction leaves has a 107-bit leading
/// coefficient, and clearing it rescales a sextic past 2^512, where the factoring declined.
/// Rubi's 1.3.1 over <c>((x^2 + 6)^3 + 324 x^3)^2</c>, whose first power was answered.
/// <a href="https://github.com/asc-community/AngouriMath/issues/718">#718</a>
/// </summary>
[Theory]
[InlineData("x^8/(216+108*x^2+324*x^3+18*x^4+x^6)^2")]
[InlineData("x^2/(216+108*x^2+324*x^3+18*x^4+x^6)^2")]
public void ALargeLeadingCoefficientOfTheResultantIsCleared(string integrand)
=> Assert.Contains(DifferentiatesBack(integrand, TheLine).Nodes, node => node is Entity.SumOverSetf);
}
}
Loading