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 : // 0 1 2 3 4 5 6 7 8 9 1
41 : #define MX_INTERNAL_PI_100 \
42 : ( 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679 )
43 : #define MX_INTERNAL_ROOT2_100 \
44 : ( 1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727 )
45 : #define MX_INTERNAL_LN2_100 \
46 : ( 0.6931471805599453094172321214581765680755001343602552541206800094933936219696947156058633269964186875 )
47 :
48 : /// Get the value of pi
49 : /** Specializations provided for float, double, long double, and quad if supported. Can default to boost for other types
50 : * if MX_INCLUDE_BOOST is defined.
51 : *
52 : * \ingroup genconstants
53 : */
54 : template <typename T>
55 : constexpr T pi()
56 : {
57 : #ifdef MX_INCLUDE_BOOST
58 : return boost::math::constants::pi<T>();
59 : #else
60 : static_assert(
61 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
62 : "pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
63 : return 0;
64 : #endif
65 : }
66 :
67 : template <>
68 : constexpr float pi<float>()
69 : {
70 : return static_cast<float>( MX_INTERNAL_PI_100 );
71 : }
72 :
73 : template <>
74 0 : constexpr double pi<double>()
75 : {
76 0 : return static_cast<double>( MX_INTERNAL_PI_100 );
77 : }
78 :
79 : template <>
80 : constexpr long double pi<long double>()
81 : {
82 : return static_cast<long double>( MX_INTERNAL_PI_100 );
83 : }
84 :
85 : #ifdef HASQUAD
86 : template <>
87 : constexpr __float128 pi<__float128>()
88 : {
89 : return static_cast<__float128>( MX_INTERNAL_PI_100 );
90 : }
91 : #endif
92 :
93 : /// Get the value of 2pi
94 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
95 : * types if MX_INCLUDE_BOOST is defined.
96 : *
97 : * \ingroup genconstants
98 : */
99 : template <typename T>
100 : constexpr T two_pi()
101 : {
102 : #ifdef MX_INCLUDE_BOOST
103 : return boost::math::constants::two_pi<T>();
104 : #else
105 : static_assert(
106 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
107 : "two_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
108 : return 0;
109 : #endif
110 : }
111 :
112 : template <>
113 : constexpr float two_pi<float>()
114 : {
115 : return static_cast<float>( 2 * MX_INTERNAL_PI_100 );
116 : }
117 :
118 : template <>
119 : constexpr double two_pi<double>()
120 : {
121 : return static_cast<double>( 2 * MX_INTERNAL_PI_100 );
122 : }
123 :
124 : template <>
125 : constexpr long double two_pi<long double>()
126 : {
127 : return static_cast<long double>( 2 * MX_INTERNAL_PI_100 );
128 : }
129 :
130 : #ifdef HASQUAD
131 : template <>
132 : constexpr __float128 two_pi<__float128>()
133 : {
134 : return static_cast<__float128>( 2 * MX_INTERNAL_PI_100 );
135 : }
136 : #endif
137 :
138 : /// Get the value of pi/2
139 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
140 : * types if MX_INCLUDE_BOOST is defined.
141 : *
142 : * \ingroup genconstants
143 : */
144 : template <typename T>
145 : constexpr T half_pi()
146 : {
147 : #ifdef MX_INCLUDE_BOOST
148 : return boost::math::constants::half_pi<T>();
149 : #else
150 : static_assert(
151 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
152 : "half_pi<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
153 : return 0;
154 : #endif
155 : }
156 :
157 : template <>
158 : constexpr float half_pi<float>()
159 : {
160 : return static_cast<float>( MX_INTERNAL_PI_100 ) / static_cast<float>( 2 );
161 : }
162 :
163 : template <>
164 : constexpr double half_pi<double>()
165 : {
166 : return static_cast<double>( MX_INTERNAL_PI_100 ) / static_cast<double>( 2 );
167 : }
168 :
169 : template <>
170 : constexpr long double half_pi<long double>()
171 : {
172 : return static_cast<long double>( MX_INTERNAL_PI_100 ) / static_cast<long double>( 2 );
173 : }
174 :
175 : #ifdef HASQUAD
176 : template <>
177 : constexpr __float128 half_pi<__float128>()
178 : {
179 : return static_cast<__float128>( MX_INTERNAL_PI_100 ) / static_cast<__float128>( 2 );
180 : ;
181 : }
182 : #endif
183 :
184 : /// Get the value of 180/pi
185 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
186 : * types if MX_INCLUDE_BOOST is defined.
187 : *
188 : * \ingroup genconstants
189 : */
190 : template <typename T>
191 : constexpr T rad2deg()
192 : {
193 : #ifdef MX_INCLUDE_BOOST
194 : return boost::math::constants::radian<T>();
195 : #else
196 : static_assert(
197 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
198 : "rad2deg<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
199 : return 0;
200 : #endif
201 : }
202 :
203 : template <>
204 : constexpr float rad2deg<float>()
205 : {
206 : return static_cast<float>( 180 ) / static_cast<float>( MX_INTERNAL_PI_100 );
207 : }
208 :
209 : template <>
210 : constexpr double rad2deg<double>()
211 : {
212 : return static_cast<double>( 180 ) / static_cast<double>( MX_INTERNAL_PI_100 );
213 : }
214 :
215 : template <>
216 : constexpr long double rad2deg<long double>()
217 : {
218 : return static_cast<long double>( 180 ) / static_cast<long double>( MX_INTERNAL_PI_100 );
219 : }
220 :
221 : #ifdef HASQUAD
222 : template <>
223 : constexpr __float128 rad2deg<__float128>()
224 : {
225 : return static_cast<__float128>( 180 ) / static_cast<__float128>( MX_INTERNAL_PI_100 );
226 : }
227 : #endif
228 :
229 : /// Get the value of sqrt(2)
230 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
231 : * types if MX_INCLUDE_BOOST is defined.
232 : *
233 : * \ingroup genconstants
234 : */
235 : template <typename T>
236 : constexpr T root_two()
237 : {
238 : #ifdef MX_INCLUDE_BOOST
239 : return boost::math::constants::root_two<T>();
240 : #else
241 : static_assert(
242 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
243 : "root_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
244 : return 0;
245 : #endif
246 : }
247 :
248 : template <>
249 : constexpr float root_two<float>()
250 : {
251 : return static_cast<float>( MX_INTERNAL_ROOT2_100 );
252 : }
253 :
254 : template <>
255 : constexpr double root_two<double>()
256 : {
257 : return static_cast<double>( MX_INTERNAL_ROOT2_100 );
258 : }
259 :
260 : template <>
261 : constexpr long double root_two<long double>()
262 : {
263 : return static_cast<long double>( MX_INTERNAL_ROOT2_100 );
264 : }
265 :
266 : #ifdef HASQUAD
267 : template <>
268 : constexpr __float128 root_two<__float128>()
269 : {
270 : return static_cast<__float128>( MX_INTERNAL_ROOT2_100 );
271 : }
272 : #endif
273 :
274 : /// Get the value of ln(2)
275 : /** Specializations provided for float, double, long double, and quad (if supported). Can default to boost for other
276 : * types if MX_INCLUDE_BOOST is defined.
277 : *
278 : * \ingroup genconstants
279 : */
280 : template <typename T>
281 : constexpr T ln_two()
282 : {
283 : #ifdef MX_INCLUDE_BOOST
284 : return boost::math::constants::ln_two<T>();
285 : #else
286 : static_assert(
287 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
288 : "ln_two<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
289 : return 0;
290 : #endif
291 : }
292 :
293 : template <>
294 : constexpr float ln_two<float>()
295 : {
296 : return static_cast<float>( MX_INTERNAL_LN2_100 );
297 : }
298 :
299 : template <>
300 : constexpr double ln_two<double>()
301 : {
302 : return static_cast<double>( MX_INTERNAL_LN2_100 );
303 : }
304 :
305 : template <>
306 : constexpr long double ln_two<long double>()
307 : {
308 : return static_cast<long double>( MX_INTERNAL_LN2_100 );
309 : }
310 :
311 : #ifdef HASQUAD
312 : template <>
313 : constexpr __float128 ln_two<__float128>()
314 : {
315 : return static_cast<__float128>( MX_INTERNAL_LN2_100 );
316 : }
317 : #endif
318 :
319 : /// Get the value of 1/3
320 : /** Wrapper for boost constant. Specializations provided for float, double, and long double.
321 : *
322 : * \ingroup genconstants
323 : */
324 : template <typename T>
325 : constexpr T third()
326 : {
327 : #ifdef MX_INCLUDE_BOOST
328 : return boost::math::constants::third<T>();
329 : #else
330 : static_assert(
331 : std::is_fundamental<T>::value || !std::is_fundamental<T>::value,
332 : "third<T> not specialized for type T, and MX_INCLUDE_BOOST is not defined, so I can't just use boost." );
333 : return 0;
334 : #endif
335 : }
336 :
337 : template <>
338 : constexpr float third<float>()
339 : {
340 : return static_cast<float>( 1 ) / static_cast<float>( 3 );
341 : }
342 :
343 : template <>
344 : constexpr double third<double>()
345 : {
346 : return static_cast<double>( 1 ) / static_cast<double>( 3 );
347 : }
348 :
349 : template <>
350 : constexpr long double third<long double>()
351 : {
352 : return static_cast<long double>( 1 ) / static_cast<long double>( 3 );
353 : }
354 :
355 : /// Return 5/3 in the specified precision
356 : /** This constant is used frequently in adaptive optics analysis.
357 : * \ingroup genconstants
358 : */
359 : template <typename floatT>
360 : constexpr floatT five_thirds()
361 : {
362 : return static_cast<floatT>( 5 ) / static_cast<floatT>( 3 );
363 : }
364 :
365 : /// Return 5/6 in the specified precision
366 : /** This constant is used frequently in adaptive optics analysis.
367 : * \ingroup genconstants
368 : *
369 : */
370 : template <typename floatT>
371 : constexpr floatT five_sixths()
372 : {
373 : return static_cast<floatT>( 5 ) / static_cast<floatT>( 6 );
374 : }
375 :
376 : /// Return 11/3 in the specified precision
377 : /** This constant is used frequently in adaptive optics analysis.
378 : * \ingroup genconstants
379 : *
380 : */
381 : template <typename floatT>
382 : constexpr floatT eleven_thirds()
383 : {
384 : return static_cast<floatT>( 11 ) / static_cast<floatT>( 3 );
385 : }
386 :
387 : /// Return 11/6 in the specified precision
388 : /** This constant is used frequently in adaptive optics analysis.
389 : * \ingroup genconstants
390 : *
391 : */
392 : template <typename floatT>
393 : constexpr floatT eleven_sixths()
394 : {
395 : return static_cast<floatT>( 11 ) / static_cast<floatT>( 6 );
396 : }
397 :
398 : /// Return 6/5 in the specified precision
399 : /** This constant is used frequently in adaptive optics analysis.
400 : * \ingroup genconstants
401 : *
402 : */
403 : template <typename floatT>
404 : constexpr floatT six_fifths()
405 : {
406 : return static_cast<floatT>( 6 ) / static_cast<floatT>( 5 );
407 : }
408 :
409 : /// Return 3/5 in the specified precision
410 : /** This constant is used frequently in adaptive optics analysis.
411 : * \ingroup genconstants
412 : *
413 : */
414 : template <typename floatT>
415 : constexpr floatT three_fifths()
416 : {
417 : return static_cast<floatT>( 3 ) / static_cast<floatT>( 5 );
418 : }
419 :
420 : /// Return 17/3 in the specified precision
421 : /** This constant is used frequently in adaptive optics analysis.
422 : * \ingroup genconstants
423 : *
424 : */
425 : template <typename floatT>
426 : constexpr floatT seventeen_thirds()
427 : {
428 : return static_cast<floatT>( 17 ) / static_cast<floatT>( 3 );
429 : }
430 :
431 : } // namespace math
432 : } // namespace mx
433 :
434 : #endif // math_constants_hpp
|