1 // SPDX-License-Identifier: Apache-2.0
2 //
3 // Copyright 2008-2016 Conrad Sanderson (http://conradsanderson.id.au)
4 // Copyright 2008-2016 National ICT Australia (NICTA)
5 //
6 // Licensed under the Apache License, Version 2.0 (the "License");
7 // you may not use this file except in compliance with the License.
8 // You may obtain a copy of the License at
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 // ------------------------------------------------------------------------
17 
18 
19 //! \addtogroup constants
20 //! @{
21 
22 
23 namespace priv
24   {
25   class Datum_helper
26     {
27     public:
28 
29     template<typename eT>
30     static
31     typename arma_real_only<eT>::result
nan(typename arma_real_only<eT>::result * junk=nullptr)32     nan(typename arma_real_only<eT>::result* junk = nullptr)
33       {
34       arma_ignore(junk);
35 
36       if(std::numeric_limits<eT>::has_quiet_NaN)
37         {
38         return std::numeric_limits<eT>::quiet_NaN();
39         }
40       else
41         {
42         return eT(0);
43         }
44       }
45 
46 
47     template<typename eT>
48     static
49     typename arma_cx_only<eT>::result
nan(typename arma_cx_only<eT>::result * junk=nullptr)50     nan(typename arma_cx_only<eT>::result* junk = nullptr)
51       {
52       arma_ignore(junk);
53 
54       typedef typename get_pod_type<eT>::result T;
55 
56       return eT( Datum_helper::nan<T>(), Datum_helper::nan<T>() );
57       }
58 
59 
60     template<typename eT>
61     static
62     typename arma_integral_only<eT>::result
nan(typename arma_integral_only<eT>::result * junk=nullptr)63     nan(typename arma_integral_only<eT>::result* junk = nullptr)
64       {
65       arma_ignore(junk);
66 
67       return eT(0);
68       }
69 
70 
71     template<typename eT>
72     static
73     typename arma_real_only<eT>::result
inf(typename arma_real_only<eT>::result * junk=nullptr)74     inf(typename arma_real_only<eT>::result* junk = nullptr)
75       {
76       arma_ignore(junk);
77 
78       if(std::numeric_limits<eT>::has_infinity)
79         {
80         return std::numeric_limits<eT>::infinity();
81         }
82       else
83         {
84         return std::numeric_limits<eT>::max();
85         }
86       }
87 
88 
89     template<typename eT>
90     static
91     typename arma_cx_only<eT>::result
inf(typename arma_cx_only<eT>::result * junk=nullptr)92     inf(typename arma_cx_only<eT>::result* junk = nullptr)
93       {
94       arma_ignore(junk);
95 
96       typedef typename get_pod_type<eT>::result T;
97 
98       return eT( Datum_helper::inf<T>(), Datum_helper::inf<T>() );
99       }
100 
101 
102     template<typename eT>
103     static
104     typename arma_integral_only<eT>::result
inf(typename arma_integral_only<eT>::result * junk=nullptr)105     inf(typename arma_integral_only<eT>::result* junk = nullptr)
106       {
107       arma_ignore(junk);
108 
109       return std::numeric_limits<eT>::max();
110       }
111 
112     };
113   }
114 
115 
116 
117 //! various constants.
118 //! Physical constants taken from NIST 2018 CODATA values, and some from WolframAlpha (values provided as of 2009-06-23)
119 //! http://physics.nist.gov/cuu/Constants
120 //! http://www.wolframalpha.com
121 //! See also http://en.wikipedia.org/wiki/Physical_constant
122 
123 
124 template<typename eT>
125 class Datum
126   {
127   public:
128 
129   static const eT pi;           //!< ratio of any circle's circumference to its diameter
130   static const eT e;            //!< base of the natural logarithm
131   static const eT euler;        //!< Euler's constant, aka Euler-Mascheroni constant
132   static const eT gratio;       //!< golden ratio
133   static const eT sqrt2;        //!< square root of 2
134   static const eT sqrt2pi;      //!< square root of 2*pi
135   static const eT log_sqrt2pi;  //!< log of square root of 2*pi
136   static const eT eps;          //!< the difference between 1 and the least value greater than 1 that is representable
137   static const eT log_min;      //!< log of the minimum representable value
138   static const eT log_max;      //!< log of the maximum representable value
139   static const eT nan;          //!< "not a number"
140   static const eT inf;          //!< infinity
141 
142   //
143 
144   static const eT m_u;       //!< atomic mass constant (in kg)
145   static const eT N_A;       //!< Avogadro constant
146   static const eT k;         //!< Boltzmann constant (in joules per kelvin)
147   static const eT k_evk;     //!< Boltzmann constant (in eV/K)
148   static const eT a_0;       //!< Bohr radius (in meters)
149   static const eT mu_B;      //!< Bohr magneton
150   static const eT Z_0;       //!< characteristic impedance of vacuum (in ohms)
151   static const eT G_0;       //!< conductance quantum (in siemens)
152   static const eT k_e;       //!< Coulomb's constant (in meters per farad)
153   static const eT eps_0;     //!< electric constant (in farads per meter)
154   static const eT m_e;       //!< electron mass (in kg)
155   static const eT eV;        //!< electron volt (in joules)
156   static const eT ec;        //!< elementary charge (in coulombs)
157   static const eT F;         //!< Faraday constant (in coulombs)
158   static const eT alpha;     //!< fine-structure constant
159   static const eT alpha_inv; //!< inverse fine-structure constant
160   static const eT K_J;       //!< Josephson constant
161   static const eT mu_0;      //!< magnetic constant (in henries per meter)
162   static const eT phi_0;     //!< magnetic flux quantum (in webers)
163   static const eT R;         //!< molar gas constant (in joules per mole kelvin)
164   static const eT G;         //!< Newtonian constant of gravitation (in newton square meters per kilogram squared)
165   static const eT h;         //!< Planck constant (in joule seconds)
166   static const eT h_bar;     //!< Planck constant over 2 pi, aka reduced Planck constant (in joule seconds)
167   static const eT m_p;       //!< proton mass (in kg)
168   static const eT R_inf;     //!< Rydberg constant (in reciprocal meters)
169   static const eT c_0;       //!< speed of light in vacuum (in meters per second)
170   static const eT sigma;     //!< Stefan-Boltzmann constant
171   static const eT R_k;       //!< von Klitzing constant (in ohms)
172   static const eT b;         //!< Wien wavelength displacement law constant
173   };
174 
175 
176 // the long lengths of the constants are for future support of "long double"
177 // and any smart compiler that does high-precision computation at compile-time
178 
179 template<typename eT> const eT Datum<eT>::pi          = eT(3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679);
180 template<typename eT> const eT Datum<eT>::e           = eT(2.7182818284590452353602874713526624977572470936999595749669676277240766303535475945713821785251664274);
181 template<typename eT> const eT Datum<eT>::euler       = eT(0.5772156649015328606065120900824024310421593359399235988057672348848677267776646709369470632917467495);
182 template<typename eT> const eT Datum<eT>::gratio      = eT(1.6180339887498948482045868343656381177203091798057628621354486227052604628189024497072072041893911374);
183 template<typename eT> const eT Datum<eT>::sqrt2       = eT(1.4142135623730950488016887242096980785696718753769480731766797379907324784621070388503875343276415727);
184 template<typename eT> const eT Datum<eT>::sqrt2pi     = eT(2.5066282746310005024157652848110452530069867406099383166299235763422936546078419749465958383780572661);
185 template<typename eT> const eT Datum<eT>::log_sqrt2pi = eT(0.9189385332046727417803297364056176398613974736377834128171515404827656959272603976947432986359541976);
186 template<typename eT> const eT Datum<eT>::eps         = std::numeric_limits<eT>::epsilon();
187 template<typename eT> const eT Datum<eT>::log_min     = std::log(std::numeric_limits<eT>::min());
188 template<typename eT> const eT Datum<eT>::log_max     = std::log(std::numeric_limits<eT>::max());
189 template<typename eT> const eT Datum<eT>::nan         = priv::Datum_helper::nan<eT>();
190 template<typename eT> const eT Datum<eT>::inf         = priv::Datum_helper::inf<eT>();
191 
192 template<typename eT> const eT Datum<eT>::m_u       = eT(1.66053906660e-27);
193 template<typename eT> const eT Datum<eT>::N_A       = eT(6.02214076e23);
194 template<typename eT> const eT Datum<eT>::k         = eT(1.380649e-23);
195 template<typename eT> const eT Datum<eT>::k_evk     = eT(8.617333262e-5);
196 template<typename eT> const eT Datum<eT>::a_0       = eT(5.29177210903e-11);
197 template<typename eT> const eT Datum<eT>::mu_B      = eT(9.2740100783e-24);
198 template<typename eT> const eT Datum<eT>::Z_0       = eT(376.730313668);
199 template<typename eT> const eT Datum<eT>::G_0       = eT(7.748091729e-5);
200 template<typename eT> const eT Datum<eT>::k_e       = eT(8.9875517923e9);
201 template<typename eT> const eT Datum<eT>::eps_0     = eT(8.8541878128e-12);
202 template<typename eT> const eT Datum<eT>::m_e       = eT(9.1093837015e-31);
203 template<typename eT> const eT Datum<eT>::eV        = eT(1.602176634e-19);
204 template<typename eT> const eT Datum<eT>::ec        = eT(1.602176634e-19);
205 template<typename eT> const eT Datum<eT>::F         = eT(96485.33212);
206 template<typename eT> const eT Datum<eT>::alpha     = eT(7.2973525693e-3);
207 template<typename eT> const eT Datum<eT>::alpha_inv = eT(137.035999084);
208 template<typename eT> const eT Datum<eT>::K_J       = eT(483597.8484e9);
209 template<typename eT> const eT Datum<eT>::mu_0      = eT(1.25663706212e-6);
210 template<typename eT> const eT Datum<eT>::phi_0     = eT(2.067833848e-15);
211 template<typename eT> const eT Datum<eT>::R         = eT(8.314462618);
212 template<typename eT> const eT Datum<eT>::G         = eT(6.67430e-11);
213 template<typename eT> const eT Datum<eT>::h         = eT(6.62607015e-34);
214 template<typename eT> const eT Datum<eT>::h_bar     = eT(1.054571817e-34);
215 template<typename eT> const eT Datum<eT>::m_p       = eT(1.67262192369e-27);
216 template<typename eT> const eT Datum<eT>::R_inf     = eT(10973731.568160);
217 template<typename eT> const eT Datum<eT>::c_0       = eT(299792458.0);
218 template<typename eT> const eT Datum<eT>::sigma     = eT(5.670374419e-8);
219 template<typename eT> const eT Datum<eT>::R_k       = eT(25812.80745);
220 template<typename eT> const eT Datum<eT>::b         = eT(2.897771955e-3);
221 
222 
223 
224 typedef Datum<float>  fdatum;
225 typedef Datum<double> datum;
226 
227 
228 
229 
230 namespace priv
231   {
232 
233   template<typename eT>
234   static
235   constexpr
236   typename arma_real_only<eT>::result
most_neg()237   most_neg()
238     {
239     return (std::numeric_limits<eT>::has_infinity) ? -(std::numeric_limits<eT>::infinity()) : std::numeric_limits<eT>::lowest();
240     }
241 
242 
243   template<typename eT>
244   static
245   constexpr
246   typename arma_integral_only<eT>::result
most_neg()247   most_neg()
248     {
249     return std::numeric_limits<eT>::lowest();
250     }
251 
252 
253   template<typename eT>
254   static
255   constexpr
256   typename arma_real_only<eT>::result
most_pos()257   most_pos()
258     {
259     return (std::numeric_limits<eT>::has_infinity) ? std::numeric_limits<eT>::infinity() : std::numeric_limits<eT>::max();
260     }
261 
262 
263   template<typename eT>
264   static
265   constexpr
266   typename arma_integral_only<eT>::result
most_pos()267   most_pos()
268     {
269     return std::numeric_limits<eT>::max();
270     }
271 
272   }
273 
274 
275 
276 //! @}
277