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