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
6 changes: 5 additions & 1 deletion BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -1433,13 +1433,17 @@ polynomial, is integrated now by the recurrence
`int L1^m L2^n = L1^(m + 1) L2^(n + 1)/((m + 1) D) - (m + n + 2) d/((m + 1) D) int L1^(m + 1) L2^n`,
`D = b c - a d`, down to `int L2^n/L1`, the polynomial written in powers of `L1` first. The
answers are the same functions as master's where master gave one, written as powers of the two
linears ([#718](https://github.com/asc-community/AngouriMath/issues/718)).
linears ([#718](https://github.com/asc-community/AngouriMath/issues/718)). Beside a multiple of the
same linear, where `D` is zero only as a value -- `b a c - a b c` for `a + b x` beside
`c a + c b x` -- the recurrence is not taken: it divided by `D`, and the answer had no value anywhere
([#1776](https://github.com/asc-community/AngouriMath/issues/1776)).

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"1/((a + b*x)^4*sqrt(c + d*x))".ToEntity().Integrate("x")` | `integral(...)` | powers of `a/b + x` beside `sqrt(c + d x)`, and the arctangent or logarithm `1/((a + b x) sqrt(c + d x))` integrates to |
| `"(p + q*x + r*x^2 + s*x^3)/((a + b*x)^5*sqrt(c + d*x))".ToEntity().Integrate("x")` | `integral(...)` | the same, term by term |
| `"x/((a + b*x)^4*sqrt(c + d*x))".ToEntity().Integrate("x")` | `integral(...)` | the same |
| `"(a + b*x)^(-3)/sqrt(c*a + c*b*x)".ToEntity().Integrate("x")` | `integral(...)` | `-2/(5 b) (a + b x)^(-2) (c a + c b x)^(-1/2)` |

### A polynomial over a power of a linear beside the root of a quadratic is integrated

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10117,8 +10117,11 @@ void Gather(Entity node, int times)
return null;
if (!TreeAnalyzer.TryGetPolyLinear(first, x, out var b, out var a) || !TreeAnalyzer.TryGetPolyLinear(second, x, out var d, out var c))
return null;
// Zero as a value, not only as written: for `a + b x` beside `c a + c b x` it is
// `b a c - a b c`, and the recurrence divided by it -- an answer with no value anywhere.
// https://github.com/asc-community/AngouriMath/issues/1776
var determinant = (b * c - a * d).InnerSimplified;
if (determinant.Evaled is Number.Complex { IsZero: true })
if (Functions.PartialFractions.IsZeroAsAValue(determinant))
return null;
// The polynomial in powers of the first linear: x = (t - a)/b.
var t = Variable.CreateUnique(expr, "t_linear");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,22 @@ public sealed class LinearPowerRecurrenceIntegralTest
[InlineData("1/(x^3*(c + d*x)^(5/2))")]
[InlineData("x/((a + b*x)^4*sqrt(c + d*x))")]
public void ByTheRecurrence(string integrand)
=> DifferentiatesBack(integrand, new[] { -2.4, -1.5, 0.3, 0.8, 1.5, 2.4 });

/// <summary>
/// Beside a root of a multiple of the same linear, where the determinant the recurrence
/// divides by is zero only as a value, <c>b a c - a b c</c>: it was divided by, and the
/// answer had no value anywhere.
/// <a href="https://github.com/asc-community/AngouriMath/issues/1776">#1776</a>
/// </summary>
[Theory]
[InlineData("(a + b*x)^(-3)/sqrt(c*a + c*b*x)")]
[InlineData("1/(c*(a + b*x)^3)^(3/2)")]
[InlineData("1/(c*(a + b*x)^3)^(5/2)")]
public void BesideAMultipleOfTheSameLinear(string integrand)
=> DifferentiatesBack(integrand, new[] { -1.2, -0.6, 0.3, 0.8, 1.5, 2.4 });

private static void DifferentiatesBack(string integrand, double[] points)
{
var integral = integrand.ToEntity().Integrate("x");
Assert.DoesNotContain("integral(", integral.Stringize());
Expand All @@ -35,7 +51,7 @@ Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("b", 0.9).Substitut
.Substitute("s", 0.6);
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
var original = Pinned(integrand.ToEntity());
foreach (var at in new[] { -2.4, -1.5, 0.3, 0.8, 1.5, 2.4 })
foreach (var at in points)
{
var want = original.Substitute("x", at).EvalNumerical();
var got = derivative.Substitute("x", at).EvalNumerical();
Expand Down
Loading