From fd8e76e821c212e54aeb8217e5923433c2b093aa Mon Sep 17 00:00:00 2001 From: Rafael Vuijk Date: Fri, 23 Oct 2026 13:51:09 +0000 Subject: [PATCH] Take the real root in the precise gamma function where the power takes it The precise evaluation read gamma(a, z) with its order as a decimal, which is the principal branch on the negative axis. The function itself takes the power's real root there for an exact order of odd denominator below 10, as the sampled checks' powers now do (#2092): gamma(1/3, -2) is 10.21, and the check read it as complex. Such an order is now handed to the function as it is written. Part of #2075. Co-Authored-By: Claude Opus 5.5 (1M context) Claude-Session: https://claude.ai/code/session_012sonx8iAspMiwRwokT1Ura --- Sources/AngouriMath/Numerics/PreciseEvaluation.cs | 15 ++++++++++++--- .../UnitTests/Core/IntervalEvaluationTest.cs | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/Sources/AngouriMath/Numerics/PreciseEvaluation.cs b/Sources/AngouriMath/Numerics/PreciseEvaluation.cs index 9da9732a7..81c1fd027 100644 --- a/Sources/AngouriMath/Numerics/PreciseEvaluation.cs +++ b/Sources/AngouriMath/Numerics/PreciseEvaluation.cs @@ -559,9 +559,9 @@ private PreciseComplexInterval EvaluateOtherThanArithmetic(Entity expr) return BySlope(Evaluate(argument), Number.Chi, z => Divide(Half(Add(Exp(z), Exp(Negate(z)))), z), cutEnd: EDecimal.Zero); // The upper incomplete gamma function of a constant order, through its derivative in z, // -z^(a - 1) e^(-z), jumping across the negative real axis but at a whole order a >= 1. The - // power is the principal one, as this evaluation's powers are. An order known only to its - // last place, as 1/3 is, is taken at both ends, and the value is the hull of the two: across - // an interval that narrow the function is linear in its order. + // power's branch is the one this evaluation's powers take. Any other order known only to its + // last place is taken at both ends, and the value is the hull of the two: across an interval + // that narrow the function is linear in its order. // https://github.com/asc-community/AngouriMath/issues/2075 case IncompleteGammaf(var parameter, var lowerLimit): { @@ -569,6 +569,15 @@ private PreciseComplexInterval EvaluateOtherThanArithmetic(Entity expr) if (!order.IsFinite) return undefined; var z = Evaluate(lowerLimit); + // An exact order of odd denominator below 10 is handed to the function as it is written, which then takes + // the power's real root on the negative axis, as the powers here do: as a decimal it was the principal + // branch there, and gamma(1/3, -2), which is 10.21, came out complex. + // https://github.com/asc-community/AngouriMath/issues/2089 + if (IntervalEvaluation.TheRealRootIsTaken(parameter) is not null && parameter is Number.Rational exactOrder) + { + var exactLessOne = Subtract(order, Real(PreciseInterval.Exactly(EDecimal.One))); + return BySlope(z, w => Number.IncompleteGamma(exactOrder, w), w => Negate(Multiply(Pow(w, exactLessOne), Exp(Negate(w)))), cutEnd: EDecimal.Zero); + } var entire = order.IsReal && order.Re.Low.CompareTo(order.Re.High) == 0 && order.Re.Low.IsInteger() && order.Re.Low.Sign > 0; PreciseComplexInterval AtTheOrder(EDecimal re, EDecimal im) { diff --git a/Sources/Tests/UnitTests/Core/IntervalEvaluationTest.cs b/Sources/Tests/UnitTests/Core/IntervalEvaluationTest.cs index 67d10ae61..0c5b72ad2 100644 --- a/Sources/Tests/UnitTests/Core/IntervalEvaluationTest.cs +++ b/Sources/Tests/UnitTests/Core/IntervalEvaluationTest.cs @@ -207,6 +207,7 @@ public void TheSizeOfALargeComplexValueIsFinite() [InlineData("gamma(1/2 + i, 2 - i)")] [InlineData("gamma(3/2, -2) + gamma(4, -1)")] [InlineData("gamma(1/3, 2) + gamma(2/7 + i/3, 1/2 + i)")] + [InlineData("gamma(1/3, -2) + gamma(2/5, -17/15)")] public void ThePreciseIntervalHoldsTheValue(string expression) { var expr = expression.ToEntity();