Repository navigation
Sin, Cos, Tan, Cot, Sec, Csc: precision from the condition number, as in WMA - #2054
Conversation
2632889 to
d6da960
Compare
1620c8a to
3e3ef84
Compare
|
Looks good, but please let's add type annotations for the new functions. |
d6da960 to
f7d8f32
Compare
3e3ef84 to
866f038
Compare
Part of step 6 of #2047 (MATH-227), on top of the Log PR. The relative error of x is multiplied by Abs[x f'[x] / f[x]], as in WMA: x Cot[x] for Sin, x Tan[x] for Cos, x (1 + Tan[x]^2) / Tan[x] for Tan, and so on. Where f[x] is small, the formula uses the value already computed, so the loss near a zero is measured at full precision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As asked in review: mpmath numbers in and out, as for Power. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Thanks for handling this suggestion. |
f7d8f32 to
f4b3c83
Compare
866f038 to
86dc366
Compare
|
Thanks. Added in 86dc366: each With #2051 merged, the stack is rebased onto master: #2052 is now against master, and each PR above it against the one below. |
| ("Precision[Sec[1.5`20]]", "18.6746", None), | ||
| ("Precision[Sec[0.3`20]]", "21.0324", None), | ||
| ("Precision[Csc[1.5`20]]", "20.9732", None), | ||
| ("Precision[Csc[100.`20]]", "17.7688", None), |
There was a problem hiding this comment.
Do we want to add checks for edge cases like when the numerator is 0?
In[1]:= Precision[Sin[0]]
Out[1]= Infinity
There was a problem hiding this comment.
Thanks, I added the zero cases (c568255 and d4d90e4), checked against WMA 15:
| Input | before | now | WMA 15 |
|---|---|---|---|
Precision[Sin[0]] |
Infinity |
Infinity |
Infinity |
Accuracy[Sin[N[Pi, 20]]] |
19.5029 |
19.5029 |
19.5029 |
Accuracy[Sin[020]]`` |
15. |
20. |
20. |
Precision[Cos[020]]`` |
20. |
40.301 |
40.301 |
Cot[0.], Csc[0.] |
unevaluated | ComplexInfinity |
ComplexInfinity |
Cot[020], Csc[020] |
unevaluated | ComplexInfinity |
ComplexInfinity |
The first two were already right: an exact zero stays exact, and a result that cancels to zero keeps an accuracy. They are now tested.
The other two cases were wrong:
- Inexact zero argument. It has an absolute error but no relative one, so the condition number does not apply. As in WMA, its error in the result is how much
fchanges within10^-accuracyof 0. SoSin[020]is020, andCos[020]`` is 1 with precision40.301, because `Cos` changes by only `(10^-20)^2/2`. This happens in the shared helper from Power, Sqrt: precision from the condition number, as in WMA #2052, so the inverse trigonometric and hyperbolic functions get it too; ArcSin, ArcCos, ArcTan, ArcCot, ArcSec, ArcCsc: precision from the condition number, as in WMA #2055 and Hyperbolic functions and their inverses: precision from the condition number, as in WMA #2056 have their own tests. I take the smaller change of the two sides: for a continuous function both sides agree, and `ArcCot` jumps at 0 on one side. The rule applies to an accuracy of at least 1; on a wider interval, looking at its ends would not bound `f`, so those keep the old path. - Division by zero.
CotandCscof0.or020`` stayed unevaluated. They now giveComplexInfinitythrough a rule `Cot[z_Real /; z == 0]`, as `Cot[0]` did already. In Hyperbolic functions and their inverses: precision from the condition number, as in WMA #2056, `Csch` gets the same rule; `Coth[0.]` already had one.
One case is left as it was: an inexact zero that gives a complex result, like ArcCosh[020]``. Complex results all still take the old path, and they are a separate item.
|
LGTM. Decide if you want to add the divide by 0 cases which report Infinity. Then feel free to merge. |
As asked in review: the edge cases where a value or an argument is zero. An exact zero stays exact (Precision[Sin[0]] is Infinity), and a zero result keeps its accuracy (Accuracy[Sin[N[Pi, 20]]] is 19.5029); both were already right and are now tested. Two cases were not, as in WMA: - An inexact zero argument has an absolute error but no relative one. Its error in the result is now the most that f changes within 10^-accuracy of 0: Sin[0``20] is 0``20 (was 0``15), and Cos[0``20] is 1 with precision 40.301 (was 20.), since Cos changes by only (10^-20)^2 / 2. This applies to an accuracy of at least 1; on a wider interval looking at its ends would not bound f, so those keep the old path. - Cot and Csc of an inexact zero (0. or 0``20) are ComplexInfinity, as Cot[0] already was. They stayed unevaluated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A branch cut at 0, as for ArcCot, jumps on one side: ArcCot[0``20] would otherwise get the size of the jump as its error. Where the function is continuous, the two sides agree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As suggested in review, edge cases next to poles and where the formulas divide by the value or by Sqrt[1 - x^2]. As in WMA: - Where the condition factor does not exist (a division by zero, an infinite factor, or a value of 0), the error is how much f changes within the error of its argument, as was already done for an inexact zero argument; a side where f has no real value is left out. This is what the inverse functions need at the ends of their domain (#2055, #2056), where ArcSin[1.`20] raised ZeroDivisionError. - A function with poles gives ComplexInfinity when no digit is left: Tan[N[Pi/2, 20]] and Tan[1.5707963`5] (was 0.`1.). Tan, Sec, Cot and Csc set has_poles. - A bounded function has an error no larger than its bound: Sin[1.`20*^30] is 0``0. Sin and Cos set value_bound. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As suggested in review: where the formulas divide by Sqrt[1 - x^2] or by the value. ArcSin[1.`20] raised ZeroDivisionError; with the fallback in #2054 its error is how much it changes within the error of 1, as WMA does for ArcCos[1.`20] (0``9.849) and for ArcSin just below 1. Also 0`20 (an exact 0) and 0.0`20 (a machine 0.). WMA gives ArcSin[1.`20] and ArcCsc[1.`20] precision 20.1961, which does not agree with its own ArcCos[1.`20] or ArcSin[0.9999999999999999999`20]; here they get 10.0456. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
As suggested in review. Coth and Csch set has_poles, and Tanh and Sech are bounded by 1 (see #2054). ArcCosh[1.`20] and ArcSech[1.`20] are 0``9.849, as in WMA, and the values next to 1 or to a pole are tested too, as are 0`20 (an exact 0) and 0.0`20 (a machine 0.). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
One more commit since your LGTM (78a0b39), from the edge cases you suggested on #2056:
All checked against WMA 15 and tested in |
Part of step 6 of the outline in #2047. On top of #2053 (#2052, #2051): this diff is against #2053's branch.
Sin,Cos,Tan,Cot,Sec,Cscget their precision from the condition numberAbs[x f'[x] / f[x]], as WMA does. Each function only adds itscondition_numbers(see #2052). Wheref[x]is small, the formula uses the value already computed, so the digits lost near a zero are measured at full precision.Precision[Sin[1.5`20]]20.20.973220.9732Precision[Sin[100.`20]]20.17.768817.7688Precision[Sin[3.14159265358979`20]]20.5.013195.01319Precision[Cos[1.5`20]]20.18.674618.6746Precision[Tan[100.`20]]20.17.640117.6401Precision[Sec[0.3`20]]20.21.032421.0324Zeros (added in review)
As in WMA 15. An exact zero stays exact (
Precision[Sin[0]]isInfinity), and a result that cancels to zero keeps an accuracy (Accuracy[Sin[N[Pi, 20]]]is19.5029); both were already right. Fixed here:fchanges within10^-accuracyof 0:Sin[020]is020(was015), andCos[020]is 1 with precision40.301(was20.). This is in the shared helper from Power, Sqrt: precision from the condition number, as in WMA #2052. It takes the smaller change of the two sides, so a jump at 0, asArcCothas, does not count. It applies to an accuracy of at least 1.CotandCscof an inexact zero (0.or020``) areComplexInfinity. They stayed unevaluated.Tests:
test_trig_zero.Tests
test_trig_real_valued_precisionintest/builtin/atomic/test_numbers.py, with WMA 15 values at three points per function. Full run on kimmy: doctests all pass. The pytest failures are the ones that depend on the order the tests run in; the failing files that touch numbers pass on their own.🤖 Generated with Claude Code