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
14 changes: 14 additions & 0 deletions BREAKING-CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,20 @@ answer on the far side of a root gets a real expression where it used to get a c
| `1/(x*(-4+x^2)^4)` | 8,472 ms | 1,878 ms |
| `1/((1+x)^3*(2+x)^3)` | 1,343 ms | 492 ms |

### An odd power of the secant is read in the tangent, with the cosine's sign

**Answers where there were none.** `sec(x)^5/(a + b tan(x))^2` was declined: the substitution
`u = tan(x)` read an odd power of the sine or the cosine as its sign times a function of the tangent,
`cos(x) = sgn(cos(x))/sqrt(1 + u^2)`, and not the secant, which is the same the other way up. It reads the
secant too now, and the integrand is `sgn(cos(x)) (1 + u^2)^(3/2)/(a + b u)^2` in `u`
([#718](https://github.com/asc-community/AngouriMath/issues/718)).

| Input | Was (2.5.0) | Now |
|---|---|---|
| `"sec(x)^5/(a + b*tan(x))^2".ToEntity().Integrate("x")` | `integral(...)` | in `sgn(cos(x))` and `tan(x)`, 901 characters |
| `"sec(x)^7/(a + b*tan(x))^3".ToEntity().Integrate("x")` | `integral(...)` | 1,253 characters |
| `"sec(x)/(a + b*cot(x))".ToEntity().Integrate("x")` | `integral(...)` | 571 characters |

### A whole power of the radicand under Euler's substitution is read as one

**Answers where there were none, and none where they were wrong.** Euler's substitution writes the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10283,6 +10283,11 @@ static bool IsTwice(Entity argument, Entity.Variable x)
=> MathS.Pow(sign / rootOfSecantSquared, k),
Powf(Sinf(var a), Number.Integer k) when a == x && k.EInteger.CanFitInInt32() && !k.EInteger.IsEven
=> MathS.Pow(sign * tangent / rootOfSecantSquared, k),
// And the secant is the cosine the other way up, the sign its own inverse:
// `sec(x)^5/(a + b tan(x))^2` is `sgn(cos(x)) (1 + u^2)^(5/2)/(a + b u)^2`.
Secantf(var a) when a == x => sign * rootOfSecantSquared,
Powf(Secantf(var a), Number.Integer k) when a == x && k.EInteger.CanFitInInt32() && !k.EInteger.IsEven
=> MathS.Pow(sign * rootOfSecantSquared, k),
_ => node,
}).Substitute(tangent, uSub);
if (odd.ContainsNode(x) || !IsAlgebraicIn(odd, uSub))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,20 @@ private static void DifferentiatesBack(string integrand)
[InlineData("sqrt(a + b*csc(c + d*x)^2)")]
[InlineData("sqrt(1 + csc(x)^2)")]
[InlineData("1/sqrt(-1 + csc(x)^2)")]
public void AnEvenPowerOfTheSecantOrTheCosecantUnderARoot(string integrand)
public void AnEvenPowerOfTheSecantOrTheCosecantUnderARoot(string integrand) => DifferentiatesBackWithTheSymbolsPinned(integrand);

/// <summary>
/// An odd power of the secant is the cosine's the other way up: <c>sec(x)^5/(a + b tan(x))^2</c>
/// is <c>sgn(cos(x)) (1 + u^2)^(3/2)/(a + b u)^2</c> under <c>u = tan(x)</c>. Rubi's 4.3.1.2,
/// checked on both signs of the cosine.
/// </summary>
[Theory]
[InlineData("sec(x)^5/(a + b*tan(x))^2")]
[InlineData("sec(x)^7/(a + b*tan(x))^3")]
[InlineData("sec(c + d*x)^5/(a + b*tan(c + d*x))^3")]
public void AnOddPowerOfTheSecantIsItsSignTimesAFunctionOfTheTangent(string integrand) => DifferentiatesBackWithTheSymbolsPinned(integrand);

private static void DifferentiatesBackWithTheSymbolsPinned(string integrand)
{
var integral = integrand.ToEntity().Integrate("x");
Assert.DoesNotContain("integral(", integral.Stringize());
Expand Down
Loading