Skip to content

Commit 3a3d016

Browse files
An even power of the secant or the cosecant under a root is written in the tangent (#1717)
The tangent substitution writes sec^2 as 1 + tan^2 and csc^2 as (1 + tan^2)/tan^2, but went on only where the tangent, or a sine or a cosine under a root, was already in the integrand, so sqrt(a + b csc(x)^2) was declined where sqrt(a + b cot(x)^2) was answered. An even power of the secant or the cosecant under a root goes on now too. Rubi's 4.5.7 and 4.6.7. Part of #718 Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 8f3757c commit 3a3d016

3 files changed

Lines changed: 72 additions & 3 deletions

File tree

‎BREAKING-CHANGES.md‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -896,6 +896,26 @@ its sign on its own, so an answer through two says `provided cos(y) >= 0`
896896
| `"sqrt(a - a*sec(x))".ToEntity().Integrate("x")` | `integral(...)` | a logarithm in `tan(x/2)`, times `sgn(tan(x/2))` |
897897
| `"sqrt(1 + csc(x))".ToEntity().Integrate("x")` | `integral(...)` | an arctangent in `tan(pi/4 - x/2)` |
898898

899+
### An even power of the secant or the cosecant under a root is written in the tangent
900+
901+
**Answers where there were none.** `sqrt(a + b csc(x)^2)`, `(a + b sec(x)^2)^(3/2)` and their kin,
902+
Rubi's 4.5.7 and 4.6.7, were declined, while `sqrt(a + b tan(x)^2)` and `sqrt(a + b cot(x)^2)` were
903+
answered through `u = tan(x)`. That substitution writes an even power of the secant or the
904+
cosecant in the tangent, `sec^2 = 1 + tan^2` and `csc^2 = (1 + tan^2)/tan^2`, but went on to do so
905+
only where the tangent, or a sine or a cosine under a root, was already in the integrand. An even
906+
power of the secant or the cosecant under a root goes on now too. The cosecant's answers carry
907+
`sgn(tan(x))`, from the root of `1/tan(x)^2`
908+
([#718](https://github.com/asc-community/AngouriMath/issues/718)).
909+
910+
| Input | Was (2.5.0) | Now |
911+
|---|---|---|
912+
| `"sqrt(a + b*csc(x)^2)".ToEntity().Integrate("x")` | `integral(...)` | arctangents in `sqrt((a + b) tan(x)^2 + b)`, times `sgn(tan(x))` |
913+
| `"(a + b*csc(c + d*x)^2)^(3/2)".ToEntity().Integrate("x")` | `integral(...)` | the same in `tan(c + d x)` and an algebraic part, by the signs of `a` and `b` |
914+
| `"sqrt(a + b*sec(x)^2)".ToEntity().Integrate("x")` | `integral(...)` | arctangents in `tan(x)/sqrt(a + b (1 + tan(x)^2))` |
915+
| `"1/sqrt(a + b*sec(x)^2)".ToEntity().Integrate("x")` | `integral(...)` | an arctangent or a logarithm in the same, by the sign of `a` |
916+
| `"sqrt(1 + csc(x)^2)".ToEntity().Integrate("x")` | `integral(...)` | logarithms and an arctangent in `sqrt(2 tan(x)^2 + 1)`, times `sgn(tan(x))` |
917+
| `"1/sqrt(-1 + csc(x)^2)".ToEntity().Integrate("x")` | `integral(...)` | `sgn(tan(x)) ln(1 + tan(x)^2)/2` |
918+
899919
### A partial-fraction coefficient with symbols in it is in lowest terms, its rational content included
900920

901921
**Improvement, not silent.** The decomposition over written factors with symbols among their

‎Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs‎

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8464,9 +8464,13 @@ node is Powf(var product, Number.Rational fraction) && fraction is not Number.In
84648464
: node);
84658465

84668466
var tangent = MathS.Tan(x);
8467-
// Or a sine or a cosine under a root, for the writing by the sign below; a rational
8468-
// function of those is the half-angle substitution's.
8469-
if (!expr.ContainsNode(tangent) && !(HasARadicalOf(expr, x) && expr.Nodes.Any(node => node is Sinf or Cosf && node.ContainsNode(x))))
8467+
// Or a sine or a cosine under a root, for the writing by the sign below, or an even
8468+
// power of the secant or the cosecant under one, which the next step writes in the
8469+
// tangent: `sqrt(a + b csc(x)^2)` is `sqrt(a + b + b/tan(x)^2)`. A rational function
8470+
// of those is the half-angle substitution's.
8471+
if (!expr.ContainsNode(tangent) && !(HasARadicalOf(expr, x) && expr.Nodes.Any(node =>
8472+
node is Sinf or Cosf && node.ContainsNode(x)
8473+
|| node is Powf(Secantf or Cosecantf, Number.Integer { EInteger.IsEven: true }) && node.ContainsNode(x))))
84708474
return null;
84718475

84728476
// An even power of the secant, cosine, sine or cosecant of x is a rational function

‎Sources/Tests/UnitTests/Calculus/TangentSubstitutionIntegralTest.cs‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,51 @@ private static void DifferentiatesBack(string integrand)
9797
[InlineData("(sec(x)^2 - 3*sqrt(4*sec(x)^2 + 5*tan(x)^2)*tan(x))/(sin(x)^2*(4*sec(x)^2 + 5*tan(x)^2)^(3/2))")]
9898
public void AnEvenPowerOfTheOthersIsWrittenInTheTangent(string integrand) => DifferentiatesBack(integrand);
9999

100+
/// <summary>
101+
/// The same under a root with no tangent beside it, Rubi's 4.5.7 and 4.6.7:
102+
/// <c>sqrt(a + b csc(x)^2)</c> is <c>sqrt(a + b (1 + u^2)/u^2)</c> under the tangent. On both
103+
/// signs of the tangent, which the cosecant's answer reads, with the symbols pinned before
104+
/// the derivative is taken: <c>sgn(tan(c + d x))</c> is flat only where <c>c</c> and
105+
/// <c>d</c> are real.
106+
/// </summary>
107+
[Theory]
108+
[InlineData("sqrt(a + b*csc(x)^2)")]
109+
[InlineData("(a + b*csc(x)^2)^(3/2)")]
110+
[InlineData("1/(a + b*csc(x)^2)^(3/2)")]
111+
[InlineData("sqrt(a + b*sec(x)^2)")]
112+
[InlineData("1/sqrt(a + b*sec(x)^2)")]
113+
[InlineData("sqrt(a + b*csc(c + d*x)^2)")]
114+
[InlineData("sqrt(1 + csc(x)^2)")]
115+
[InlineData("1/sqrt(-1 + csc(x)^2)")]
116+
public void AnEvenPowerOfTheSecantOrTheCosecantUnderARoot(string integrand)
117+
{
118+
var integral = integrand.ToEntity().Integrate("x");
119+
Assert.DoesNotContain("integral(", integral.Stringize());
120+
var pins = new (string, double)[] { ("a", 1.3), ("b", 0.7), ("c", 0.4), ("d", 1.1) };
121+
var answer = integral.Substitute("C", 0);
122+
var original = integrand.ToEntity();
123+
foreach (var (name, value) in pins)
124+
{
125+
answer = answer.Substitute(name, value);
126+
original = original.Substitute(name, value);
127+
}
128+
var derivative = answer.Differentiate("x");
129+
var compared = 0;
130+
foreach (var at in new[] { -2.6, -0.9, 0.4, 1.1, 1.9, 2.7 })
131+
{
132+
var got = derivative.Substitute("x", at).EvalNumerical();
133+
var want = original.Substitute("x", at).EvalNumerical();
134+
if (got.IsNaN || want.IsNaN)
135+
continue;
136+
compared++;
137+
var difference = Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart);
138+
var scale = Math.Max(1.0, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart));
139+
Assert.True(difference / scale < 1e-9,
140+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
141+
}
142+
Assert.True(compared >= 4, $"only {compared} points could be compared for {integrand}");
143+
}
144+
100145
/// <summary>
101146
/// An odd power of the sine or the cosine is its sign times a function of the tangent,
102147
/// <c>cos(x) = sgn(cos(x))/sqrt(1 + tan^2)</c> and <c>sin(x) = tan(x) cos(x)</c>, the sign a

0 commit comments

Comments
 (0)