CMS 3D CMS Logo

approx_asin.h
Go to the documentation of this file.
1 #ifndef DataFormatsMathapprox_asin_h
2 #define DataFormatsMathapprox_asin_h
3 
4 #include <cmath>
5 template <int DEGREE>
6 constexpr float approx_asin_P(float z);
7 
8 // degree = 3 => absolute accuracy is 8 bits
9 template <>
10 constexpr float approx_asin_P<3>(float z) {
11  return 1.f + z * 0.2133004963397979736328125f;
12 }
13 // degree = 5 => absolute accuracy is 11 bits
14 template <>
15 constexpr float approx_asin_P<5>(float z) {
16  return 1.f + z * (0.154711246490478515625f + z * 0.1322681009769439697265625f);
17 }
18 // degree = 7 => absolute accuracy is 15 bits
19 template <>
20 constexpr float approx_asin_P<7>(float z) {
21  return 1.f + z * (0.169519245624542236328125f + z * (4.9031913280487060546875e-2f + z * 0.10941398143768310546875));
22 }
23 // degree = 9 => absolute accuracy is 18 bits
24 template <>
25 constexpr float approx_asin_P<9>(float z) {
26  return 1.f + z * (0.166020572185516357421875f +
27  z * (8.44048559665679931640625e-2f +
28  z * (1.11602735705673694610595703125e-3f + z * 0.103476583957672119140625f)));
29 }
30 // degree = 11 => absolute accuracy is 21 bits
31 template <>
32 constexpr float approx_asin_P<11>(float z) {
33  return 1.f + z * (0.1668075025081634521484375f +
34  z * (7.20207393169403076171875e-2f +
35  z * (6.607978045940399169921875e-2f +
36  z * ((-3.6048568785190582275390625e-2f) + z * 0.10574872791767120361328125f))));
37 }
38 
39 /*
40  // degree = 3 => absolute accuracy is 8 bits
41 template<> constexpr float approx_asin_P< 3 >(float z){
42  return 1.f + z * 0.2114248573780059814453125f;
43 }
44  // degree = 5 => absolute accuracy is 12 bits
45 template<> constexpr float approx_asin_P< 5 >(float z){
46  return 1.f + z * (0.1556626856327056884765625f + z * 0.1295671761035919189453125f);
47 }
48  // degree = 7 => absolute accuracy is 15 bits
49 template<> constexpr float approx_asin_P< 7 >(float z){
50  return 1.f + z * (0.1691854894161224365234375f + z * (5.1305986940860748291015625e-2f + z * 0.1058919131755828857421875f));
51 }
52  // degree = 9 => absolute accuracy is 18 bits
53 template<> constexpr float approx_asin_P< 9 >(float z){
54  return 1.f + z * (0.166119158267974853515625f + z * (8.322779834270477294921875e-2f + z * (5.28236292302608489990234375e-3f + z * 9.89462435245513916015625e-2f)));
55 }
56  // degree = 11 => absolute accuracy is 21 bits
57 template<> constexpr float approx_asin_P< 11 >(float z){
58  return 1.f + z * (0.1667812168598175048828125f + z * (7.249967753887176513671875e-2f + z * (6.321799755096435546875e-2f + z * ((-2.913488447666168212890625e-2f) + z * 9.9913299083709716796875e-2f))));
59 }
60 */
61 
62 // valid for |x|<0.71
63 template <int DEGREE>
64 constexpr float unsafe_asin07(float x) {
65  auto z = x * x;
66  return x * approx_asin_P<DEGREE>(z);
67 }
68 
69 template <int DEGREE>
70 constexpr float unsafe_acos07(float x) {
71  constexpr float pihalf = M_PI / 2;
72  return pihalf - unsafe_asin07<DEGREE>(x);
73 }
74 
75 // for |x|> 0.71 use slower
76 template <int DEGREE>
77 constexpr float unsafe_acos71(float x) {
78  constexpr float pi = M_PI;
79  auto z = 1.f - x * x;
80  z = std::sqrt(z) * approx_asin_P<DEGREE>(z);
81  return x > 0 ? z : pi - z;
82 }
83 
84 template <int DEGREE>
85 constexpr float unsafe_asin71(float x) {
86  constexpr float pihalf = M_PI / 2;
87  return pihalf - unsafe_acos71<DEGREE>(x);
88 }
89 
90 template <int DEGREE>
91 constexpr float unsafe_asin(float x) {
92  return (std::abs(x) < 0.71f) ? unsafe_asin07<DEGREE>(x) : unsafe_asin71<DEGREE>(x);
93 }
94 
95 template <int DEGREE>
96 constexpr float unsafe_acos(float x) {
97  return (std::abs(x) < 0.71f) ? unsafe_acos07<DEGREE>(x) : unsafe_acos71<DEGREE>(x);
98 }
99 
100 #endif
constexpr float approx_asin_P(float z)
constexpr float approx_asin_P< 11 >(float z)
Definition: approx_asin.h:32
constexpr float unsafe_asin71(float x)
Definition: approx_asin.h:85
constexpr float approx_asin_P< 7 >(float z)
Definition: approx_asin.h:20
constexpr float unsafe_asin07(float x)
Definition: approx_asin.h:64
constexpr float unsafe_asin(float x)
Definition: approx_asin.h:91
float float float z
constexpr float unsafe_acos(float x)
Definition: approx_asin.h:96
const Double_t pi
constexpr float approx_asin_P< 5 >(float z)
Definition: approx_asin.h:15
T sqrt(T t)
Definition: SSEVec.h:19
constexpr float approx_asin_P< 3 >(float z)
Definition: approx_asin.h:10
constexpr float unsafe_acos71(float x)
Definition: approx_asin.h:77
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double f[11][100]
#define M_PI
constexpr float approx_asin_P< 9 >(float z)
Definition: approx_asin.h:25
constexpr float unsafe_acos07(float x)
Definition: approx_asin.h:70
float x