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
20 changes: 20 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2315,6 +2315,26 @@ no integrand without one changes: Rubi's independent suites and a sample of its
| `"Ei(b*x)^2".Integrate("x")` | `Ei * (b * x) ^ 3 / 3 / b + C`, with `Ei` a variable | an antiderivative in `Ei(b x)` and `Ei(2 b x)` |
| `"x*erf(b*x)^2".Integrate("x")` | `UnrecognizedFunctionParseException`: there is no function `erf` | an antiderivative in `erf(b x)` |

### A constant of integration is matched to a linear divisor with a symbol in it

By parts against a polynomial chooses the polynomial's antiderivative so that what the other
factor's derivative divides by divides it too, and that was done only where the division left a
number over. `a + b x` leaves a symbol: `x^2/2` over `a + b x` leaves `a^2/(2 b^2)`, so the
remainder of `x Shi(a + b x)^2` kept `x^2/(a + b x)` and nothing read it. The antiderivative less
its value at `-a/b` is taken now, written as `a + b x` times the quotient, so that the linear
cancels in the remainder ([#1501](https://github.com/asc-community/AngouriMath/issues/1501)).
`x Shi(a + b x)^2`, `x Chi(a + b x)^2` and `x Ei(a + b x)^2` are answered. An integrand holding one of
these functions had no reading in 2.5.0, which the entries for the functions themselves record, and
no integrand without one changes: Rubi's independent suites and a sample of its families 1 to 7
are answered alone as they were. Where by parts already answered a special function of `a + b x`
beside a power of `x`, the answer is written with the same constant: `x Ei(a + b x)` now reads
`Ei(a + b x) (a + b x)(x/(2b) - a/(2b^2)) - ...`, the same function as before.

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"x*Shi(a+b*x)^2".Integrate("x")` | `a ^ 2 * Shi * x ^ 2 / 2 + a * b * 2 * Shi * x ^ 3 / 3 + b ^ 2 * Shi * x ^ 4 / 4 + C`, with `Shi` a variable | an antiderivative in `Shi(a + b x)` and `Ei(2 (a + b x))`, `Ei(-2 (a + b x))` |
| `"x*Ei(a+b*x)^2".Integrate("x")` | `a ^ 2 * Ei * x ^ 2 / 2 + a * b * 2 * Ei * x ^ 3 / 3 + b ^ 2 * Ei * x ^ 4 / 4 + C`, with `Ei` a variable | an antiderivative in `Ei(a + b x)` and `Ei(2 (a + b x))` |

### An exponential or a hyperbolic function over several linears is split into partial fractions over them

`e^x/(x (x + 1))` was left unevaluated, where `e^x/x` and `e^x/(x + 1)` were each answered with
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1691,6 +1691,19 @@ static Entity WithTheConstantMatchedTo(Entity antiderivative, Entity derivativeO
&& Functions.SingleQuotient.Of(leftOver) is var (leftOverTop, _) && !leftOverTop.ContainsNode(x)
&& leftOverTop.Evaled is Number.Complex { IsZero: false } constant)
return (antiderivative + (-constant).Evaled).InnerSimplified;
// A linear divisor with a symbol in it, `a + b x`, leaves a symbol over, which the
// case above does not read: the antiderivative less its value at the root, -a/b, is
// divisible by the linear, and it is written as the linear times the quotient, so
// that the linear the derivative divides by cancels as written. `x Shi(a + b x)^2`
// is two rounds of parts that way, where with `x^2/2` the remainder kept
// `x^2/(a + b x)` and nothing read it.
// https://github.com/asc-community/AngouriMath/issues/1501
if (TreeAnalyzer.TryGetPolyLinear(divisors[0], x, out var slope, out var offset) && !TreeAnalyzer.IsZero(slope)
&& antiderivative.Substitute(x, (-offset / slope).InnerSimplified).InnerSimplified is var atTheRoot
&& !atTheRoot.ContainsNode(x) && !TreeAnalyzer.IsZero(atTheRoot)
&& TreeAnalyzer.PolynomialLongDivision((antiderivative - atTheRoot).Expand().InnerSimplified, divisors[0], genericCase: true, inTermsOf: x) is var (quotient, _)
&& !quotient.ContainsNode(MathS.NaN))
return divisors[0] * Functions.PartialFractions.Bare(quotient);
return antiderivative;
}

Expand Down
11 changes: 11 additions & 0 deletions Sources/Tests/UnitTests/Calculus/SpecialFunctionsByPartsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,5 +133,16 @@ public void BesideAPowerAndTheElementaryFactorOfItsDerivative(string integrand)
[InlineData("Chi(b*x)^2")]
public void ASquareIsTwoRoundsOfParts(string integrand)
=> DifferentiatesBack(integrand, Parameters);

/// <summary>
/// Of <c>a + b x</c>, the first round against <c>x</c> takes <c>x^2/2</c> less its value at
/// <c>-a/b</c>, written as <c>a + b x</c> times the quotient, so the linear the derivative
/// divides by cancels and what is left is the case above.
/// </summary>
[Theory]
[InlineData("x*Shi(a + b*x)^2")]
[InlineData("x*Ei(a + b*x)^2")]
public void ASquareOfAShiftedArgumentIsTwoRoundsOfParts(string integrand)
=> DifferentiatesBack(integrand, Parameters);
}
}
Loading