Skip to content

Commit 86d99c5

Browse files
committed
Cache exact atan reduction anchors
1 parent 34680d1 commit 86d99c5

10 files changed

Lines changed: 167 additions & 124 deletions

File tree

benchmarks.md

Lines changed: 81 additions & 78 deletions
Large diffs are not rendered by default.

dispatch_trace.md

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ This table groups raw trace labels into Yap-aligned diagnostic buckets so scalar
4343
| `computable/inverse_trig_adversarial/asin_near_one` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 7 | 2 | 1 |
4444
| `computable/inverse_trig_adversarial/asin_tiny` | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4545
| `computable/inverse_trig_adversarial/asin_zero` | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
46-
| `computable/inverse_trig_adversarial/atan_generated_783_412` | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 3 | 2 | 2 | 0 | 0 | 0 | 2 | 0 | 1 | 1 | 1 |
47-
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | 10 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 | 0 | 0 | 0 | 2 | 0 | 1 | 1 | 1 |
46+
| `computable/inverse_trig_adversarial/atan_generated_783_412` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 3 | 2 | 2 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
47+
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | 8 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
4848
| `computable/inverse_trig_adversarial/atan_huge` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 3 | 2 | 2 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
4949
| `computable/inverse_trig_adversarial/atan_large` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 3 | 2 | 2 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
5050
| `computable/inverse_trig_adversarial/atan_mid` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 3 | 2 | 2 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 1 |
@@ -53,8 +53,8 @@ This table groups raw trace labels into Yap-aligned diagnostic buckets so scalar
5353
| `computable/ln_nonsmooth_rational` | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 2 |
5454
| `computable/ln_smooth_rational` | 26 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 11 | 3 | 3 | 0 | 0 | 0 | 0 | 0 | 17 | 1 | 1 |
5555
| `computable/ln_square_plus_one_promoted_generated_677_222` | 7 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 5 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 6 | 2 | 2 |
56-
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 |
57-
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | 9 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 | 0 | 0 | 0 | 2 | 0 | 4 | 2 | 2 |
56+
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 5 | 2 | 2 | 0 | 0 | 0 | 3 | 0 | 5 | 3 | 2 |
57+
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | 12 | 0 | 0 | 0 | 0 | 0 | 0 | 2 | 0 | 5 | 2 | 2 | 0 | 0 | 0 | 3 | 0 | 5 | 3 | 2 |
5858
| `computable/promoted_library_slow/cos_generated_16610_pos_7_4_19` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 3 | 1 | 2 |
5959
| `computable/promoted_library_slow/cos_generated_9365_pos_7_14_139` | 6 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 4 | 2 | 2 |
6060
| `computable/promoted_library_slow/ln_generated_10732_pos_6_6_137` | 7 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 5 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 8 | 2 | 3 |
@@ -325,20 +325,18 @@ This table groups raw trace labels into Yap-aligned diagnostic buckets so scalar
325325
| `computable/inverse_trig_adversarial/asin_zero` | `computable` | `constructor` | `zero` | 1 |
326326
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `atan` | `exact-rational-deferred` | 1 |
327327
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `atan-rational-deferred` | 1 |
328-
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `cached-atan-inv2` | 1 |
329-
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `cached-pi` | 1 |
330-
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `shared-constant-wrapper` | 2 |
328+
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `cached-atan2` | 1 |
329+
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable` | `constructor` | `shared-constant-wrapper` | 1 |
331330
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable_approx` | `atan` | `exact-rational-reduction` | 1 |
332-
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable_approx` | `atan` | `two-anchor-half-pi` | 1 |
331+
| `computable/inverse_trig_adversarial/atan_generated_783_412` | `computable_approx` | `atan` | `two-anchor-shared` | 1 |
333332
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `atan` | `exact-rational-deferred` | 1 |
334333
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `atan` | `known-negative-symmetry` | 1 |
335334
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `atan-rational-deferred` | 1 |
336-
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `cached-atan-inv5` | 1 |
337-
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `cached-pi` | 1 |
335+
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `cached-atan-three-halves` | 1 |
338336
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `rational-node` | 1 |
339-
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `shared-constant-wrapper` | 2 |
337+
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable` | `constructor` | `shared-constant-wrapper` | 1 |
340338
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable_approx` | `atan` | `exact-rational-reduction` | 1 |
341-
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable_approx` | `atan` | `three-halves-anchor` | 1 |
339+
| `computable/inverse_trig_adversarial/atan_generated_minus_32_19` | `computable_approx` | `atan` | `three-halves-anchor-shared` | 1 |
342340
| `computable/inverse_trig_adversarial/atan_huge` | `computable` | `atan` | `exact-rational-deferred` | 1 |
343341
| `computable/inverse_trig_adversarial/atan_huge` | `computable` | `constructor` | `atan-rational-deferred` | 1 |
344342
| `computable/inverse_trig_adversarial/atan_huge` | `computable` | `constructor` | `cached-pi` | 1 |
@@ -380,19 +378,21 @@ This table groups raw trace labels into Yap-aligned diagnostic buckets so scalar
380378
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `atan` | `exact-rational-deferred` | 1 |
381379
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `atan-rational-deferred` | 1 |
382380
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `cached-atan-inv2` | 1 |
381+
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `cached-atan2` | 1 |
383382
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `cached-pi` | 1 |
384-
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `rational-node` | 1 |
385-
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `shared-constant-wrapper` | 2 |
383+
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `rational-node` | 2 |
384+
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable` | `constructor` | `shared-constant-wrapper` | 3 |
386385
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable_approx` | `atan` | `exact-rational-reduction` | 1 |
387-
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable_approx` | `atan` | `two-anchor-half-pi` | 1 |
386+
| `computable/promoted_library_slow/atan_generated_10704_pos_1_371_412` | `computable_approx` | `atan` | `two-anchor-shared` | 1 |
388387
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `atan` | `exact-rational-deferred` | 1 |
389388
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `atan-rational-deferred` | 1 |
390389
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `cached-atan-inv5` | 1 |
390+
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `cached-atan-three-halves` | 1 |
391391
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `cached-pi` | 1 |
392-
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `rational-node` | 1 |
393-
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `shared-constant-wrapper` | 2 |
392+
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `rational-node` | 2 |
393+
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable` | `constructor` | `shared-constant-wrapper` | 3 |
394394
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable_approx` | `atan` | `exact-rational-reduction` | 1 |
395-
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable_approx` | `atan` | `three-halves-anchor` | 1 |
395+
| `computable/promoted_library_slow/atan_generated_11034_pos_1_367_518` | `computable_approx` | `atan` | `three-halves-anchor-shared` | 1 |
396396
| `computable/promoted_library_slow/cos_generated_16610_pos_7_4_19` | `computable` | `constructor` | `cached-pi` | 1 |
397397
| `computable/promoted_library_slow/cos_generated_16610_pos_7_4_19` | `computable` | `constructor` | `cos-large-rational-deferred` | 1 |
398398
| `computable/promoted_library_slow/cos_generated_16610_pos_7_4_19` | `computable` | `constructor` | `rational-node` | 1 |

promoted_slow_offenders.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,4 +101,4 @@ generated_tan_p96 generated[9396] -4 128/155 18279 tan_generated_9396_neg_4_128_
101101
generated_sin_p96 generated[11884] 4 14/31 18269 sin_generated_11884_4_14_31_p96
102102
generated_tan_p96 generated[14421] 5 25/47 18209 tan_generated_14421_5_25_47_p96
103103
generated_sin_p96 generated[13219] 4 31/51 18188 sin_generated_13219_4_31_51_p96
104-
generated_cos_p96 generated[9950] -5 1/5 18169 cos_generated_9950_neg_5_1_5_p96
104+
generated_atan_p96 generated[2739] -1 235/241 18159 atan_generated_2739_neg_1_235_241_p96

slow_performers.txt

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -272,18 +272,18 @@ Latest run sampled 20000 deterministic cases. The table below intentionally merg
272272
| 262 | 16.009 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[11242] 77/754` |
273273
| 263 | 16.009 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[16747] 143/347` |
274274
| 264 | 16.009 us | `computable` | `generated_tan_p96` | `generated[2571] 5 29/46` |
275-
| 265 | 15.979 us | `computable` | `generated_atan_p96` | `generated[13284] -1 21/25` |
276-
| 266 | 15.979 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[17482] -35/171` |
277-
| 267 | 15.979 us | `computable` | `generated_tan_p96` | `generated[14781] 7 49/72` |
278-
| 268 | 15.969 us | `computable` | `generated_atan_p96` | `generated[10674] 1 99/493` |
279-
| 269 | 15.959 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9502] 2 59/467` |
280-
| 270 | 15.959 us | `computable` | `generated_tan_p96` | `generated[17526] -6 133/138` |
281-
| 271 | 15.949 us | `real` | `generated_ln_abs_plus_one_build` | `generated[1049] -6 2/5` |
282-
| 272 | 15.939 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9127] -395/981` |
283-
| 273 | 15.919 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9517] 89/925` |
284-
| 274 | 15.899 us | `computable` | `generated_tan_p96` | `generated[7341] -3 89/110` |
285-
| 275 | 15.889 us | `computable` | `generated_atan_p96` | `generated[15609] -1 86/157` |
286-
| 276 | 15.879 us | `computable` | `generated_tan_p96` | `generated[1071] -3 177/200` |
275+
| 265 | 15.999 us | `computable` | `generated_tan_p96` | `generated[1071] -3 177/200` |
276+
| 266 | 15.979 us | `computable` | `generated_atan_p96` | `generated[13284] -1 21/25` |
277+
| 267 | 15.979 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[17482] -35/171` |
278+
| 268 | 15.979 us | `computable` | `generated_tan_p96` | `generated[14781] 7 49/72` |
279+
| 269 | 15.969 us | `computable` | `generated_atan_p96` | `generated[10674] 1 99/493` |
280+
| 270 | 15.959 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9502] 2 59/467` |
281+
| 271 | 15.959 us | `computable` | `generated_tan_p96` | `generated[17526] -6 133/138` |
282+
| 272 | 15.949 us | `real` | `generated_ln_abs_plus_one_build` | `generated[1049] -6 2/5` |
283+
| 273 | 15.939 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9127] -395/981` |
284+
| 274 | 15.919 us | `computable` | `generated_ln_abs_plus_one_p96` | `generated[9517] 89/925` |
285+
| 275 | 15.899 us | `computable` | `generated_tan_p96` | `generated[7341] -3 89/110` |
286+
| 276 | 15.889 us | `computable` | `generated_atan_p96` | `generated[15609] -1 86/157` |
287287
| 277 | 15.878 us | `computable` | `generated_atan_p96` | `generated[13929] 1 147/179` |
288288
| 278 | 15.849 us | `computable` | `generated_atan_p96` | `generated[6939] -1 90/109` |
289289
| 279 | 15.849 us | `computable` | `generated_atan_p96` | `generated[714] -1 385/466` |

src/computable/approximation/constants.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,27 @@ fn asinh1_constant(signal: &Option<Signal>, p: Precision) -> BigInt {
6868
.approx_signal(signal, p)
6969
}
7070

71+
fn atan2_constant(signal: &Option<Signal>, p: Precision) -> BigInt {
72+
// atan(2) = pi/2 - atan(1/2). The exact-rational atan reduction uses this
73+
// anchor for values near 2; a shared node lets promoted adversarial cases
74+
// reuse the combined approximation instead of assembling pi and atan(1/2)
75+
// independently at every precision.
76+
Computable::pi()
77+
.multiply(Computable::rational(Rational::fraction(1, 2).unwrap()))
78+
.add(Computable::atan_inv2_constant().negate())
79+
.approx_signal(signal, p)
80+
}
81+
82+
fn atan_three_halves_constant(signal: &Option<Signal>, p: Precision) -> BigInt {
83+
// atan(3/2) = pi/4 + atan(1/5). This is the second midpoint anchor for
84+
// exact-rational atan; caching the assembled constant keeps the residual
85+
// series as the only per-call work after warm-up.
86+
Computable::pi()
87+
.multiply(Computable::rational(Rational::fraction(1, 4).unwrap()))
88+
.add(Computable::atan_inv5_constant())
89+
.approx_signal(signal, p)
90+
}
91+
7192
fn e_terms_for_precision(p: Precision) -> u32 {
7293
// Choose enough 1/k! terms so the binary-split tail is below the requested
7394
// bit precision. Positive precisions need only a tiny constant amount.
@@ -129,4 +150,3 @@ fn e(p: Precision) -> BigInt {
129150
let (tail_p, tail_q) = e_binary_split(1, terms + 1);
130151
rounded_ratio(tail_q.clone() + tail_p, tail_q, p)
131152
}
132-

src/computable/approximation/dispatch.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
impl SharedConstant {
2-
pub(super) const COUNT: usize = 16;
2+
pub(super) const COUNT: usize = 18;
33

44
pub(super) fn cache_index(self) -> usize {
55
match self {
@@ -19,6 +19,8 @@ impl SharedConstant {
1919
Self::Asinh1 => 13,
2020
Self::AtanInv2 => 14,
2121
Self::AtanInv5 => 15,
22+
Self::Atan2 => 16,
23+
Self::AtanThreeHalves => 17,
2224
}
2325
}
2426
}
@@ -119,6 +121,8 @@ impl SharedConstant {
119121
Self::Asinh1 => asinh1_constant(signal, p),
120122
Self::AtanInv2 => atan(signal, &BigInt::from(2_u8), p),
121123
Self::AtanInv5 => atan(signal, &BigInt::from(5_u8), p),
124+
Self::Atan2 => atan2_constant(signal, p),
125+
Self::AtanThreeHalves => atan_three_halves_constant(signal, p),
122126
}
123127
}
124128
}

src/computable/approximation/inverse_trig.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -217,22 +217,18 @@ fn atan_rational(signal: &Option<Signal>, r: &Rational, p: Precision) -> BigInt
217217
let extra = 3;
218218
let work_precision = p - extra;
219219
if r >= SEVEN_FOURTHS_RATIONAL.deref() && r <= TWO_RATIONAL.deref() {
220-
crate::trace_dispatch!("computable_approx", "atan", "two-anchor-half-pi");
221-
let half_pi = Computable::pi().approx_signal(signal, work_precision + 1);
222-
let anchor_tail =
223-
Computable::atan_inv2_constant().approx_signal(signal, work_precision + 1);
220+
crate::trace_dispatch!("computable_approx", "atan", "two-anchor-shared");
221+
let anchor = Computable::atan2_constant().approx_signal(signal, work_precision);
224222
let residual = atan_anchor_residual(r, 2, 1);
225223
let reduced = atan_rational_small(signal, &residual, work_precision);
226-
return scale(half_pi - anchor_tail + reduced, -extra);
224+
return scale(anchor + reduced, -extra);
227225
}
228226
if r >= FOUR_THIRDS_RATIONAL.deref() && r <= TWO_RATIONAL.deref() {
229-
crate::trace_dispatch!("computable_approx", "atan", "three-halves-anchor");
230-
let quarter_pi = Computable::pi().approx_signal(signal, work_precision + 2);
231-
let anchor_tail =
232-
Computable::atan_inv5_constant().approx_signal(signal, work_precision + 2);
227+
crate::trace_dispatch!("computable_approx", "atan", "three-halves-anchor-shared");
228+
let anchor = Computable::atan_three_halves_constant().approx_signal(signal, work_precision);
233229
let residual = atan_anchor_residual(r, 3, 2);
234230
let reduced = atan_rational_small(signal, &residual, work_precision);
235-
return scale(quarter_pi + anchor_tail + scale(reduced, 2), -(extra + 2));
231+
return scale(anchor + reduced, -extra);
236232
}
237233
if r <= TWO_RATIONAL.deref() {
238234
crate::trace_dispatch!("computable_approx", "atan", "unit-anchor-pi-quarter");
@@ -370,4 +366,3 @@ fn acos_positive_rational(signal: &Option<Signal>, r: &Rational, p: Precision) -
370366
fn acos_negative_rational(signal: &Option<Signal>, r: &Rational, p: Precision) -> BigInt {
371367
Computable::pi().approx_signal(signal, p) - acos_positive_rational(signal, r, p)
372368
}
373-

src/computable/approximation/representation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,6 @@ pub(super) enum SharedConstant {
177177
Asinh1,
178178
AtanInv2,
179179
AtanInv5,
180+
Atan2,
181+
AtanThreeHalves,
180182
}

src/computable/node/bounds.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,13 +295,15 @@ impl SharedConstant {
295295
SharedConstant::Tau => Some(2),
296296
SharedConstant::Ln2 => Some(-1),
297297
SharedConstant::Asinh1 => Some(-1),
298+
SharedConstant::AtanThreeHalves => Some(-1),
298299
SharedConstant::Ln3
299300
| SharedConstant::Ln5
300301
| SharedConstant::Ln6
301302
| SharedConstant::Ln7
302303
| SharedConstant::Sqrt2
303304
| SharedConstant::Sqrt3
304-
| SharedConstant::Acosh2 => Some(0),
305+
| SharedConstant::Acosh2
306+
| SharedConstant::Atan2 => Some(0),
305307
};
306308
BoundInfo::with_sign(Sign::Plus, msd)
307309
}
@@ -335,6 +337,14 @@ impl SharedConstant {
335337
Rational::fraction(46, 100).unwrap(),
336338
Rational::fraction(47, 100).unwrap(),
337339
),
340+
Self::Atan2 => (
341+
Rational::fraction(110, 100).unwrap(),
342+
Rational::fraction(111, 100).unwrap(),
343+
),
344+
Self::AtanThreeHalves => (
345+
Rational::fraction(98, 100).unwrap(),
346+
Rational::fraction(99, 100).unwrap(),
347+
),
338348
Self::Ln2 => (
339349
Rational::fraction(69, 100).unwrap(),
340350
Rational::fraction(7, 10).unwrap(),
@@ -421,4 +431,3 @@ thread_local! {
421431
static SHARED_CONSTANT_CACHES: RefCell<Vec<Cache>> =
422432
RefCell::new(vec![Cache::Invalid; SharedConstant::COUNT]);
423433
}
424-

src/computable/node/primitive_constructors.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,16 @@ impl Computable {
311311
Self::shared_constant(SharedConstant::AtanInv2)
312312
}
313313

314+
pub(crate) fn atan2_constant() -> Computable {
315+
crate::trace_dispatch!("computable", "constructor", "cached-atan2");
316+
Self::shared_constant(SharedConstant::Atan2)
317+
}
318+
319+
pub(crate) fn atan_three_halves_constant() -> Computable {
320+
crate::trace_dispatch!("computable", "constructor", "cached-atan-three-halves");
321+
Self::shared_constant(SharedConstant::AtanThreeHalves)
322+
}
323+
314324
/// Approximate τ, the ratio of a circle's circumference to its radius.
315325
pub fn tau() -> Computable {
316326
crate::trace_dispatch!("computable", "constructor", "cached-tau");

0 commit comments

Comments
 (0)