11use core:: f32:: consts:: * ;
22use core:: intrinsics:: * ;
33
4+ /// Defines fast approximate functions for 32-bit floats. Outputs may differ based on platform, so
5+ /// nothing should be checked for equality. This is part of the reason why functions in here are
6+ /// marked as unsafe, because the behavior of these small floating point differences is undefined.
7+ ///
8+ ///
9+ /// Coefficient constants for the `sin` and `cos` functions were derived from here:
10+ /// https://publik-void.github.io/sin-cos-approximations/#_cos_abs_error_minimized_degree_2
11+ ///
12+ ///
13+ /// Other coefficients were generated from this Julia function:
14+ /// https://gist.github.com/burgerindividual/5f0ee20232f78c356df5767713ffad57
415pub trait FastApproxFloat {
16+ /// # Inputs
17+ /// Precision can set between 0 and 3, with 0 being the fastest and least
18+ /// precise, and 3 being the slowest and most precise.
19+ ///
520 /// # Safety
621 /// Inputs valid between [-2^23, 2^23]. The output of this function can differ based on
722 /// machine characteristics, and should not be used with equality testing.
23+ ///
24+ /// # Notes
25+ /// As the inputs get further from 0, the accuracy gets continuously worse
26+ /// due to nature of the fast range reduction.
827 unsafe fn sin_fast_approx < const PRECISION : usize > ( self ) -> Self ;
28+ /// # Inputs
29+ /// Precision can set between 0 and 3, with 0 being the fastest and least
30+ /// precise, and 3 being the slowest and most precise.
31+ ///
932 /// # Safety
1033 /// Inputs valid between [-2^23, 2^23]. The output of this function can differ based on
1134 /// machine characteristics, and should not be used with equality testing.
35+ ///
36+ /// # Notes
37+ /// As the inputs get further from 0, the accuracy gets continuously worse
38+ /// due to nature of the fast range reduction.
1239 unsafe fn cos_fast_approx < const PRECISION : usize > ( self ) -> Self ;
1340
41+ /// # Inputs
42+ /// Precision can set between 0 and 3, with 0 being the fastest and least
43+ /// precise, and 3 being the slowest and most precise.
44+ ///
1445 /// # Safety
15- /// Inputs valid between [-1 /2, 1 /2]. The output of this function can differ based on
46+ /// Inputs valid between [-PI /2, PI /2]. The output of this function can differ based on
1647 /// machine characteristics, and should not be used with equality testing.
1748 unsafe fn sin_ranged_fast_approx < const PRECISION : usize > ( self ) -> Self ;
49+ /// # Inputs
50+ /// Precision can set between 0 and 3, with 0 being the fastest and least
51+ /// precise, and 3 being the slowest and most precise.
52+ ///
1853 /// # Safety
19- /// Inputs valid between [-1 /2, 1 /2]. The output of this function can differ based on
54+ /// Inputs valid between [-PI /2, PI /2]. The output of this function can differ based on
2055 /// machine characteristics, and should not be used with equality testing.
2156 unsafe fn cos_ranged_fast_approx < const PRECISION : usize > ( self ) -> Self ;
2257
@@ -30,32 +65,6 @@ pub trait FastApproxFloat {
3065 unsafe fn log_fast_approx_const_base < const PRECISION : usize > ( self , base : Self ) -> Self ;
3166}
3267
33- /// # Inputs
34- /// Precision can set between 0 and 3, with 0 being the fastest and least
35- /// precise, and 3 being the slowest and most precise.<br>
36- /// #### Max Absolute Error Chart (from [-PI/2, PI/2]):
37- ///
38- /// | PRECISION | ERROR |
39- /// | :-------- | :----- |
40- /// | 0 | 2.9e-2 |
41- /// | 1 | 6.0e-4 |
42- /// | 2 | 6.9e-6 |
43- /// | 3 | 2.7e-7 |
44- ///
45- /// If COS is set to true, the period is offset by PI/2.
46- ///
47- /// # Safety
48- /// Inputs valid between [-2^23, 2^23]. The output of this function can differ based on
49- /// machine characteristics, and should not be used with equality testing.
50- ///
51- /// # Notes
52- /// As the inputs get further from 0, the accuracy gets continuously worse
53- /// due to nature of the fast range reduction.
54- ///
55- /// This function should auto vectorize under LLVM with -Copt-level=3.
56- ///
57- /// The coefficient constants were derived from the constants defined here:
58- /// https://publik-void.github.io/sin-cos-approximations/#_cos_abs_error_minimized_degree_2
5968#[ inline( always) ]
6069pub ( crate ) unsafe fn sin_fast_approx < const PRECISION : usize , const COS : bool > ( x : f32 ) -> f32 {
6170 let coeffs: & [ f32 ] = match PRECISION {
0 commit comments