/rust/registry/src/index.crates.io-1949cf8c6b5b557f/pxfm-0.1.25/src/tangent/evalf.rs
Line | Count | Source |
1 | | /* |
2 | | * // Copyright (c) Radzivon Bartoshyk 9/2025. All rights reserved. |
3 | | * // |
4 | | * // Redistribution and use in source and binary forms, with or without modification, |
5 | | * // are permitted provided that the following conditions are met: |
6 | | * // |
7 | | * // 1. Redistributions of source code must retain the above copyright notice, this |
8 | | * // list of conditions and the following disclaimer. |
9 | | * // |
10 | | * // 2. Redistributions in binary form must reproduce the above copyright notice, |
11 | | * // this list of conditions and the following disclaimer in the documentation |
12 | | * // and/or other materials provided with the distribution. |
13 | | * // |
14 | | * // 3. Neither the name of the copyright holder nor the names of its |
15 | | * // contributors may be used to endorse or promote products derived from |
16 | | * // this software without specific prior written permission. |
17 | | * // |
18 | | * // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
19 | | * // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
20 | | * // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
21 | | * // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
22 | | * // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
23 | | * // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
24 | | * // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
25 | | * // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
26 | | * // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 | | * // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 | | */ |
29 | | use crate::polyeval::f_polyeval4; |
30 | | use crate::sin_cosf::ArgumentReducer; |
31 | | |
32 | | // Generated in SageMath: |
33 | | // print("[") |
34 | | // for k in range(64): |
35 | | // k = RealField(150)(k) * RealField(150).pi() / RealField(150)(32) |
36 | | // print(double_to_hex(k.tan()) + ",") |
37 | | // print("];") |
38 | | pub(crate) static TAN_K_PI_OVER32: [u64; 64] = [ |
39 | | 0x0000000000000000, |
40 | | 0x3fb936bb8c5b2da2, |
41 | | 0x3fc975f5e0553158, |
42 | | 0x3fd36a08355c63dc, |
43 | | 0x3fda827999fcef32, |
44 | | 0x3fe11ab7190834ec, |
45 | | 0x3fe561b82ab7f990, |
46 | | 0x3fea43002ae42850, |
47 | | 0x3ff0000000000000, |
48 | | 0x3ff37efd8d87607e, |
49 | | 0x3ff7f218e25a7461, |
50 | | 0x3ffdef13b73c1406, |
51 | | 0x4003504f333f9de6, |
52 | | 0x400a5f59e90600dd, |
53 | | 0x40141bfee2424771, |
54 | | 0x40244e6c595afdcc, |
55 | | 0xc950457bf6be49c7, |
56 | | 0xc0244e6c595afdcc, |
57 | | 0xc0141bfee2424771, |
58 | | 0xc00a5f59e90600dd, |
59 | | 0xc003504f333f9de6, |
60 | | 0xbffdef13b73c1406, |
61 | | 0xbff7f218e25a7461, |
62 | | 0xbff37efd8d87607e, |
63 | | 0xbff0000000000000, |
64 | | 0xbfea43002ae42850, |
65 | | 0xbfe561b82ab7f990, |
66 | | 0xbfe11ab7190834ec, |
67 | | 0xbfda827999fcef32, |
68 | | 0xbfd36a08355c63dc, |
69 | | 0xbfc975f5e0553158, |
70 | | 0xbfb936bb8c5b2da2, |
71 | | 0x369f77598338bfdf, |
72 | | 0x3fb936bb8c5b2da2, |
73 | | 0x3fc975f5e0553158, |
74 | | 0x3fd36a08355c63dc, |
75 | | 0x3fda827999fcef32, |
76 | | 0x3fe11ab7190834ec, |
77 | | 0x3fe561b82ab7f990, |
78 | | 0x3fea43002ae42850, |
79 | | 0x3ff0000000000000, |
80 | | 0x3ff37efd8d87607e, |
81 | | 0x3ff7f218e25a7461, |
82 | | 0x3ffdef13b73c1406, |
83 | | 0x4003504f333f9de6, |
84 | | 0x400a5f59e90600dd, |
85 | | 0x40141bfee2424771, |
86 | | 0x40244e6c595afdcc, |
87 | | 0xc935b1fa9e530d0a, |
88 | | 0xc0244e6c595afdcc, |
89 | | 0xc0141bfee2424771, |
90 | | 0xc00a5f59e90600dd, |
91 | | 0xc003504f333f9de6, |
92 | | 0xbffdef13b73c1406, |
93 | | 0xbff7f218e25a7461, |
94 | | 0xbff37efd8d87607e, |
95 | | 0xbff0000000000000, |
96 | | 0xbfea43002ae42850, |
97 | | 0xbfe561b82ab7f990, |
98 | | 0xbfe11ab7190834ec, |
99 | | 0xbfda827999fcef32, |
100 | | 0xbfd36a08355c63dc, |
101 | | 0xbfc975f5e0553158, |
102 | | 0xbfb936bb8c5b2da2, |
103 | | ]; |
104 | | |
105 | | pub(crate) struct TanfEval { |
106 | | pub(crate) tan_k: f64, |
107 | | pub(crate) tan_y: f64, |
108 | | } |
109 | | |
110 | | #[inline] |
111 | 0 | pub(crate) fn tanpif_eval(y: f64, k: i64) -> TanfEval { |
112 | 0 | let y_sqr = y * y; |
113 | | |
114 | | // After range reduction, k = round(x * 32 / pi) and y = (x * 32 / pi) - k. |
115 | | // So k is an integer and -0.5 <= y <= 0.5. |
116 | | |
117 | | // picking minus sin and cos according to quadrant |
118 | 0 | let tan_k = f64::from_bits(TAN_K_PI_OVER32[((k as u64) & 63) as usize]); |
119 | | |
120 | | // tan(x*pi/32) generated by Sollya: |
121 | | // d = [0, 0.5]; |
122 | | // f_tan = tan(y*pi/32)/y; |
123 | | // Q = fpminimax(f_tan, [|0, 2, 4, 6|], [|D...|], d, relative, floating); |
124 | | // See ./notes/tanpif.sollya |
125 | 0 | let tan_y = f_polyeval4( |
126 | 0 | y_sqr, |
127 | 0 | f64::from_bits(0x3fb921fb54442cef), |
128 | 0 | f64::from_bits(0x3f34abbce63a363e), |
129 | 0 | f64::from_bits(0x3eb466baced705e8), |
130 | 0 | f64::from_bits(0x3e346a33cde88184), |
131 | 0 | ) * y; |
132 | 0 | TanfEval { tan_y, tan_k } |
133 | 0 | } |
134 | | |
135 | | #[inline] |
136 | 0 | pub(crate) fn tanf_eval(x: f64, x_abs: u32) -> TanfEval { |
137 | 0 | let (y, k) = ArgumentReducer { x, x_abs }.reduce(); |
138 | 0 | let y_sqr = y * y; |
139 | | |
140 | | // After range reduction, k = round(x * 32 / pi) and y = (x * 32 / pi) - k. |
141 | | // So k is an integer and -0.5 <= y <= 0.5. |
142 | | |
143 | | // picking minus sin and cos according to quadrant |
144 | 0 | let tan_k = f64::from_bits(TAN_K_PI_OVER32[(k & 63) as usize]); |
145 | | |
146 | | // tan(x*pi/32) generated by Sollya: |
147 | | // d = [0, 0.5]; |
148 | | // f_tan = tan(x*pi/32)/x; |
149 | | // Q = fpminimax(f_tan, [|0, 2, 4, 6|], [|D...|], d); |
150 | | // See ./notes/tanf.sollya |
151 | 0 | let tan_y = f_polyeval4( |
152 | 0 | y_sqr, |
153 | 0 | f64::from_bits(0x3fb921fb54442cef), |
154 | 0 | f64::from_bits(0x3f34abbce63a363e), |
155 | 0 | f64::from_bits(0x3eb466baced705e8), |
156 | 0 | f64::from_bits(0x3e346a33cde88184), |
157 | 0 | ) * y; |
158 | 0 | TanfEval { tan_y, tan_k } |
159 | 0 | } |