@@ -7157,10 +7157,12 @@ private static bool TheInverseIsBelowTheBar(Entity expr, Entity inverse, Entity.
71577157 /// and the cosine is not negative; substituting and simplifying instead would leave
71587158 /// <c>sqrt(1 - sin(u)^2)</c>, which the simplifier is right not to call <c>cos(u)</c>.
71597159 /// So <c>(1 - x^2)^(k/2)</c> becomes <c>cos(u)^k</c> directly, and likewise
7160- /// <c>(1 + x^2)^(k/2)</c> into <c>sec(u)^k</c> for the tangent and <c>(x^2 - 1)^(k/2)</c>
7161- /// into <c>tan(u)^k</c> for the secant, each on its principal branch. That branch is the
7162- /// one the inverse function is defined on, so the answer holds wherever the integrand
7163- /// is read through it.
7160+ /// <c>(1 + x^2)^(k/2)</c> into <c>sec(u)^k</c> for the tangent, each on its principal
7161+ /// branch. That branch is the one the inverse function is defined on, so the answer holds
7162+ /// wherever the integrand is read through it. For the secant <c>(x^2 - 1)^(k/2)</c> is
7163+ /// <c>|tan(u)|^k</c>, and on the arcsecant's range the tangent has the sign of the
7164+ /// argument, so it becomes <c>tan(u)^k</c> times that sign to the <c>k</c>, as the
7165+ /// cosecant's and the cotangent's roots carry theirs.
71647166 /// </para>
71657167 /// <para>
71667168 /// Exactly one inverse function, of the variable or of a linear <c>c x + d</c> in it,
@@ -7213,9 +7215,10 @@ private static bool TheInverseIsBelowTheBar(Entity expr, Entity inverse, Entity.
72137215 }
72147216
72157217 var u = Variable.CreateUnique(expr, "u_inv");
7216- // The sign of u, where the root's sign is that: a constant on each half of the
7217- // range, carried through the integration as a symbol and written back as the sign
7218- // of x, which it is for the cosecant and the cotangent.
7218+ // The sign the root has, where it has one: a constant on each half of the range,
7219+ // carried through the integration as a symbol and written back as the sign of the
7220+ // argument, which it is -- the sign of u for the cosecant and the cotangent, and of
7221+ // tan(u) for the secant.
72197222 var signOfU = Variable.CreateUnique(expr, "s_inv");
72207223 // x in terms of u, dx/du, the quadratic whose root goes by construction and what it
72217224 // becomes, and the way back.
@@ -7245,7 +7248,11 @@ private static bool TheInverseIsBelowTheBar(Entity expr, Entity inverse, Entity.
72457248 (xInU, dxdu, radicandBase, root) = (MathS.Cosec(u), -MathS.Cosec(u) * MathS.Cotan(u), MathS.Sqr(argument) - 1, MathS.Cotan(u) * signOfU);
72467249 break;
72477250 default:
7248- (xInU, dxdu, radicandBase, root) = (MathS.Sec(u), MathS.Sec(u) * MathS.Tan(u), MathS.Sqr(argument) - 1, MathS.Tan(u));
7251+ // arcsec has the range [0, pi/2) ∪ (pi/2, pi], where the tangent has the sign
7252+ // of the argument: `sqrt(x^2 - 1)` is `tan(u) sgn(x)`. Taken as `tan(u)`, the
7253+ // answer was right for x > 1 and its derivative the integrand's negative for
7254+ // every x < -1, where the integrand is as real: `x arcsec(x)/sqrt(x^2 - 1)`.
7255+ (xInU, dxdu, radicandBase, root) = (MathS.Sec(u), MathS.Sec(u) * MathS.Tan(u), MathS.Sqr(argument) - 1, MathS.Tan(u) * signOfU);
72497256 break;
72507257 }
72517258 if (linear)
@@ -7318,10 +7325,10 @@ node is Powf(var @base, Number.Integer power) && power.EInteger.CompareTo(EInteg
73187325 {
73197326 if (radicalsRemoved == 0 && !exponentialOfTheInverse && !powerOfTheInverse)
73207327 return null;
7321- // The cosecant and the cotangent carry the sign of u into the root, and a first
7322- // power of either beside a root is parts' -- `arccot(x)/(1 + x^2)^(3/2)` is
7323- // `x arccot(x)/sqrt(1 + x^2) + 1/sqrt(1 + x^2)` there, with no sign in it.
7324- if (inverse is Arccosecantf or Arccotanf && !exponentialOfTheInverse && !powerOfTheInverse)
7328+ // The cosecant, the cotangent and the secant carry a sign into the root, and a
7329+ // first power of any of them beside a root is parts' -- `arccot(x)/(1 + x^2)^(3/2)`
7330+ // is `x arccot(x)/sqrt(1 + x^2) + 1/sqrt(1 + x^2)` there, with no sign in it.
7331+ if (inverse is Arccosecantf or Arccotanf or Arcsecantf && !exponentialOfTheInverse && !powerOfTheInverse)
73257332 return null;
73267333 }
73277334 // And nothing else of `x` under a root, which the construction did not reach:
@@ -7374,10 +7381,11 @@ node is Powf(var @base, Number.Rational power) && power is not Number.Integer &&
73747381 if (result is null)
73757382 return null;
73767383 if (result.ContainsNode(signOfU))
7377- // The sign squared is one, and the sign itself is the sign of x.
7384+ // The sign squared is one, and the sign itself is the argument's: `arccsc(c x + d)`
7385+ // has the sign of `c x + d`, which is the sign of x only for a positive c and no d.
73787386 result = result
73797387 .Replace(node => node is Powf(var b, Number.Integer k) && b == signOfU ? (k.EInteger.IsEven ? Number.Integer.One : signOfU) : node)
7380- .Substitute(signOfU, MathS.Signum(x ));
7388+ .Substitute(signOfU, MathS.Signum(argument ));
73817389 return TrigonometryOfTheInverseInX(result.Substitute(u, inverse), inverse, argument);
73827390 }
73837391
0 commit comments