GteTanEstimate.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
11 #include <cmath>
12 
13 // Minimax polynomial approximations to tan(x). The polynomial p(x) of
14 // degree D has only odd-power terms, is required to have linear term x,
15 // and p(pi/4) = tan(pi/4) = 1. It minimizes the quantity
16 // maximum{|tan(x) - p(x)| : x in [-pi/4,pi/4]} over all polynomials of
17 // degree D subject to the constraints mentioned.
18 
19 namespace gte
20 {
21 
22 template <typename Real>
24 {
25 public:
26  // The input constraint is x in [-pi/4,pi/4]. For example,
27  // float x; // in [-pi/4,pi/4]
28  // float result = TanEstimate<float>::Degree<3>(x);
29  template <int D>
30  inline static Real Degree(Real x);
31 
32  // The input x can be any real number. Range reduction is used to
33  // generate a value y in [-pi/2,pi/2]. If |y| <= pi/4, then the
34  // polynomial is evaluated. If y in (pi/4,pi/2), set z = y - pi/4
35  // and use the identity
36  // tan(y) = tan(z + pi/4) = [1 + tan(z)]/[1 - tan(z)]
37  // Be careful when evaluating at y nearly pi/2, because tan(y)
38  // becomes infinite. For example,
39  // float x; // x any real number
40  // float result = TanEstimate<float>::DegreeRR<3>(x);
41  template <int D>
42  inline static Real DegreeRR(Real x);
43 
44 private:
45  // Metaprogramming and private implementation to allow specialization of
46  // a template member function.
47  template <int D> struct degree {};
48  inline static Real Evaluate(degree<3>, Real x);
49  inline static Real Evaluate(degree<5>, Real x);
50  inline static Real Evaluate(degree<7>, Real x);
51  inline static Real Evaluate(degree<9>, Real x);
52  inline static Real Evaluate(degree<11>, Real x);
53  inline static Real Evaluate(degree<13>, Real x);
54 
55  // Support for range reduction.
56  inline static void Reduce(Real x, Real& y);
57 };
58 
59 
60 template <typename Real>
61 template <int D>
62 inline Real TanEstimate<Real>::Degree(Real x)
63 {
64  return Evaluate(degree<D>(), x);
65 }
66 
67 template <typename Real>
68 template <int D>
69 inline Real TanEstimate<Real>::DegreeRR(Real x)
70 {
71  Real y;
72  Reduce(x, y);
73  if (std::abs(y) <= (Real)GTE_C_QUARTER_PI)
74  {
75  return Degree<D>(y);
76  }
77  else if (y > (Real)GTE_C_QUARTER_PI)
78  {
79  Real poly = Degree<D>(y - (Real)GTE_C_QUARTER_PI);
80  return ((Real)1 + poly) / ((Real)1 - poly);
81  }
82  else
83  {
84  Real poly = Degree<D>(y + (Real)GTE_C_QUARTER_PI);
85  return -((Real)1 - poly) / ((Real)1 + poly);
86  }
87 }
88 
89 template <typename Real>
91 {
92  Real xsqr = x * x;
93  Real poly;
94  poly = (Real)GTE_C_TAN_DEG3_C1;
95  poly = (Real)GTE_C_TAN_DEG3_C0 + poly * xsqr;
96  poly = poly * x;
97  return poly;
98 }
99 
100 template <typename Real>
102 {
103  Real xsqr = x * x;
104  Real poly;
105  poly = (Real)GTE_C_TAN_DEG5_C2;
106  poly = (Real)GTE_C_TAN_DEG5_C1 + poly * xsqr;
107  poly = (Real)GTE_C_TAN_DEG5_C0 + poly * xsqr;
108  poly = poly * x;
109  return poly;
110 }
111 
112 template <typename Real>
114 {
115  Real xsqr = x * x;
116  Real poly;
117  poly = (Real)GTE_C_TAN_DEG7_C3;
118  poly = (Real)GTE_C_TAN_DEG7_C2 + poly * xsqr;
119  poly = (Real)GTE_C_TAN_DEG7_C1 + poly * xsqr;
120  poly = (Real)GTE_C_TAN_DEG7_C0 + poly * xsqr;
121  poly = poly * x;
122  return poly;
123 }
124 
125 template <typename Real>
127 {
128  Real xsqr = x * x;
129  Real poly;
130  poly = (Real)GTE_C_TAN_DEG9_C4;
131  poly = (Real)GTE_C_TAN_DEG9_C3 + poly * xsqr;
132  poly = (Real)GTE_C_TAN_DEG9_C2 + poly * xsqr;
133  poly = (Real)GTE_C_TAN_DEG9_C1 + poly * xsqr;
134  poly = (Real)GTE_C_TAN_DEG9_C0 + poly * xsqr;
135  poly = poly * x;
136  return poly;
137 }
138 
139 template <typename Real>
141 {
142  Real xsqr = x * x;
143  Real poly;
144  poly = (Real)GTE_C_TAN_DEG11_C5;
145  poly = (Real)GTE_C_TAN_DEG11_C4 + poly * xsqr;
146  poly = (Real)GTE_C_TAN_DEG11_C3 + poly * xsqr;
147  poly = (Real)GTE_C_TAN_DEG11_C2 + poly * xsqr;
148  poly = (Real)GTE_C_TAN_DEG11_C1 + poly * xsqr;
149  poly = (Real)GTE_C_TAN_DEG11_C0 + poly * xsqr;
150  poly = poly * x;
151  return poly;
152 }
153 
154 template <typename Real>
156 {
157  Real xsqr = x * x;
158  Real poly;
159  poly = (Real)GTE_C_TAN_DEG13_C6;
160  poly = (Real)GTE_C_TAN_DEG13_C5 + poly * xsqr;
161  poly = (Real)GTE_C_TAN_DEG13_C4 + poly * xsqr;
162  poly = (Real)GTE_C_TAN_DEG13_C3 + poly * xsqr;
163  poly = (Real)GTE_C_TAN_DEG13_C2 + poly * xsqr;
164  poly = (Real)GTE_C_TAN_DEG13_C1 + poly * xsqr;
165  poly = (Real)GTE_C_TAN_DEG13_C0 + poly * xsqr;
166  poly = poly * x;
167  return poly;
168 }
169 
170 template <typename Real>
171 inline void TanEstimate<Real>::Reduce(Real x, Real& y)
172 {
173  // Map x to y in [-pi,pi], x = pi*quotient + remainder.
174  y = fmod(x, (Real)GTE_C_PI);
175 
176  // Map y to [-pi/2,pi/2] with tan(y) = tan(x).
177  if (y > (Real)GTE_C_HALF_PI)
178  {
179  y -= (Real)GTE_C_PI;
180  }
181  else if (y < (Real)-GTE_C_HALF_PI)
182  {
183  y += (Real)GTE_C_PI;
184  }
185 }
186 
187 
188 }
#define GTE_C_TAN_DEG7_C2
Definition: GteConstants.h:238
#define GTE_C_TAN_DEG5_C1
Definition: GteConstants.h:232
#define GTE_C_TAN_DEG9_C4
Definition: GteConstants.h:246
#define GTE_C_TAN_DEG11_C0
Definition: GteConstants.h:249
#define GTE_C_TAN_DEG9_C3
Definition: GteConstants.h:245
static Real Evaluate(degree< 3 >, Real x)
gte::BSNumber< UIntegerType > abs(gte::BSNumber< UIntegerType > const &number)
Definition: GteBSNumber.h:966
static void Reduce(Real x, Real &y)
#define GTE_C_QUARTER_PI
Definition: GteConstants.h:19
#define GTE_C_TAN_DEG9_C1
Definition: GteConstants.h:243
#define GTE_C_TAN_DEG11_C4
Definition: GteConstants.h:253
#define GTE_C_TAN_DEG13_C0
Definition: GteConstants.h:257
GLint GLenum GLint x
Definition: glcorearb.h:404
#define GTE_C_TAN_DEG3_C1
Definition: GteConstants.h:228
#define GTE_C_TAN_DEG7_C1
Definition: GteConstants.h:237
#define GTE_C_PI
Definition: GteConstants.h:17
#define GTE_C_TAN_DEG11_C5
Definition: GteConstants.h:254
#define GTE_C_TAN_DEG7_C3
Definition: GteConstants.h:239
#define GTE_C_TAN_DEG13_C1
Definition: GteConstants.h:258
#define GTE_C_TAN_DEG11_C3
Definition: GteConstants.h:252
#define GTE_C_TAN_DEG11_C2
Definition: GteConstants.h:251
#define GTE_C_TAN_DEG9_C2
Definition: GteConstants.h:244
#define GTE_C_TAN_DEG9_C0
Definition: GteConstants.h:242
static Real Degree(Real x)
#define GTE_C_TAN_DEG13_C2
Definition: GteConstants.h:259
#define GTE_C_HALF_PI
Definition: GteConstants.h:18
#define GTE_C_TAN_DEG13_C4
Definition: GteConstants.h:261
#define GTE_C_TAN_DEG3_C0
Definition: GteConstants.h:227
static Real DegreeRR(Real x)
#define GTE_C_TAN_DEG5_C2
Definition: GteConstants.h:233
#define GTE_C_TAN_DEG13_C6
Definition: GteConstants.h:263
#define GTE_C_TAN_DEG5_C0
Definition: GteConstants.h:231
#define GTE_C_TAN_DEG13_C5
Definition: GteConstants.h:262
#define GTE_C_TAN_DEG13_C3
Definition: GteConstants.h:260
#define GTE_C_TAN_DEG7_C0
Definition: GteConstants.h:236
GLint y
Definition: glcorearb.h:98
#define GTE_C_TAN_DEG11_C1
Definition: GteConstants.h:250


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01