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
19 changes: 17 additions & 2 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,21 @@ quotient of two such linears the sum is `(b - d t^2)^2 + (c t^2 - a)^2`. Rubi's
| `"(c + d*tan(x))^(3/2)/(a + b*tan(x))^3".ToEntity().Integrate("x")` | `integral(...)` | the same |
| `"1/((a + b*tan(x))^(3/2)*(c + d*tan(x))^(3/2))".ToEntity().Integrate("x")` | `integral(...)`; past a minute on the unreleased master | in the root of the quotient of the two, in a second |

### `a + i a tan` below an odd power of the secant is written over its conjugate

**Answers where there were none, and shorter ones.** `sec(x)^7/(a + i a tan(x))^4` was declined, with
the rest of Rubi's 4.3.1.2 that is an odd power of the secant over a whole power of `a + i a tan`. The sum
times `a - i a tan(z)` is `a^2 sec(z)^2`, so `sec(z)^s/(a + i a tan(z))^n` is
`sec(z)^(s - 2 n) (a - i a tan(z))^n/a^(2 n)`, a whole power of the conjugate beside one of the secant,
and it is integrated as that. Those integrated in `u = a + i a tan(z)` before come out a tenth as long
([#718](https://github.com/asc-community/AngouriMath/issues/718)).

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"sec(x)^7/(a + i*a*tan(x))^4".ToEntity().Integrate("x")` | `integral(...)` | 371 characters |
| `"sec(x)^9/(a + i*a*tan(x))^8".ToEntity().Integrate("x")` | `integral(...)` | 745 characters |
| `"sec(x)^5/(a + i*a*tan(x))^2".ToEntity().Integrate("x")` | `integral(...)`; 2,431 characters on the unreleased master | 225 characters |

### An odd power of the secant over a whole power of `a + i a tan` is integrated in the sum

**Answers where there were none.** `sec(x)^5/(a + i a tan(x))^2` was declined: the rule that integrates
Expand All @@ -379,8 +394,8 @@ right answers were declined after seconds

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"sec(x)^5/(a + i*a*tan(x))^2".ToEntity().Integrate("x")` | `integral(...)` | 2,431 characters |
| `"sec(x)^7/(a + i*a*tan(x))^3".ToEntity().Integrate("x")` | `integral(...)` | 3,774 characters |
| `"sec(x)^5/(a + i*a*tan(x))^2".ToEntity().Integrate("x")` | `integral(...)` | 225 characters |
| `"sec(x)^7/(a + i*a*tan(x))^3".ToEntity().Integrate("x")` | `integral(...)` | 289 characters |

### A power of the cosine beside a power of `a + i a tan` is read as one of the secant

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27047,10 +27047,15 @@ static Entity SumOfThePowers(Entity first, Entity second)
Entity? sumPower = null;
Entity secantPower = Number.Integer.Zero;
var sawSecant = false;
// Everything but the sum, for the rewrite of a whole power of it below.
Entity others = Number.Integer.One;
foreach (var (factor, underneath) in FactorsOfTheIntegrand(expr))
{
if (!factor.ContainsNode(x))
{
others = underneath ? others / factor : others * factor;
continue;
}
var (@base, power) = factor is Powf(var b, var p) && !p.ContainsNode(x)
? (b, p.Evaled is Number.Rational r ? r : p)
: (factor, (Entity)Number.Integer.One);
Expand All @@ -27077,27 +27082,41 @@ static Entity SumOfThePowers(Entity first, Entity second)
if (of is null || argument is not null && argument != of)
return null;
argument = of;
others = underneath ? others / factor : others * factor;
secantPower = sign == 1 ? secantPower + power : secantPower - power;
sawSecant = true;
}
if (sumPower is null || sum is null || argument is null || !sawSecant
|| !TreeAnalyzer.TryGetPolyLinear(argument, x, out var slope, out _) || TreeAnalyzer.IsZero(slope))
return null;
secantPower = secantPower is Number ? secantPower : secantPower.InnerSimplified;
// Whole powers on both are left to the rules for the sine and the cosine, which answer
// `cos(x)^5/(a + i a tan(x))^3` and `sec(x)^3/(a + i a tan(x))^4` in a fraction of a second
// where in u they ran past five -- but for an odd power s of the secant over the sum's n-th
// with s + 2 n = 1. Then u^n (sec(z)^2)^((s - 2)/2) is a whole power of 2 A - u over the root
// of u, which is answered in a second, and `sec(x)^5/(a + i a tan(x))^2` was declined by
// every route but this.
if (sumPower is Number.Integer { EInteger: var whole } && secantPower is Number.Integer { EInteger: var secant }
&& !(secant + whole * 2).Equals(EInteger.One))
return null;
Entity constantTerm = Number.Integer.Zero;
foreach (var term in Sumf.LinearChildren(sum))
if (!term.ContainsNode(x))
constantTerm += term;
var a = constantTerm.InnerSimplified;
// Whole powers on both. An odd power s of the secant over the sum's n-th: the sum times its
// conjugate is A^2 sec(z)^2, so `sec(x)^7/(a + i a tan(x))^4` is
// `sec(x)^(-1) (a - i a tan(x))^4/a^8`, a whole power of the conjugate beside one of the
// secant, which the rules for the sine and the cosine answer in a fraction of a second. In u
// it ran past five, or with s + 2 n = 1 took two seconds for an answer ten times as long.
// An even power is left to those rules as written, which answer `sec(x)^4/(a + i a tan(x))^3`
// shorter than its rewrite, and so is an odd power of the cosine, `cos(x)/(a + i a tan(x))^4`,
// which they answer several times sooner; and a whole power above the bar to them too, but for
// s + 2 n = 1, where u^n (sec(z)^2)^((s - 2)/2) is a whole power of 2 A - u over the root of u.
if (sumPower is Number.Integer { EInteger: var whole } && secantPower is Number.Integer { EInteger: var secant })
{
if (whole.Sign < 0 && secant.Sign > 0 && !secant.IsEven && whole.CanFitInInt32())
{
var n = -whole.ToInt32Checked();
var conjugate = a + (plus ? -MathS.i : MathS.i) * a * MathS.Tan(argument);
return Integration.ComputeAsTheSameQuestion(
(others * MathS.Pow(conjugate, n) * MathS.Pow(MathS.Sec(argument), -2 * n) / MathS.Pow(a, 2 * n)).InnerSimplified,
x, integrateByParts);
}
if (!(secant + whole * 2).Equals(EInteger.One))
return null;
}
var u = Variable.CreateUnique(expr, "u_tan");
var half = ((secantPower - 2) / 2).InnerSimplified;
Entity squared = MathS.Pow(u / a, half) * MathS.Pow((2 * a - u) / a, half);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ public sealed class SecantBesideAnImaginaryTangentSumIntegralTest
[InlineData("cos(x)^9*(a + i*a*tan(x))^(7/2)")]
[InlineData("(m*sec(x))^(2/3)*(a + i*a*tan(x))^(5/3)")]
[InlineData("sec(x)^5/(a + i*a*tan(x))^2")]
[InlineData("sec(x)^7/(a + i*a*tan(x))^4")]
[InlineData("sec(x)^9/(a + i*a*tan(x))^8")]
[InlineData("(k*sec(x))^3/(a - i*a*tan(x))^2")]
public void InTheSum(string integrand)
{
var integral = integrand.ToEntity().Integrate("x");
Expand Down
Loading