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
3 changes: 2 additions & 1 deletion BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,8 @@ as `a - b = 0`, as a statement's own solve reads it: `"x + 1 = 3".Solve("x")` wa
`z = -b ln(F) x^n` and `s = (m + 1)/n`, where `s` is neither whole nor half a whole number, or is past 30, as
`x^31 e^(-x)` is, whose sum of 32 terms is `-gamma(32, x)` now. A definite integral of such an answer that is
undefined at a bound is left as written. And beside a power of a sine and a cosine, which Euler's formula writes as
those exponentials, the gamma functions of an imaginary argument.
those exponentials, the gamma functions of an imaginary argument, and beside a hyperbolic function of a power of
`x`, as `x sinh(c + d x^3)`.
([#2075](https://github.com/asc-community/AngouriMath/issues/2075))

| Input | Was (2.6.0) | Now |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -422,23 +422,31 @@ private static bool TakeMomentFactor(Entity factor, bool inverted, Entity.Variab
var exponent = exponentialBelow ? -exponential.Exponent : exponential.Exponent;
var logarithm = exponential.Base == MathS.e ? Entity.Number.Integer.One : MathS.Ln(exponential.Base);

// The exponent as a + b x^n, the term in x as written.
// The exponent as a + b x^n, the term in x as written, or as expanded: -(c + d x^3) is one term as written, and
// it is how sinh(c + d x^3) arrives, as (e^(c + d x^3) - e^(-(c + d x^3)))/2.
Entity constant = Entity.Number.Integer.Zero;
Entity? term = null;
Entity? degree = null;
foreach (var summand in Entity.Sumf.LinearChildren(exponent))
if (!summand.ContainsNode(x))
constant += summand;
else if (term is null && ThePowerOfX(summand, x) is { } read)
{
term = summand;
degree = read;
}
else
{
term = null;
for (var reading = 0; reading < 2 && term is null; reading++)
{
var asRead = reading == 0 ? exponent : exponent.Expand();
if (reading == 1 && asRead == exponent)
break;
}
constant = Entity.Number.Integer.Zero;
foreach (var summand in Entity.Sumf.LinearChildren(asRead))
if (!summand.ContainsNode(x))
constant += summand;
else if (term is null && ThePowerOfX(summand, x) is { } read)
{
term = summand;
degree = read;
}
else
{
term = null;
break;
}
}
// Or a linear written otherwise, as the negation -(a + b x) is, which is how gamma(2, a + b x) is
// elementary: e^(-(a + b x)) (1 + a + b x). https://github.com/asc-community/AngouriMath/issues/2075
if (term is null && TreeAnalyzer.TryGetPolyLinear(exponent, x, out var slopeOfTheExponent, out var offsetOfTheExponent)
Expand Down Expand Up @@ -474,11 +482,11 @@ private static bool TakeMomentFactor(Entity factor, bool inverted, Entity.Variab
// x^(m + 1) z^(-s), constant on each half-line, is K^(-s) for x > 0 with z = K x^n, and its value at -1 for
// x < 0. Where the two are one number it is that number on the whole line, and the answer has a value at 0
// rather than 0 times an infinity there: e^(x^3) is gamma(1/3, -x^3)/3, and its integral from 0 to 1 was NaN.
if (allOfX && mPlusOne is Entity.Number && degree is Entity.Number
&& (-logarithm * term.Substitute(x, Entity.Number.Integer.One)).InnerSimplified is Entity.Number theRate
&& MathS.Pow(theRate, (-s).InnerSimplified).InnerSimplified is Entity.Number onTheRight
&& constantFactor.Substitute(x, Entity.Number.Integer.MinusOne).InnerSimplified is Entity.Number onTheLeft
&& onTheRight == onTheLeft)
// The two are its values at 1 and -1, which need not be numbers: x^(1/3) e^(-1 - 3 x^2) has 3^(-2/3) on both.
if (allOfX
&& constantFactor.Substitute(x, Entity.Number.Integer.One).InnerSimplified is var onTheRight
&& !onTheRight.ContainsNode(x)
&& constantFactor.Substitute(x, Entity.Number.Integer.MinusOne).InnerSimplified == onTheRight)
return leading * onTheRight * MathS.IncompleteGamma(s, z);
return leading * constantFactor * MathS.IncompleteGamma(s, z);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ public void AHighWholePowerIsOneGammaFunction()
[Theory]
[InlineData("integral(e^(x^3), x, 0, 1)", 1.34190441797742)]
[InlineData("integral(e^(-x^3), x, 0, 1)", 0.807511182139671)]
// 3^(-2/3) on both half-lines, which is not a number but one constant.
[InlineData("integral(x^(1/3)*e^(-(1 + 3*x^2)), x, 0, 1)", 0.1169389395696306439)]
public void ADefiniteIntegralFromZero(string integral, double value)
{
var result = integral.ToEntity().Simplify().EvalNumerical();
Expand All @@ -110,6 +112,17 @@ public void APositiveRateIsTakenOutOfThePower()
[InlineData("sin(c + d*x^3)^2")]
public void APowerBesideASineOrACosine(string integrand) => DifferentiatesBack(integrand);

/// <summary>
/// And a hyperbolic function of a power of <c>x</c>, which arrives as <c>e^u</c> and <c>e^(-u)</c>: the second's exponent
/// is read expanded. Rubi's 6.1.3.
/// </summary>
[Theory]
[InlineData("x*sinh(c + d*x^3)")]
[InlineData("(f*x)^m*sinh(c + d*x^2)")]
[InlineData("x^m*sinh(a + b/x)")]
[InlineData("x^m*e^(-(a + b*x^2))")]
public void AHyperbolicFunctionOfAPowerOfX(string integrand) => DifferentiatesBack(integrand);

/// <summary>
/// Not where the integral is elementary, an exponential integral or an error function: those keep the form
/// they had.
Expand Down
Loading