diff --git a/BREAKING-CHANGES.md b/BREAKING-CHANGES.md
index cdac56cc4..d67fd2311 100644
--- a/BREAKING-CHANGES.md
+++ b/BREAKING-CHANGES.md
@@ -561,6 +561,22 @@ power, which by parts answers as before ([#233](https://github.com/asc-community
| `"x*(a+b*atanh(c*x))^2/(d+c*d*x)^3".ToEntity().Integrate("x")` | `integral(...)` | 731 characters |
| `"x*(a+b*acoth(c*x))^2/(d+c*d*x)^3".ToEntity().Integrate("x")` | `integral(...)` | 756 characters |
+### A hyperbolic quotient over a linear in its cosine is asked as the cosine's
+
+**Answers where there were none, and shorter than master's.** Rubi's 6.2.5 `sech(x)^3/(a + b cosh(x))` and 6.5.3
+`sech(x)^4/(a + b sech(x))` ran past the corpus's budget. Under the tangent of the half argument each is a cube of
+`1 + t^2` beside a symbolic quadratic, and was answered in about 118,000 characters. By Osborn's rule each is a rational
+function of a cosine alone, over a sum linear in it, and that question is now asked first. In the cosine,
+`1/(cos(s)^3 (a + b cos(s)))` is a partial fraction in it
+([#233](https://github.com/asc-community/AngouriMath/issues/233)).
+
+| Input | Was (2.5.0) | Now |
+|---|---|---|
+| `"sech(x)^3/(a+b*cosh(x))".ToEntity().Integrate("x")` | `integral(...)` | 2,396 characters, where before this change master gave 118,366 |
+| `"sech(x)^4/(a+b*sech(x))".ToEntity().Integrate("x")` | `integral(...)` | 2,412 characters, where before this change master gave 118,032 |
+| `"cosh(x)^3/(a+b*cosh(x))".ToEntity().Integrate("x")` | `integral(...)` | 1,108 characters, where before this change master gave 2,858 |
+| `"cosh(x)^2/(a+b*sech(x))".ToEntity().Integrate("x")` | `integral(...)` | 802 characters, where before this change master gave 2,820 |
+
### An arctangent over a power of `d (1 + i c x)` is integrated under the tangent
**Answers where there were none.** `(a + b atan(c x))^2/(d + i c d x)^2` ran out of time, and so did seven more of
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
index 0ebd2e20e..b00ba9a9a 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/IndefiniteIntegralSolver.cs
@@ -1430,7 +1430,7 @@ static bool APowerOfAQuotientOfLinearsVanishingAtPlusOrMinusOne(Entity inU, Vari
/// s took seconds to decline, five gigabytes for 1/(1 + sinh(x)^3) against 0.2.
///
internal static Entity? SolveAHyperbolicIntegrandAsATrigonometricOne(Entity expr, Entity.Variable x, bool integrateByParts, bool rationalToo,
- bool overAQuadraticInTheSine = false)
+ bool overAQuadraticInTheSine = false, bool overALinearInTheCosine = false)
{
// Only the question asked: a question in s is not cheap to decline, and below the top every
// sub-question a route gives up on would ask it.
@@ -1498,6 +1498,12 @@ static bool APowerOfAQuotientOfLinearsVanishingAtPlusOrMinusOne(Entity inU, Vari
&& AFactorAboveAQuadraticInS(inS, s))
return null;
var question = MathS.i / slopeOfL * inS;
+ // Or, asked as early, only a rational function of the cosine alone over a sum linear in it, or in
+ // the secant: under the tangent of the half argument Rubi's `sech(x)^3/(a + b cosh(x))` is a
+ // cube of `1 + t^2` beside a symbolic quadratic, answered in 118,366 characters, where in the
+ // cosine `1/(cos(s)^3 (a + b cos(s)))` is a partial fraction in it.
+ if (overALinearInTheCosine && !IsARationalFunctionOfTheCosineOverALinearInIt(inS, s))
+ return null;
// Or the one rule for a rational function of a sine or a cosine over a symbolic quadratic in
// it, asked ahead of the exponential substitution and cheap to decline.
if ((overAQuadraticInTheSine
@@ -1520,6 +1526,26 @@ static bool APowerOfAQuotientOfLinearsVanishingAtPlusOrMinusOne(Entity inU, Vari
}).Substitute(s, -MathS.i * linear).InnerSimplified;
return Functions.PartialFractions.DerivativeHoldsAtSampledPoints(answer, expr, x) ? answer : null;
+ // Whether inS holds s only in cos(s), and below the bar a sum linear in it, to the first power:
+ // over `b^2 + 2 a b cos(s) + a^2 cos(s)^2`, the square of one, the question in s took four times
+ // the memory the tangent did, Rubi's 6.7.1 `(a + b cosh(x))/(b + a cosh(x))^2`.
+ static bool IsARationalFunctionOfTheCosineOverALinearInIt(Entity inS, Variable s)
+ {
+ var cosine = MathS.Cos(s);
+ foreach (var node in inS.Nodes)
+ if (node.ContainsNode(s) && node != cosine && node != s
+ && node is not (Sumf or Minusf or Mulf or Divf or Powf(_, Number.Integer)))
+ return false;
+ var (_, below) = Functions.SingleQuotient.Of(inS);
+ var y = Variable.CreateUnique(inS, "y_osb");
+ bool ASum(Entity node) => node is Sumf or Minusf && node.ContainsNode(cosine);
+ bool Linear(Entity sum) => TreeAnalyzer.TryGetPolynomial(sum.Replace(node => node == cosine ? y : node), y, out var read)
+ && read.Keys.Max()!.Equals(EInteger.One);
+ var sums = Mulf.LinearChildren(below).Where(ASum).ToList();
+ return sums.Count > 0 && sums.All(Linear)
+ && !Mulf.LinearChildren(below).Any(factor => factor is Powf(var @base, _) && ASum(@base));
+ }
+
// Whether inS, rational in cos(s) alone or sin(s) alone, has a denominator of degree three or
// more that t = tan(s/2) or t = tan(s) leaves with an irreducible factor of degree above two,
// which the rational rules write only as a sum over roots. The cosine, and the square of the
diff --git a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
index 2341084f9..83739326f 100644
--- a/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
+++ b/Sources/AngouriMath/Functions/Continuous/Integration/Integration.Definition.cs
@@ -1242,6 +1242,9 @@ internal static bool ASumOverRootsWouldAnswer
// `sinh(x)^2/(a + b sinh(x) + c sinh(x)^2)` is a quartic with symbols, and its partial
// fractions ran past the budget, where the sine's rule answers the question in s at once.
if ((answer = IndefiniteIntegralSolver.SolveAHyperbolicIntegrandAsATrigonometricOne(expr, x, integrateByParts, rationalToo: true, overAQuadraticInTheSine: true)) is { }) return answer;
+ // And one of the cosine alone over a sum linear in it, which the tangent made a cube of
+ // `1 + t^2` beside a symbolic quadratic: `sech(x)^3/(a + b cosh(x))` in 118,366 characters.
+ if ((answer = IndefiniteIntegralSolver.SolveAHyperbolicIntegrandAsATrigonometricOne(expr, x, integrateByParts, rationalToo: true, overALinearInTheCosine: true)) is { }) return answer;
if ((answer = IndefiniteIntegralSolver.SolveARationalFunctionOfTheHyperbolicTangent(expr, x, integrateByParts)) is { }) return answer;
// A rational function of a sine or a cosine over a quadratic in it with a symbol
// among the coefficients, split over the quadratic's two roots: under the
diff --git a/Sources/Tests/UnitTests/Calculus/AHyperbolicQuotientOverALinearInItsCosineIntegralTest.cs b/Sources/Tests/UnitTests/Calculus/AHyperbolicQuotientOverALinearInItsCosineIntegralTest.cs
new file mode 100644
index 000000000..d3b365087
--- /dev/null
+++ b/Sources/Tests/UnitTests/Calculus/AHyperbolicQuotientOverALinearInItsCosineIntegralTest.cs
@@ -0,0 +1,51 @@
+//
+// Copyright (c) 2019-2026 Angouri.
+// AngouriMath is licensed under MIT.
+// Details: https://github.com/asc-community/AngouriMath/blob/master/LICENSE.md.
+// Website: https://am.angouri.org.
+//
+
+using System;
+using AngouriMath.Extensions;
+using Xunit;
+
+namespace AngouriMath.Tests.Calculus
+{
+ ///
+ /// A rational function of the hyperbolic cosine alone over a sum linear in it, or in the secant,
+ /// asked by Osborn's rule as one of the cosine before the tangent of the half argument: under that
+ /// tangent Rubi's 6.2.5 sech(x)^3/(a + b cosh(x)) and 6.5.3 sech(x)^4/(a + b sech(x))
+ /// are a cube of 1 + t^2 beside a symbolic quadratic, and were answered in 118,366 and
+ /// 118,032 characters, past the corpus's budget.
+ /// #233
+ ///
+ [Trait("Area", "Calculus")]
+ public sealed class AHyperbolicQuotientOverALinearInItsCosineIntegralTest
+ {
+ [Theory]
+ // Rubi 6.2.5:89.
+ [InlineData("sech(x)^3/(a + b*cosh(x))")]
+ // Rubi 6.5.3:139.
+ [InlineData("sech(x)^4/(a + b*sech(x))")]
+ [InlineData("cosh(x)^2/(a + b*sech(x))")]
+ public void IsAnsweredInTheCosine(string integrand)
+ {
+ var integral = integrand.ToEntity().Integrate("x");
+ var text = integral.Stringize();
+ Assert.DoesNotContain("integral(", text);
+ Assert.True(text.Length < 5000, $"{integrand} came back in {text.Length} characters");
+ Entity Pinned(Entity e) => e.Substitute("a", 1.3).Substitute("b", 0.7);
+ var derivative = Pinned(integral.Substitute("C", 0)).Differentiate("x");
+ var original = Pinned(integrand.ToEntity());
+ foreach (var at in new[] { -2.2, -0.9, 0.3, 1.4, 2.1 })
+ {
+ var want = original.Substitute("x", at).EvalNumerical();
+ var got = derivative.Substitute("x", at).EvalNumerical();
+ Assert.False(got.IsNaN, $"d/dx of the antiderivative of {integrand} has no value at x = {at}, where the integrand is {want}");
+ Assert.True(Math.Abs((double)(got - want).RealPart) + Math.Abs((double)(got - want).ImaginaryPart)
+ < 1e-9 * Math.Max(1, Math.Abs((double)want.RealPart) + Math.Abs((double)want.ImaginaryPart)),
+ $"d/dx of the antiderivative of {integrand} is {got} at x = {at}, where the integrand is {want}");
+ }
+ }
+ }
+}