Line data Source code
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 : #ifndef math_constants_hpp
28 : #define math_constants_hpp
29 :
30 : #include <type_traits>
31 :
32 : #ifdef MX_INCLUDE_BOOST
33 : #include <boost/math/constants/constants.hpp>
34 : #endif
35 :
36 : namespace mx
37 : {
38 : namespace math
39 : {
40 : // Constants to 100 digits for casting
41 : // 1
42 : // 1 2 3 4 5 6 7 8 9 0
43 : // 01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890
44 : #define MX_INTERNAL_PI_100 \
45 : ( 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 )
46 : #define MX_INTERNAL_ROOT2_100 \
47 : ( 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727 )
48 : #define MX_INTERNAL_LN2_100 \
49 : ( 0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875 )
50 : #define MX_INTERNAL_ROOT3_100 \
51 : ( 1.732050807568877293527446341505872366942805253810380628055806979451933016908800037081146186757248576 )
52 : #define MX_INTERNAL_HALF_ROOT3_100 \
53 : ( 0.8660254037844386467637231707529361834714026269051903140279034897259665084544000185405730933786242878 )
54 :
55 : /// Get the value of pi
56 : /** Specializations provided for float, double, long double, and quad if supported. Can default to boost for other types
57 : * if MX_INCLUDE_BOOST is defined.
58 : *
59 : * \ingroup genconstants
60 : */
61 : template <typename T>
62 : constexpr T pi()
63 : {
64 : #ifdef MX_INCLUDE_BOOST
65 : return boost::math::constants::pi<T>();
66 : #else
67 : static_assert(
68 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
69 : "pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
70 : return 0;
71 : #endif
72 : }
73 :
74 : template <>
75 1 : constexpr float pi<float>()
76 : {
77 1 : return static_cast<float>( MX_INTERNAL_PI_100 );
78 : }
79 :
80 : template <>
81 331445 : constexpr double pi<double>()
82 : {
83 331445 : return static_cast<double>( MX_INTERNAL_PI_100 );
84 : }
85 :
86 : template <>
87 0 : constexpr long double pi<long double>()
88 : {
89 0 : return static_cast<long double>( MX_INTERNAL_PI_100 );
90 : }
91 :
92 : #ifdef HASQUAD
93 : template <>
94 : constexpr __float128 pi<__float128>()
95 : {
96 : return static_cast<__float128>( MX_INTERNAL_PI_100 );
97 : }
98 : #endif
99 :
100 : /// Get the value of 2pi
101 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
102 : * types if MX_INCLUDE_BOOST is defined.
103 : *
104 : * \ingroup genconstants
105 : */
106 : template <typename T>
107 : constexpr T two_pi()
108 : {
109 : #ifdef MX_INCLUDE_BOOST
110 : return boost::math::constants::two_pi<T>();
111 : #else
112 : static_assert(
113 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
114 : "two_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
115 : return 0;
116 : #endif
117 : }
118 :
119 : template <>
120 0 : constexpr float two_pi<float>()
121 : {
122 0 : return static_cast<float>( 2 * MX_INTERNAL_PI_100 );
123 : }
124 :
125 : template <>
126 2651649 : constexpr double two_pi<double>()
127 : {
128 2651649 : return static_cast<double>( 2 * MX_INTERNAL_PI_100 );
129 : }
130 :
131 : template <>
132 0 : constexpr long double two_pi<long double>()
133 : {
134 0 : return static_cast<long double>( 2 * MX_INTERNAL_PI_100 );
135 : }
136 :
137 : #ifdef HASQUAD
138 : template <>
139 : constexpr __float128 two_pi<__float128>()
140 : {
141 : return static_cast<__float128>( 2 * MX_INTERNAL_PI_100 );
142 : }
143 : #endif
144 :
145 : /// Get the value of pi/2
146 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
147 : * types if MX_INCLUDE_BOOST is defined.
148 : *
149 : * \ingroup genconstants
150 : */
151 : template <typename T>
152 : constexpr T half_pi()
153 : {
154 : #ifdef MX_INCLUDE_BOOST
155 : return boost::math::constants::half_pi<T>();
156 : #else
157 : static_assert(
158 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
159 : "half_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
160 : return 0;
161 : #endif
162 : }
163 :
164 : template <>
165 : constexpr float half_pi<float>()
166 : {
167 : return static_cast<float>( MX_INTERNAL_PI_100 ) / static_cast<float>( 2 );
168 : }
169 :
170 : template <>
171 1 : constexpr double half_pi<double>()
172 : {
173 1 : return static_cast<double>( MX_INTERNAL_PI_100 ) / static_cast<double>( 2 );
174 : }
175 :
176 : template <>
177 : constexpr long double half_pi<long double>()
178 : {
179 : return static_cast<long double>( MX_INTERNAL_PI_100 ) / static_cast<long double>( 2 );
180 : }
181 :
182 : #ifdef HASQUAD
183 : template <>
184 : constexpr __float128 half_pi<__float128>()
185 : {
186 : return static_cast<__float128>( MX_INTERNAL_PI_100 ) / static_cast<__float128>( 2 );
187 : ;
188 : }
189 : #endif
190 :
191 : /// Get the value of 180/pi
192 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
193 : * types if MX_INCLUDE_BOOST is defined.
194 : *
195 : * \ingroup genconstants
196 : */
197 : template <typename T>
198 : constexpr T rad2deg()
199 : {
200 : #ifdef MX_INCLUDE_BOOST
201 : return boost::math::constants::radian<T>();
202 : #else
203 : static_assert(
204 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
205 : "rad2deg<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
206 : return 0;
207 : #endif
208 : }
209 :
210 : template <>
211 : constexpr float rad2deg<float>()
212 : {
213 : return static_cast<float>( 180 ) / static_cast<float>( MX_INTERNAL_PI_100 );
214 : }
215 :
216 : template <>
217 : constexpr double rad2deg<double>()
218 : {
219 : return static_cast<double>( 180 ) / static_cast<double>( MX_INTERNAL_PI_100 );
220 : }
221 :
222 : template <>
223 : constexpr long double rad2deg<long double>()
224 : {
225 : return static_cast<long double>( 180 ) / static_cast<long double>( MX_INTERNAL_PI_100 );
226 : }
227 :
228 : #ifdef HASQUAD
229 : template <>
230 : constexpr __float128 rad2deg<__float128>()
231 : {
232 : return static_cast<__float128>( 180 ) / static_cast<__float128>( MX_INTERNAL_PI_100 );
233 : }
234 : #endif
235 :
236 : /// Get the value of sqrt(2)
237 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
238 : * types if MX_INCLUDE_BOOST is defined.
239 : *
240 : * \ingroup genconstants
241 : */
242 : template <typename T>
243 : constexpr T root_two()
244 : {
245 : #ifdef MX_INCLUDE_BOOST
246 : return boost::math::constants::root_two<T>();
247 : #else
248 : static_assert(
249 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
250 : "root_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
251 : return 0;
252 : #endif
253 : }
254 :
255 : template <>
256 0 : constexpr float root_two<float>()
257 : {
258 0 : return static_cast<float>( MX_INTERNAL_ROOT2_100 );
259 : }
260 :
261 : template <>
262 0 : constexpr double root_two<double>()
263 : {
264 0 : return static_cast<double>( MX_INTERNAL_ROOT2_100 );
265 : }
266 :
267 : template <>
268 0 : constexpr long double root_two<long double>()
269 : {
270 0 : return static_cast<long double>( MX_INTERNAL_ROOT2_100 );
271 : }
272 :
273 : #ifdef HASQUAD
274 : template <>
275 : constexpr __float128 root_two<__float128>()
276 : {
277 : return static_cast<__float128>( MX_INTERNAL_ROOT2_100 );
278 : }
279 : #endif
280 :
281 : /// Get the value of ln(2)
282 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
283 : * types if MX_INCLUDE_BOOST is defined.
284 : *
285 : * \ingroup genconstants
286 : */
287 : template <typename T>
288 : constexpr T ln_two()
289 : {
290 : #ifdef MX_INCLUDE_BOOST
291 : return boost::math::constants::ln_two<T>();
292 : #else
293 : static_assert(
294 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
295 : "ln_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
296 : return 0;
297 : #endif
298 : }
299 :
300 : template <>
301 : constexpr float ln_two<float>()
302 : {
303 : return static_cast<float>( MX_INTERNAL_LN2_100 );
304 : }
305 :
306 : template <>
307 : constexpr double ln_two<double>()
308 : {
309 : return static_cast<double>( MX_INTERNAL_LN2_100 );
310 : }
311 :
312 : template <>
313 : constexpr long double ln_two<long double>()
314 : {
315 : return static_cast<long double>( MX_INTERNAL_LN2_100 );
316 : }
317 :
318 : #ifdef HASQUAD
319 : template <>
320 : constexpr __float128 ln_two<__float128>()
321 : {
322 : return static_cast<__float128>( MX_INTERNAL_LN2_100 );
323 : }
324 : #endif
325 :
326 : /// Get the value of sqrt(3)
327 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
328 : * types if MX_INCLUDE_BOOST is defined.
329 : *
330 : * \ingroup genconstants
331 : */
332 : template <typename T>
333 : constexpr T root_three()
334 : {
335 : #ifdef MX_INCLUDE_BOOST
336 : return boost::math::constants::root_three<T>();
337 : #else
338 : static_assert(
339 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
340 : "root_three<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
341 : return 0;
342 : #endif
343 : }
344 :
345 : template <>
346 : constexpr float root_three<float>()
347 : {
348 : return static_cast<float>( MX_INTERNAL_ROOT3_100 );
349 : }
350 :
351 : template <>
352 : constexpr double root_three<double>()
353 : {
354 : return static_cast<double>( MX_INTERNAL_ROOT3_100 );
355 : }
356 :
357 : template <>
358 : constexpr long double root_three<long double>()
359 : {
360 : return static_cast<long double>( MX_INTERNAL_ROOT3_100 );
361 : }
362 :
363 : #ifdef HASQUAD
364 : template <>
365 : constexpr __float128 root_three<__float128>()
366 : {
367 : return static_cast<__float128>( MX_INTERNAL_ROOT3_100 );
368 : }
369 : #endif
370 :
371 : /// Get the value of sqrt(3)/2
372 : /** Specializations provided for float, double, long double, and quad (if supported).
373 : *
374 : * Note there is no boost equivalent.
375 : *
376 : * \ingroup genconstants
377 : */
378 : template <typename T>
379 : constexpr T half_root_three()
380 : {
381 : static_assert(
382 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
383 : "half_root_three<T> not specialized for type T, and there is no boost equivalent." );
384 : return 0;
385 : }
386 :
387 : template <>
388 : constexpr float half_root_three<float>()
389 : {
390 : return static_cast<float>( MX_INTERNAL_HALF_ROOT3_100 );
391 : }
392 :
393 : template <>
394 : constexpr double half_root_three<double>()
395 : {
396 : return static_cast<double>( MX_INTERNAL_HALF_ROOT3_100 );
397 : }
398 :
399 : template <>
400 : constexpr long double half_root_three<long double>()
401 : {
402 : return static_cast<long double>( MX_INTERNAL_HALF_ROOT3_100 );
403 : }
404 :
405 : #ifdef HASQUAD
406 : template <>
407 : constexpr __float128 half_root_three<__float128>()
408 : {
409 : return static_cast<__float128>( MX_INTERNAL_HALF_ROOT3_100 );
410 : }
411 : #endif
412 :
413 : /// Get the value of 1/3
414 : /** Wrapper for boost constant. Specializations provided for float, double, and long double.
415 : *
416 : * \ingroup genconstants
417 : */
418 : template <typename T>
419 : constexpr T third()
420 : {
421 : #ifdef MX_INCLUDE_BOOST
422 : return boost::math::constants::third<T>();
423 : #else
424 : static_assert(
425 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
426 : "third<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
427 : return 0;
428 : #endif
429 : }
430 :
431 : template <>
432 : constexpr float third<float>()
433 : {
434 : return static_cast<float>( 1 ) / static_cast<float>( 3 );
435 : }
436 :
437 : template <>
438 : constexpr double third<double>()
439 : {
440 : return static_cast<double>( 1 ) / static_cast<double>( 3 );
441 : }
442 :
443 : template <>
444 : constexpr long double third<long double>()
445 : {
446 : return static_cast<long double>( 1 ) / static_cast<long double>( 3 );
447 : }
448 :
449 : /// Return 5/3 in the specified precision
450 : /** This constant is used frequently in adaptive optics analysis.
451 : * \ingroup genconstants
452 : */
453 : template <typename floatT>
454 96478 : constexpr floatT five_thirds()
455 : {
456 96478 : return static_cast<floatT>( 5 ) / static_cast<floatT>( 3 );
457 : }
458 :
459 : /// Return 5/6 in the specified precision
460 : /** This constant is used frequently in adaptive optics analysis.
461 : * \ingroup genconstants
462 : *
463 : */
464 : template <typename floatT>
465 : constexpr floatT five_sixths()
466 : {
467 : return static_cast<floatT>( 5 ) / static_cast<floatT>( 6 );
468 : }
469 :
470 : /// Return 11/3 in the specified precision
471 : /** This constant is used frequently in adaptive optics analysis.
472 : * \ingroup genconstants
473 : *
474 : */
475 : template <typename floatT>
476 96615 : constexpr floatT eleven_thirds()
477 : {
478 96615 : return static_cast<floatT>( 11 ) / static_cast<floatT>( 3 );
479 : }
480 :
481 : /// Return 11/6 in the specified precision
482 : /** This constant is used frequently in adaptive optics analysis.
483 : * \ingroup genconstants
484 : *
485 : */
486 : template <typename floatT>
487 : constexpr floatT eleven_sixths()
488 : {
489 : return static_cast<floatT>( 11 ) / static_cast<floatT>( 6 );
490 : }
491 :
492 : /// Return 6/5 in the specified precision
493 : /** This constant is used frequently in adaptive optics analysis.
494 : * \ingroup genconstants
495 : *
496 : */
497 : template <typename floatT>
498 8 : constexpr floatT six_fifths()
499 : {
500 8 : return static_cast<floatT>( 6 ) / static_cast<floatT>( 5 );
501 : }
502 :
503 : /// Return 3/5 in the specified precision
504 : /** This constant is used frequently in adaptive optics analysis.
505 : * \ingroup genconstants
506 : *
507 : */
508 : template <typename floatT>
509 6 : constexpr floatT three_fifths()
510 : {
511 6 : return static_cast<floatT>( 3 ) / static_cast<floatT>( 5 );
512 : }
513 :
514 : /// Return 17/3 in the specified precision
515 : /** This constant is used frequently in adaptive optics analysis.
516 : * \ingroup genconstants
517 : *
518 : */
519 : template <typename floatT>
520 : constexpr floatT seventeen_thirds()
521 : {
522 : return static_cast<floatT>( 17 ) / static_cast<floatT>( 3 );
523 : }
524 :
525 : } // namespace math
526 : } // namespace mx
527 :
528 : #endif // math_constants_hpp
|