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 
20 //! \addtogroup arma_cmath
21 //! @{
22 
23 
24 
25 //
26 // wrappers for isfinite
27 
28 
29 template<typename eT>
30 inline
31 bool
arma_isfinite(eT)32 arma_isfinite(eT)
33   {
34   return true;
35   }
36 
37 
38 
39 template<>
40 inline
41 bool
arma_isfinite(float x)42 arma_isfinite(float x)
43   {
44   return std::isfinite(x);
45   }
46 
47 
48 
49 template<>
50 inline
51 bool
arma_isfinite(double x)52 arma_isfinite(double x)
53   {
54   return std::isfinite(x);
55   }
56 
57 
58 
59 template<typename T>
60 inline
61 bool
arma_isfinite(const std::complex<T> & x)62 arma_isfinite(const std::complex<T>& x)
63   {
64   return ( arma_isfinite(x.real()) && arma_isfinite(x.imag()) );
65   }
66 
67 
68 
69 //
70 // wrappers for isinf
71 
72 
73 template<typename eT>
74 inline
75 bool
arma_isinf(eT)76 arma_isinf(eT)
77   {
78   return false;
79   }
80 
81 
82 
83 template<>
84 inline
85 bool
arma_isinf(float x)86 arma_isinf(float x)
87   {
88   return std::isinf(x);
89   }
90 
91 
92 
93 template<>
94 inline
95 bool
arma_isinf(double x)96 arma_isinf(double x)
97   {
98   return std::isinf(x);
99   }
100 
101 
102 
103 template<typename T>
104 inline
105 bool
arma_isinf(const std::complex<T> & x)106 arma_isinf(const std::complex<T>& x)
107   {
108   return ( arma_isinf(x.real()) || arma_isinf(x.imag()) );
109   }
110 
111 
112 
113 //
114 // wrappers for isnan
115 
116 
117 template<typename eT>
118 inline
119 bool
arma_isnan(eT val)120 arma_isnan(eT val)
121   {
122   arma_ignore(val);
123 
124   return false;
125   }
126 
127 
128 
129 template<>
130 inline
131 bool
arma_isnan(float x)132 arma_isnan(float x)
133   {
134   return std::isnan(x);
135   }
136 
137 
138 
139 template<>
140 inline
141 bool
arma_isnan(double x)142 arma_isnan(double x)
143   {
144   return std::isnan(x);
145   }
146 
147 
148 
149 template<typename T>
150 inline
151 bool
arma_isnan(const std::complex<T> & x)152 arma_isnan(const std::complex<T>& x)
153   {
154   return ( arma_isnan(x.real()) || arma_isnan(x.imag()) );
155   }
156 
157 
158 
159 //
160 // implementation of arma_sign()
161 
162 
163 template<typename eT>
164 constexpr
165 typename arma_unsigned_integral_only<eT>::result
arma_sign(const eT x)166 arma_sign(const eT x)
167   {
168   return (x > eT(0)) ? eT(+1) : eT(0);
169   }
170 
171 
172 
173 template<typename eT>
174 constexpr
175 typename arma_signed_integral_only<eT>::result
arma_sign(const eT x)176 arma_sign(const eT x)
177   {
178   return (x > eT(0)) ? eT(+1) : ( (x < eT(0)) ? eT(-1) : eT(0) );
179   }
180 
181 
182 
183 template<typename eT>
184 constexpr
185 typename arma_real_only<eT>::result
arma_sign(const eT x)186 arma_sign(const eT x)
187   {
188   return (x > eT(0)) ? eT(+1) : ( (x < eT(0)) ? eT(-1) : ((x == eT(0)) ? eT(0) : x) );
189   }
190 
191 
192 
193 template<typename eT>
194 inline
195 typename arma_cx_only<eT>::result
arma_sign(const eT & x)196 arma_sign(const eT& x)
197   {
198   typedef typename eT::value_type T;
199 
200   const T abs_x = std::abs(x);
201 
202   return (abs_x != T(0)) ? (x / abs_x) : x;
203   }
204 
205 
206 
207 //
208 // wrappers for hypot(x, y) = sqrt(x^2 + y^2)
209 
210 
211 template<typename eT>
212 inline
213 eT
arma_hypot(const eT x,const eT y)214 arma_hypot(const eT x, const eT y)
215   {
216   arma_ignore(x);
217   arma_ignore(y);
218 
219   arma_stop_runtime_error("arma_hypot(): not implemented for integer or complex element types");
220 
221   return eT(0);
222   }
223 
224 
225 
226 template<>
227 inline
228 float
arma_hypot(const float x,const float y)229 arma_hypot(const float x, const float y)
230   {
231   return std::hypot(x, y);
232   }
233 
234 
235 
236 template<>
237 inline
238 double
arma_hypot(const double x,const double y)239 arma_hypot(const double x, const double y)
240   {
241   return std::hypot(x, y);
242   }
243 
244 
245 
246 //
247 // implementation of arma_sinc()
248 
249 
250 template<typename eT>
251 inline
252 eT
arma_sinc_generic(const eT x)253 arma_sinc_generic(const eT x)
254   {
255   typedef typename get_pod_type<eT>::result T;
256 
257   const eT tmp = Datum<T>::pi * x;
258 
259   return (tmp == eT(0)) ? eT(1) : eT( std::sin(tmp) / tmp );
260   }
261 
262 
263 
264 template<typename eT>
265 inline
266 eT
arma_sinc(const eT x)267 arma_sinc(const eT x)
268   {
269   return eT( arma_sinc_generic( double(x) ) );
270   }
271 
272 
273 
274 template<>
275 inline
276 float
arma_sinc(const float x)277 arma_sinc(const float x)
278   {
279   return arma_sinc_generic(x);
280   }
281 
282 
283 
284 template<>
285 inline
286 double
arma_sinc(const double x)287 arma_sinc(const double x)
288   {
289   return arma_sinc_generic(x);
290   }
291 
292 
293 
294 template<typename T>
295 inline
296 std::complex<T>
arma_sinc(const std::complex<T> & x)297 arma_sinc(const std::complex<T>& x)
298   {
299   return arma_sinc_generic(x);
300   }
301 
302 
303 
304 //
305 // wrappers for arg()
306 
307 
308 template<typename eT>
309 struct arma_arg
310   {
311   static
312   inline
313   eT
evalarma_arg314   eval(const eT x)
315     {
316     return eT( std::arg(x) );
317     }
318   };
319 
320 
321 
322 template<>
323 struct arma_arg<float>
324   {
325   static
326   inline
327   float
evalarma_arg328   eval(const float x)
329     {
330     return std::arg(x);
331     }
332   };
333 
334 
335 
336 template<>
337 struct arma_arg<double>
338   {
339   static
340   inline
341   double
evalarma_arg342   eval(const double x)
343     {
344     return std::arg(x);
345     }
346   };
347 
348 
349 
350 template<>
351 struct arma_arg< std::complex<float> >
352   {
353   static
354   inline
355   float
evalarma_arg356   eval(const std::complex<float>& x)
357     {
358     return std::arg(x);
359     }
360   };
361 
362 
363 
364 template<>
365 struct arma_arg< std::complex<double> >
366   {
367   static
368   inline
369   double
evalarma_arg370   eval(const std::complex<double>& x)
371     {
372     return std::arg(x);
373     }
374   };
375 
376 
377 
378 //! @}
379