mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
constants.hpp
1 /** \file math.hpp
2  * \author Jared R. Males
3  * \brief Definitions of constants
4  * \ingroup gen_math_files
5  *
6  */
7 
8 //***********************************************************************//
9 // Copyright 2020 Jared R. Males (jaredmales@gmail.com)
10 //
11 // This file is part of mxlib.
12 //
13 // mxlib is free software: you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation, either version 3 of the License, or
16 // (at your option) any later version.
17 //
18 // mxlib is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with mxlib. If not, see <http://www.gnu.org/licenses/>.
25 //***********************************************************************//
26 
27 
28 #ifndef math_constants_hpp
29 #define math_constants_hpp
30 
31 #include <type_traits>
32 
33 #ifdef MX_INCLUDE_BOOST
34 #include <boost/math/constants/constants.hpp>
35 #endif
36 
37 namespace mx
38 {
39 namespace math
40 {
41 // 0 1 2 3 4 5 6 7 8 9 1
42 #define MX_INTERNAL_PI_100 (3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679)
43 #define MX_INTERNAL_ROOT2_100 (1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727)
44 #define MX_INTERNAL_LN2_100 (0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875)
45 
46 /// Get the value of pi
47 /** Specializations provided for float, double, long double, and quad if supported. Can default to boost for other types if MX_INCLUDE_BOOST is defined.
48  *
49  * \ingroup genconstants
50  */
51 template<typename T>
52 constexpr T pi()
53 {
54 #ifdef MX_INCLUDE_BOOST
55  return boost::math::constants::pi<T>();
56 #else
57  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
58  return 0;
59 #endif
60 }
61 
62 template<>
63 constexpr float pi<float>()
64 {
65  return static_cast<float>(MX_INTERNAL_PI_100);
66 }
67 
68 template<>
69 constexpr double pi<double>()
70 {
71  return static_cast<double>(MX_INTERNAL_PI_100);
72 }
73 
74 template<>
75 constexpr long double pi<long double>()
76 {
77  return static_cast<long double>(MX_INTERNAL_PI_100);
78 }
79 
80 #ifdef HASQUAD
81 template<>
82 constexpr __float128 pi<__float128>()
83 {
84  return static_cast<__float128>(MX_INTERNAL_PI_100);
85 }
86 #endif
87 
88 /// Get the value of 2pi
89 /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other types if MX_INCLUDE_BOOST is defined.
90  *
91  * \ingroup genconstants
92  */
93 template<typename T>
94 constexpr T two_pi()
95 {
96 #ifdef MX_INCLUDE_BOOST
97  return boost::math::constants::two_pi<T>();
98 #else
99  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "two_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
100  return 0;
101 #endif
102 }
103 
104 template<>
105 constexpr float two_pi<float>()
106 {
107  return static_cast<float>(2*MX_INTERNAL_PI_100);
108 }
109 
110 template<>
111 constexpr double two_pi<double>()
112 {
113  return static_cast<double>(2*MX_INTERNAL_PI_100);
114 }
115 
116 template<>
117 constexpr long double two_pi<long double>()
118 {
119  return static_cast<long double>(2*MX_INTERNAL_PI_100);
120 }
121 
122 #ifdef HASQUAD
123 template<>
124 constexpr __float128 two_pi<__float128>()
125 {
126  return static_cast<__float128>(2*MX_INTERNAL_PI_100);
127 }
128 #endif
129 
130 /// Get the value of pi/2
131 /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other types if MX_INCLUDE_BOOST is defined.
132  *
133  * \ingroup genconstants
134  */
135 template<typename T>
136 constexpr T half_pi()
137 {
138 #ifdef MX_INCLUDE_BOOST
139  return boost::math::constants::half_pi<T>();
140 #else
141  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "half_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
142  return 0;
143 #endif
144 }
145 
146 template<>
147 constexpr float half_pi<float>()
148 {
149  return static_cast<float>(MX_INTERNAL_PI_100)/static_cast<float>(2);
150 }
151 
152 template<>
153 constexpr double half_pi<double>()
154 {
155  return static_cast<double>(MX_INTERNAL_PI_100)/static_cast<double>(2);
156 }
157 
158 template<>
159 constexpr long double half_pi<long double>()
160 {
161  return static_cast<long double>(MX_INTERNAL_PI_100)/static_cast<long double>(2);
162 }
163 
164 #ifdef HASQUAD
165 template<>
166 constexpr __float128 half_pi<__float128>()
167 {
168  return static_cast<__float128>(MX_INTERNAL_PI_100)/static_cast<__float128>(2);;
169 }
170 #endif
171 
172 /// Get the value of 180/pi
173 /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other types if MX_INCLUDE_BOOST is defined.
174  *
175  * \ingroup genconstants
176  */
177 template<typename T>
178 constexpr T rad2deg()
179 {
180 #ifdef MX_INCLUDE_BOOST
181  return boost::math::constants::radian<T>();
182 #else
183  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "rad2deg<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
184  return 0;
185 #endif
186 }
187 
188 template<>
189 constexpr float rad2deg<float>()
190 {
191  return static_cast<float>(180)/static_cast<float>(MX_INTERNAL_PI_100);
192 }
193 
194 template<>
195 constexpr double rad2deg<double>()
196 {
197  return static_cast<double>(180)/static_cast<double>(MX_INTERNAL_PI_100);
198 }
199 
200 template<>
201 constexpr long double rad2deg<long double>()
202 {
203  return static_cast<long double>(180)/static_cast<long double>(MX_INTERNAL_PI_100);
204 }
205 
206 #ifdef HASQUAD
207 template<>
208 constexpr __float128 rad2deg<__float128>()
209 {
210  return static_cast<__float128>(180)/static_cast<__float128>(MX_INTERNAL_PI_100);
211 }
212 #endif
213 
214 /// Get the value of sqrt(2)
215 /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other types if MX_INCLUDE_BOOST is defined.
216  *
217  * \ingroup genconstants
218  */
219 template<typename T>
220 constexpr T root_two()
221 {
222 #ifdef MX_INCLUDE_BOOST
223  return boost::math::constants::root_two<T>();
224 #else
225  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "root_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
226  return 0;
227 #endif
228 }
229 
230 template<>
231 constexpr float root_two<float>()
232 {
233  return static_cast<float>(MX_INTERNAL_ROOT2_100);
234 }
235 
236 template<>
237 constexpr double root_two<double>()
238 {
239  return static_cast<double>(MX_INTERNAL_ROOT2_100);
240 }
241 
242 template<>
243 constexpr long double root_two<long double>()
244 {
245  return static_cast<long double>(MX_INTERNAL_ROOT2_100);
246 }
247 
248 #ifdef HASQUAD
249 template<>
250 constexpr __float128 root_two<__float128>()
251 {
252  return static_cast<__float128>(MX_INTERNAL_ROOT2_100);
253 }
254 #endif
255 
256 
257 /// Get the value of ln(2)
258 /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other types if MX_INCLUDE_BOOST is defined.
259  *
260  * \ingroup genconstants
261  */
262 template<typename T>
263 constexpr T ln_two()
264 {
265 #ifdef MX_INCLUDE_BOOST
266  return boost::math::constants::ln_two<T>();
267 #else
268  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "ln_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
269  return 0;
270 #endif
271 }
272 
273 template<>
274 constexpr float ln_two<float>()
275 {
276  return static_cast<float>(MX_INTERNAL_LN2_100);
277 }
278 
279 template<>
280 constexpr double ln_two<double>()
281 {
282  return static_cast<double>(MX_INTERNAL_LN2_100);
283 }
284 
285 template<>
286 constexpr long double ln_two<long double>()
287 {
288  return static_cast<long double>(MX_INTERNAL_LN2_100);
289 }
290 
291 #ifdef HASQUAD
292 template<>
293 constexpr __float128 ln_two<__float128>()
294 {
295  return static_cast<__float128>(MX_INTERNAL_LN2_100);
296 }
297 #endif
298 
299 
300 /// Get the value of 1/3
301 /** Wrapper for boost constant. Specializations provided for float, double, and long double.
302  *
303  * \ingroup genconstants
304  */
305 template<typename T>
306 constexpr T third()
307 {
308 #ifdef MX_INCLUDE_BOOST
309  return boost::math::constants::third<T>();
310 #else
311  static_assert(std::is_fundamental<T>::value || !std::is_fundamental<T>::value, "third<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost.");
312  return 0;
313 #endif
314 }
315 
316 template<>
317 constexpr float third<float>()
318 {
319  return static_cast<float>(1)/static_cast<float>(3);
320 }
321 
322 template<>
323 constexpr double third<double>()
324 {
325  return static_cast<double>(1)/static_cast<double>(3);
326 }
327 
328 template<>
329 constexpr long double third<long double>()
330 {
331  return static_cast<long double>(1)/static_cast<long double>(3);
332 }
333 
334 
335 ///Return 5/3 in the specified precision
336 /** This constant is used frequently in adaptive optics analysis.
337  * \ingroup genconstants
338  */
339 template<typename floatT>
340 constexpr floatT five_thirds()
341 {
342  return static_cast<floatT>(5)/static_cast<floatT>(3);
343 }
344 
345 
346 ///Return 5/6 in the specified precision
347 /** This constant is used frequently in adaptive optics analysis.
348  * \ingroup genconstants
349  *
350  */
351 template<typename floatT>
352 constexpr floatT five_sixths()
353 {
354  return static_cast<floatT>(5)/static_cast<floatT>(6);
355 }
356 
357 ///Return 11/3 in the specified precision
358 /** This constant is used frequently in adaptive optics analysis.
359  * \ingroup genconstants
360  *
361  */
362 template<typename floatT>
363 constexpr floatT eleven_thirds()
364 {
365  return static_cast<floatT>(11)/static_cast<floatT>(3);
366 }
367 
368 ///Return 11/6 in the specified precision
369 /** This constant is used frequently in adaptive optics analysis.
370  * \ingroup genconstants
371  *
372  */
373 template<typename floatT>
374 constexpr floatT eleven_sixths()
375 {
376  return static_cast<floatT>(11)/static_cast<floatT>(6);
377 }
378 
379 ///Return 6/5 in the specified precision
380 /** This constant is used frequently in adaptive optics analysis.
381  * \ingroup genconstants
382  *
383  */
384 template<typename floatT>
385 constexpr floatT six_fifths()
386 {
387  return static_cast<floatT>(6)/static_cast<floatT>(5);
388 }
389 
390 ///Return 3/5 in the specified precision
391 /** This constant is used frequently in adaptive optics analysis.
392  * \ingroup genconstants
393  *
394  */
395 template<typename floatT>
396 constexpr floatT three_fifths()
397 {
398  return static_cast<floatT>(3)/static_cast<floatT>(5);
399 }
400 
401 ///Return 17/3 in the specified precision
402 /** This constant is used frequently in adaptive optics analysis.
403  * \ingroup genconstants
404  *
405  */
406 template<typename floatT>
407 constexpr floatT seventeen_thirds()
408 {
409  return static_cast<floatT>(17)/static_cast<floatT>(3);
410 }
411 
412 } //namespace math
413 } //namespace mx
414 
415 #endif //math_constants_hpp
constexpr T pi()
Get the value of pi.
Definition: constants.hpp:52
constexpr floatT six_fifths()
Return 6/5 in the specified precision.
Definition: constants.hpp:385
constexpr floatT eleven_sixths()
Return 11/6 in the specified precision.
Definition: constants.hpp:374
constexpr floatT seventeen_thirds()
Return 17/3 in the specified precision.
Definition: constants.hpp:407
constexpr floatT five_thirds()
Return 5/3 in the specified precision.
Definition: constants.hpp:340
constexpr T root_two()
Get the value of sqrt(2)
Definition: constants.hpp:220
constexpr floatT eleven_thirds()
Return 11/3 in the specified precision.
Definition: constants.hpp:363
constexpr T ln_two()
Get the value of ln(2)
Definition: constants.hpp:263
constexpr T two_pi()
Get the value of 2pi.
Definition: constants.hpp:94
constexpr floatT three_fifths()
Return 3/5 in the specified precision.
Definition: constants.hpp:396
constexpr T third()
Get the value of 1/3.
Definition: constants.hpp:306
constexpr T half_pi()
Get the value of pi/2.
Definition: constants.hpp:136
constexpr floatT five_sixths()
Return 5/6 in the specified precision.
Definition: constants.hpp:352
constexpr T rad2deg()
Get the value of 180/pi.
Definition: constants.hpp:178
The mxlib c++ namespace.
Definition: mxError.hpp:107