Skip to content

Commit fc1d521

Browse files
Integrate fractional trigonometric powers two apart by the reduction, and a sine raised from nothing as a derivative (#2031)
- A sum of powers of one sine, cosine, secant or cosecant of a linear, the powers not whole and two apart, by the reduction formula from the highest down; each power alone is elliptic. Beside x, by parts once. - The derivative of a sine raised from nothing times powers of the cosine and sums in it, or of a cosine beside the sine. - A cosine beside a function of the sine with a power of it that is not rational, in s = sin(x). - (c sin(a + b x)^n)^(1/n) as a constant times sin(a + b x) between the zeros of the sine, and so for the cosine. - Under the homogeneous substitution, factors written alike on both sides cancelled; under the tangent, a whole power of a product distributed; and the root of 1 - cos(x)^2 beside a root of 1 - cos(x) as the product of the roots of 1 - cos(x) and 1 + cos(x). Chain against master f7f2a7a: pocket of 2,005 rows, 1,979 -> 1,998 solved, 0 wrong; family 4's sample 1,025 -> 1,026, the others unchanged; the 19 rows that moved, alone, 0 -> 19 solved; 7,510 rows compared for allocation, none grew past 55 MB. The new test that the power-of-x case is left to the rules before it pinned `c > 0` in the answer to (c x^n)^(1/n), as those wrote it before #2012; master writes x (c x^n)^(1/n)/2, whose derivative is the integrand on every branch since d/dx (c x^n)^(1/n) = (c x^n)^(1/n)/x, and the test pins that. Part of #233. Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 86d60b9 commit fc1d521

9 files changed

Lines changed: 930 additions & 4 deletions

‎BREAKING-CHANGES.md‎

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3812,6 +3812,38 @@ of the six functions read inside a power as it is
38123812
| `"(csc(x) - sin(x))^(5/2)".ToEntity().Integrate("x")` | `integral(...)` | powers of `sin(x)` times `(cos(x)^2/sin(x))^(5/2)` |
38133813
| `"1/(sec(x) - cos(x))^(3/2)".ToEntity().Integrate("x")` | `integral(...)` | a root of `cos(x)` with a logarithm and an arctangent, times `(sin(x)^2/cos(x))^(-3/2)` |
38143814

3815+
### Fractional trigonometric powers two apart, and a sine raised from nothing, are integrated as derivatives
3816+
3817+
**Answers where there were none.** Rubi's trigonometric integrands of these shapes were declined or ran out of time
3818+
([#233](https://github.com/asc-community/AngouriMath/issues/233)):
3819+
- A sum of powers of one sine, cosine, secant or cosecant of a linear, the powers not whole and two apart, by the
3820+
reduction formula from the highest down: `(cos sin^(n - 1))' = (n - 1) sin^(n - 2) - n sin^n`, and its kind for the
3821+
others. Each power alone is elliptic, so split, `(3 + 3 sec(c + d x)^2)/sqrt(sec(c + d x))` was two declined
3822+
integrals. Beside x, by parts once: `x/csc(c + d x)^(3/2) - x sqrt(csc(c + d x))/3`. The written function is kept.
3823+
- The derivative of a sine raised from nothing times powers of the cosine and sums in it, or of a cosine beside the
3824+
sine: `(a + a cos(x))^(3/2)/cos(x)^(5/4)` is `(4 a^2 sin(x)/(cos(x)^(1/4) sqrt(a + a cos(x))))'`. Beside x, by parts
3825+
once: `x (b + a sin(x))/(a + b sin(x))^2` is `x G - integral G` for `G = -cos(x)/(a + b sin(x))`.
3826+
- A cosine beside a function of the sine with a power of it that is not rational, in `s = sin(x)`:
3827+
`cos(x)/(sin(x) + sin(x)^sqrt(2))` is `1/(s + s^sqrt(2))`.
3828+
- `(c sin(a + b x)^n)^(1/n)` is `K sin(a + b x)` with `K = (c sin(a + b x)^n)^(1/n)/sin(a + b x)`, constant between the
3829+
zeros of the sine, and so for the cosine.
3830+
- Under the homogeneous substitution, factors written alike on both sides are cancelled where the quotient was
3831+
simplified: `sin(c + d x)^6/(a + b sin(c + d x)^2)^2`. Under the tangent, a whole power of a product is distributed
3832+
over its factors: `cot(c + d x)^2/(a + b sec(c + d x)^2)^2`. And beside a root of `1 - cos(x)`, the root of
3833+
`1 - cos(x)^2` is the product of the roots of `1 - cos(x)` and `1 + cos(x)`: `sqrt(1 - cos(x))/sqrt(a - cos(x))`.
3834+
3835+
| Input | Was (2.5.0) | Now |
3836+
|---|---|---|
3837+
| `"(3+3*sec(c+d*x)^2)/sec(c+d*x)^(1/2)".ToEntity().Integrate("x")` | `integral(...)` | 60 characters |
3838+
| `"x/csc(c+d*x)^(3/2)-1/3*x*sqrt(csc(c+d*x))".ToEntity().Integrate("x")` | `integral(...)` | 131 characters |
3839+
| `"(a+a*cos(c+d*x))^(3/2)/cos(c+d*x)^(5/4)".ToEntity().Integrate("x")` | `integral(...)` | 96 characters |
3840+
| `"x*(b+a*sin(x))/(a+b*sin(x))^2".ToEntity().Integrate("x")` | `integral(...)` | 64 characters |
3841+
| `"cos(x)/(sin(x)+sin(x)^sqrt(2))".ToEntity().Integrate("x")` | `integral(...)` | 86 characters |
3842+
| `"(c*sin(a+b*x)^n)^(1/n)".ToEntity().Integrate("x")` | `integral(...)` | 77 characters |
3843+
| `"sin(c+d*x)^6/(a+b*sin(c+d*x)^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 2,169 characters |
3844+
| `"cot(c+d*x)^2/(a+b*sec(c+d*x)^2)^2".ToEntity().Integrate("x")` | `integral(...)` | 1,963 characters |
3845+
| `"sqrt(1-cos(x))/sqrt(a-cos(x))".ToEntity().Integrate("x")` | `integral(...)` | 70 characters |
3846+
38153847
### A product of powers of the trigonometric functions, some not whole, is integrated as sine and cosine powers
38163848

38173849
**Answers where there were none.** `(a sin(x))^(5/2) sqrt(b sec(x))` was declined, and so were

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

Lines changed: 545 additions & 4 deletions
Large diffs are not rendered by default.

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,6 +684,17 @@ private static Entity WithItsPiecewiseSumsCombined(Entity expr)
684684
// A symbolic power of a sine, cosine, secant or cosecant times `alpha + beta f^2`, where it is
685685
// the derivative of `cos sin^(m + 1)`, `sin cos^(m + 1)`, `tan sec^m` or `cot csc^m`.
686686
if ((answer = IndefiniteIntegralSolver.SolveASymbolicPowerOfATrigonometricFunctionAsTheDerivativeOfAProduct(expr, x)) is { }) return answer;
687+
// And numbers not whole for the exponents, two apart, by the reduction from the highest
688+
// down: split, `1/csc(u)^(3/2) - sqrt(csc(u))/3` is two elliptic integrals.
689+
if ((answer = IndefiniteIntegralSolver.SolveFractionalPowersOfATrigonometricFunctionTwoApartByTheReduction(expr, x)) is { }) return answer;
690+
// And the derivative of a sine raised from nothing times powers of the cosine and sums in it,
691+
// or of a cosine beside the sine, alone or beside x by parts: the half angle declined
692+
// `(a + a cos(u))^(3/2)/cos(u)^(5/4)`, and parts integrated `x (b + a sin(x))/(a + b sin(x))^2`'s
693+
// derivative into a function of tan(x/2) and ran out of time.
694+
if ((answer = IndefiniteIntegralSolver.SolveAsTheDerivativeOfASineRaisedFromNothingBesidePowersOfTheCosine(expr, x, integrateByParts)) is { }) return answer;
695+
// A cosine beside a function of the sine with a power off the rationals in it, in the sine:
696+
// the substitution search declined `cos(x)/(sin(x) + sin(x)^sqrt(2))`.
697+
if ((answer = IndefiniteIntegralSolver.SolveACosineBesideAFunctionOfTheSineWithAnIrrationalPowerInIt(expr, x, integrateByParts)) is { }) return answer;
687698
// A power of a sine, cosine or hyperbolic one over a binomial in a power of it, over the
688699
// binomial's roots, before the rules that spent the budget on `sinh(y)^4/(a + b sinh(y)^3)`.
689700
if ((answer = IndefiniteIntegralSolver.SolveAPowerOverABinomialInAPowerOfASineOverItsRoots(expr, x)) is { }) return answer;
@@ -1101,6 +1112,9 @@ private static Entity WithItsPiecewiseSumsCombined(Entity expr)
11011112
// A fractional power of a constant times an even power of a function, the function
11021113
// taken out with its sign: `(a sin(x)^2)^(5/2)` is `a^(5/2) sgn(sin(x)) sin(x)^5`.
11031114
if ((answer = IndefiniteIntegralSolver.SolveByTakingAFunctionOutOfAPowerOfItsEvenPower(expr, x, integrateByParts)) is { }) return answer;
1115+
// And a symbolic root of a power, `(c sin(u)^n)^(1/n)`, the function out and the rest a
1116+
// constant written back.
1117+
if ((answer = IndefiniteIntegralSolver.SolveByTakingAFunctionOutOfASymbolicRootOfItsPower(expr, x, integrateByParts)) is { }) return answer;
11041118
// A sum of two roots below the bar, multiplied above and below by its conjugate:
11051119
// `1/(sqrt(A) - sqrt(B))` is `(sqrt(A) + sqrt(B))/(A - B)`.
11061120
if ((answer = IndefiniteIntegralSolver.SolveByRationalisingASumOfRoots(expr, x, integrateByParts)) is { }) return answer;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
//
2+
// Copyright (c) 2019-2026 Angouri.
3+
// AngouriMath is licensed under MIT.
4+
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
5+
// Website: https://am.angouri.org.
6+
//
7+
8+
using System;
9+
using AngouriMath.Extensions;
10+
using Xunit;
11+
12+
namespace AngouriMath.Tests.Calculus
13+
{
14+
/// <summary>
15+
/// A cosine beside a function of the sine with a power of it off the rationals, integrated in the
16+
/// sine, and a sine beside the cosine the same: Rubi's 4.7.7 <c>cos(x)/(sin(x) + sin(x)^sqrt(2))</c>.
17+
/// <a href="https://github.com/asc-community/AngouriMath/issues/233">#233</a>
18+
/// </summary>
19+
[Trait("Area", "Calculus")]
20+
public sealed class ACosineBesideAFunctionOfTheSineWithAnIrrationalPowerIntegralTest
21+
{
22+
[Theory]
23+
[InlineData("cos(x)/(sin(x)+sin(x)^sqrt(2))")]
24+
[InlineData("cos(c+d*x)/(sin(c+d*x)+sin(c+d*x)^p)")]
25+
[InlineData("sin(c+d*x)*cos(c+d*x)^pi*(1+cos(c+d*x))")]
26+
public void IsAnsweredAndDifferentiatesBack(string integrand)
27+
{
28+
var integral = integrand.ToEntity().Integrate("x");
29+
var text = integral.Stringize();
30+
Assert.DoesNotContain("integral(", text);
31+
Entity Pinned(Entity e) => e.Substitute("c", 0.3).Substitute("d", 0.75).Substitute("p", 2.5);
32+
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
33+
var original = Pinned(integrand.ToEntity());
34+
var compared = 0;
35+
foreach (var at in new[] { -2.3, -1.1, -0.7, 0.4, 1.9, 2.8 })
36+
{
37+
var want = original.Substitute("x", at).EvalNumerical();
38+
var got = derivative.Substitute("x", at).EvalNumerical();
39+
if (want.IsNaN)
40+
continue;
41+
compared++;
42+
Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
43+
< 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
44+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
45+
}
46+
Assert.True(compared >= 5, $"only {compared} points could be compared for {integrand}");
47+
}
48+
}
49+
}
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
//
2+
// Copyright (c) 2019-2026 Angouri.
3+
// AngouriMath is licensed under MIT.
4+
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
5+
// Website: https://am.angouri.org.
6+
//
7+
8+
using System;
9+
using AngouriMath.Extensions;
10+
using Xunit;
11+
12+
namespace AngouriMath.Tests.Calculus
13+
{
14+
/// <summary>
15+
/// A symbolic root of a constant times a power of a function, <c>(c sin(u)^n)^(1/n)</c>, as the
16+
/// function times a factor constant between its zeros, written back: Rubi's 4.1.7 and 4.2.0.
17+
/// <a href="https://github.com/asc-community/AngouriMath/issues/233">#233</a>
18+
/// </summary>
19+
[Trait("Area", "Calculus")]
20+
public sealed class AFunctionOutOfASymbolicRootOfItsPowerIntegralTest
21+
{
22+
[Theory]
23+
[InlineData("(c*sin(a+b*x)^n)^(1/n)")]
24+
[InlineData("(c*cos(a+b*x)^m)^(1/m)")]
25+
[InlineData("x*(c*cos(x)^m)^(1/m)")]
26+
[InlineData("(c*sin(x)^n)^(2/n)")]
27+
public void IsAnsweredAndDifferentiatesBack(string integrand)
28+
{
29+
var integral = integrand.ToEntity().Integrate("x");
30+
var text = integral.Stringize();
31+
Assert.DoesNotContain("integral(", text);
32+
Entity Pinned(Entity e) => e.Substitute("a", 0.3).Substitute("b", 0.75).Substitute("c", 1.3).Substitute("n", 2.5).Substitute("m", 0.4);
33+
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
34+
var original = Pinned(integrand.ToEntity());
35+
var compared = 0;
36+
foreach (var at in new[] { -2.3, -1.1, -0.7, 0.4, 1.9, 2.8 })
37+
{
38+
var want = original.Substitute("x", at).EvalNumerical();
39+
var got = derivative.Substitute("x", at).EvalNumerical();
40+
if (want.IsNaN)
41+
continue;
42+
compared++;
43+
Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
44+
< 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
45+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
46+
}
47+
Assert.True(compared >= 5, $"only {compared} points could be compared for {integrand}");
48+
}
49+
50+
[Fact]
51+
public void LeavesAPowerOfXToTheRulesForBinomials()
52+
{
53+
// (c x^n)^(1/n) is the rule's for a symbolic power of a monomial: `x (c x^n)^(1/n)/2`,
54+
// whose derivative is `(c x^n)^(1/n)/2 + x (c x^n)^(1/n)/(2 x)`, the integrand on every
55+
// branch, since d/dx (c x^n)^(1/n) is (c x^n)^(1/n)/x on every one.
56+
var integral = "(c*x^n)^(1/n)".ToEntity().Integrate("x").Stringize();
57+
Assert.Equal("x * (c * x ^ n) ^ (1 / n) / 2 + C", integral);
58+
}
59+
}
60+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
//
2+
// Copyright (c) 2019-2026 Angouri.
3+
// AngouriMath is licensed under MIT.
4+
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
5+
// Website: https://am.angouri.org.
6+
//
7+
8+
using System;
9+
using AngouriMath.Extensions;
10+
using Xunit;
11+
12+
namespace AngouriMath.Tests.Calculus
13+
{
14+
/// <summary>
15+
/// A quotient of sines and cosines with symbols in it, written in the tangent with the factors alike
16+
/// on both sides of the bar cancelled rather than simplified: Rubi's 4.1.7 and 4.5.7, whose
17+
/// simplification ran past the budget.
18+
/// <a href="https://github.com/asc-community/AngouriMath/issues/233">#233</a>
19+
/// </summary>
20+
[Trait("Area", "Calculus")]
21+
public sealed class AQuotientInTheTangentWithItsSymbolsCancelledIntegralTest
22+
{
23+
[Theory]
24+
[InlineData("sin(c+d*x)^6/(a+b*sin(c+d*x)^2)^2")]
25+
[InlineData("csc(c+d*x)^2/(a-b*sin(c+d*x)^4)^2")]
26+
[InlineData("cot(c+d*x)^2/(a+b*sec(c+d*x)^2)^2")]
27+
[InlineData("sin(x)^4/(a+b*sin(x)^2)^2")]
28+
public void IsAnsweredAndDifferentiatesBack(string integrand)
29+
{
30+
var integral = integrand.ToEntity().Integrate("x");
31+
var text = integral.Stringize();
32+
Assert.DoesNotContain("integral(", text);
33+
Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("b", 0.7).Substitute("c", 0.3).Substitute("d", 0.75);
34+
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
35+
var original = Pinned(integrand.ToEntity());
36+
var compared = 0;
37+
foreach (var at in new[] { -2.3, -1.1, -0.7, 0.4, 1.9, 2.8 })
38+
{
39+
var want = original.Substitute("x", at).EvalNumerical();
40+
var got = derivative.Substitute("x", at).EvalNumerical();
41+
if (want.IsNaN)
42+
continue;
43+
compared++;
44+
Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
45+
< 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
46+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
47+
}
48+
Assert.True(compared >= 5, $"only {compared} points could be compared for {integrand}");
49+
}
50+
}
51+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
//
2+
// Copyright (c) 2019-2026 Angouri.
3+
// AngouriMath is licensed under MIT.
4+
// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
5+
// Website: https://am.angouri.org.
6+
//
7+
8+
using System;
9+
using AngouriMath.Extensions;
10+
using Xunit;
11+
12+
namespace AngouriMath.Tests.Calculus
13+
{
14+
/// <summary>
15+
/// The derivative of a sine raised from nothing times powers of the cosine, the secant and sums
16+
/// in them, or of a cosine beside the sine, alone or beside x by parts: Rubi's 4.2.2.1, 4.5.1.2,
17+
/// 4.5.4.2 and 4.7.7.
18+
/// <a href="https://github.com/asc-community/AngouriMath/issues/233">#233</a>
19+
/// </summary>
20+
[Trait("Area", "Calculus")]
21+
public sealed class ASineRaisedFromNothingBesidePowersOfTheCosineIntegralTest
22+
{
23+
// Points where the cosine is negative too, where the integrand is complex and the answer's
24+
// principal powers still differentiate to it.
25+
[Theory]
26+
[InlineData("(a+a*cos(c+d*x))^(3/2)/cos(c+d*x)^(5/4)")]
27+
[InlineData("(a+a*cos(c+d*x))^(3/2)*sec(c+d*x)^(5/4)")]
28+
[InlineData("(a+a*sec(c+d*x))^(3/2)/sec(c+d*x)^(1/4)")]
29+
[InlineData("(a+a*sec(c+d*x))^n*(-a*A*n-a*Q*(1+n)*sec(c+d*x))/(a*(1+n)*sec(c+d*x)^n)+sec(c+d*x)^(-1-n)*(a+a*sec(c+d*x))^n*(A+Q*sec(c+d*x)^2)")]
30+
[InlineData("x*(b+a*sin(x))/(a+b*sin(x))^2")]
31+
[InlineData("x*(b+a*cos(c+d*x))/(a+b*cos(c+d*x))^2")]
32+
public void IsAnsweredAndDifferentiatesBack(string integrand)
33+
{
34+
var integral = integrand.ToEntity().Integrate("x");
35+
var text = integral.Stringize();
36+
Assert.DoesNotContain("integral(", text);
37+
Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("b", 0.7).Substitute("c", 0.3).Substitute("d", 0.75)
38+
.Substitute("A", 0.6).Substitute("Q", 1.25).Substitute("n", 0.4);
39+
var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
40+
var original = Pinned(integrand.ToEntity());
41+
var compared = 0;
42+
foreach (var at in new[] { -2.3, -1.1, -0.7, 0.4, 1.9, 2.8 })
43+
{
44+
var want = original.Substitute("x", at).EvalNumerical();
45+
var got = derivative.Substitute("x", at).EvalNumerical();
46+
if (want.IsNaN)
47+
continue;
48+
compared++;
49+
Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
50+
< 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
51+
$"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
52+
}
53+
Assert.True(compared >= 5, $"only {compared} points could be compared for {integrand}");
54+
}
55+
56+
[Fact]
57+
public void IsTheRaisedProductInClosedForm()
58+
{
59+
// 4 a^2 sin/(cos^(1/4) sqrt(a + a cos)), Rubi's, with no half angle in it.
60+
var integral = "(a+a*cos(x))^(3/2)/cos(x)^(5/4)".ToEntity().Integrate("x").Stringize();
61+
Assert.DoesNotContain("x / 2", integral);
62+
Assert.Contains("cos(x) ^ (-1/4)", integral);
63+
}
64+
}
65+
}

0 commit comments

Comments
 (0)