mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
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#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
36namespace mx
37{
38namespace 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 */
61template <typename T>
62constexpr 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
74template <>
75constexpr float pi<float>()
76{
77 return static_cast<float>( MX_INTERNAL_PI_100 );
78}
79
80template <>
81constexpr double pi<double>()
82{
83 return static_cast<double>( MX_INTERNAL_PI_100 );
84}
85
86template <>
87constexpr long double pi<long double>()
88{
89 return static_cast<long double>( MX_INTERNAL_PI_100 );
90}
91
92#ifdef HASQUAD
93template <>
94constexpr __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 */
106template <typename T>
107constexpr 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
119template <>
120constexpr float two_pi<float>()
121{
122 return static_cast<float>( 2 * MX_INTERNAL_PI_100 );
123}
124
125template <>
126constexpr double two_pi<double>()
127{
128 return static_cast<double>( 2 * MX_INTERNAL_PI_100 );
129}
130
131template <>
132constexpr long double two_pi<long double>()
133{
134 return static_cast<long double>( 2 * MX_INTERNAL_PI_100 );
135}
136
137#ifdef HASQUAD
138template <>
139constexpr __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 */
151template <typename T>
152constexpr 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
164template <>
165constexpr float half_pi<float>()
166{
167 return static_cast<float>( MX_INTERNAL_PI_100 ) / static_cast<float>( 2 );
168}
169
170template <>
171constexpr double half_pi<double>()
172{
173 return static_cast<double>( MX_INTERNAL_PI_100 ) / static_cast<double>( 2 );
174}
175
176template <>
177constexpr 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
183template <>
184constexpr __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 */
197template <typename T>
198constexpr 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
210template <>
211constexpr float rad2deg<float>()
212{
213 return static_cast<float>( 180 ) / static_cast<float>( MX_INTERNAL_PI_100 );
214}
215
216template <>
217constexpr double rad2deg<double>()
218{
219 return static_cast<double>( 180 ) / static_cast<double>( MX_INTERNAL_PI_100 );
220}
221
222template <>
223constexpr 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
229template <>
230constexpr __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 */
242template <typename T>
243constexpr 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
255template <>
256constexpr float root_two<float>()
257{
258 return static_cast<float>( MX_INTERNAL_ROOT2_100 );
259}
260
261template <>
262constexpr double root_two<double>()
263{
264 return static_cast<double>( MX_INTERNAL_ROOT2_100 );
265}
266
267template <>
268constexpr long double root_two<long double>()
269{
270 return static_cast<long double>( MX_INTERNAL_ROOT2_100 );
271}
272
273#ifdef HASQUAD
274template <>
275constexpr __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 */
287template <typename T>
288constexpr 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
300template <>
301constexpr float ln_two<float>()
302{
303 return static_cast<float>( MX_INTERNAL_LN2_100 );
304}
305
306template <>
307constexpr double ln_two<double>()
308{
309 return static_cast<double>( MX_INTERNAL_LN2_100 );
310}
311
312template <>
313constexpr long double ln_two<long double>()
314{
315 return static_cast<long double>( MX_INTERNAL_LN2_100 );
316}
317
318#ifdef HASQUAD
319template <>
320constexpr __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 */
332template <typename T>
333constexpr 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
345template <>
346constexpr float root_three<float>()
347{
348 return static_cast<float>( MX_INTERNAL_ROOT3_100 );
349}
350
351template <>
352constexpr double root_three<double>()
353{
354 return static_cast<double>( MX_INTERNAL_ROOT3_100 );
355}
356
357template <>
358constexpr long double root_three<long double>()
359{
360 return static_cast<long double>( MX_INTERNAL_ROOT3_100 );
361}
362
363#ifdef HASQUAD
364template <>
365constexpr __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 */
378template <typename T>
379constexpr 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
387template <>
388constexpr float half_root_three<float>()
389{
390 return static_cast<float>( MX_INTERNAL_HALF_ROOT3_100 );
391}
392
393template <>
394constexpr double half_root_three<double>()
395{
396 return static_cast<double>( MX_INTERNAL_HALF_ROOT3_100 );
397}
398
399template <>
400constexpr long double half_root_three<long double>()
401{
402 return static_cast<long double>( MX_INTERNAL_HALF_ROOT3_100 );
403}
404
405#ifdef HASQUAD
406template <>
407constexpr __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 */
418template <typename T>
419constexpr 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
431template <>
432constexpr float third<float>()
433{
434 return static_cast<float>( 1 ) / static_cast<float>( 3 );
435}
436
437template <>
438constexpr double third<double>()
439{
440 return static_cast<double>( 1 ) / static_cast<double>( 3 );
441}
442
443template <>
444constexpr 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 */
453template <typename floatT>
454constexpr floatT five_thirds()
455{
456 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 */
464template <typename floatT>
465constexpr 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 */
475template <typename floatT>
476constexpr floatT eleven_thirds()
477{
478 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 */
486template <typename floatT>
487constexpr 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 */
497template <typename floatT>
498constexpr floatT six_fifths()
499{
500 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 */
508template <typename floatT>
509constexpr floatT three_fifths()
510{
511 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 */
519template <typename floatT>
520constexpr 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
constexpr T pi()
Get the value of pi.
Definition constants.hpp:62
constexpr floatT six_fifths()
Return 6/5 in the specified precision.
constexpr T root_three()
Get the value of sqrt(3).
constexpr floatT eleven_sixths()
Return 11/6 in the specified precision.
constexpr floatT seventeen_thirds()
Return 17/3 in the specified precision.
constexpr floatT five_thirds()
Return 5/3 in the specified precision.
constexpr T root_two()
Get the value of sqrt(2).
constexpr floatT eleven_thirds()
Return 11/3 in the specified precision.
constexpr T ln_two()
Get the value of ln(2).
constexpr T two_pi()
Get the value of 2pi.
constexpr floatT three_fifths()
Return 3/5 in the specified precision.
constexpr T third()
Get the value of 1/3.
constexpr T half_root_three()
Get the value of sqrt(3)/2.
constexpr T half_pi()
Get the value of pi/2.
constexpr floatT five_sixths()
Return 5/6 in the specified precision.
constexpr T rad2deg()
Get the value of 180/pi.
The mxlib c++ namespace.
Definition mxlib.hpp:37