comparison armadillo-3.900.4/include/armadillo_bits/cmath_wrap.hpp @ 49:1ec0e2823891

Switch to using subrepo copies of qm-dsp, nnls-chroma, vamp-plugin-sdk; update Armadillo version; assume build without external BLAS/LAPACK
author Chris Cannam
date Thu, 13 Jun 2013 10:25:24 +0100
parents
children
comparison
equal deleted inserted replaced
48:69251e11a913 49:1ec0e2823891
1 // Copyright (C) 2008-2010 NICTA (www.nicta.com.au)
2 // Copyright (C) 2008-2010 Conrad Sanderson
3 //
4 // This Source Code Form is subject to the terms of the Mozilla Public
5 // License, v. 2.0. If a copy of the MPL was not distributed with this
6 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
7
8
9
10 //! \addtogroup cmath_wrap
11 //! @{
12
13
14
15 //
16 // wrappers for isfinite
17 //
18
19
20
21 template<typename eT>
22 arma_inline
23 bool
24 arma_isfinite(eT val)
25 {
26 arma_ignore(val);
27
28 return true;
29 }
30
31
32
33 template<>
34 arma_inline
35 bool
36 arma_isfinite(float x)
37 {
38 #if defined(ARMA_HAVE_STD_ISFINITE)
39 {
40 return (std::isfinite(x) != 0);
41 }
42 #else
43 {
44 const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) );
45 const bool x_is_nan = (x != x);
46
47 return ( (x_is_inf == false) && (x_is_nan == false) );
48 }
49 #endif
50 }
51
52
53
54 template<>
55 arma_inline
56 bool
57 arma_isfinite(double x)
58 {
59 #if defined(ARMA_HAVE_STD_ISFINITE)
60 {
61 return (std::isfinite(x) != 0);
62 }
63 #else
64 {
65 const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) );
66 const bool x_is_nan = (x != x);
67
68 return ( (x_is_inf == false) && (x_is_nan == false) );
69 }
70 #endif
71 }
72
73
74
75 template<typename T>
76 arma_inline
77 bool
78 arma_isfinite(const std::complex<T>& x)
79 {
80 if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) )
81 {
82 return false;
83 }
84 else
85 {
86 return true;
87 }
88 }
89
90
91
92 //
93 // wrappers for trigonometric functions
94 //
95
96
97
98 // Wherever possible, try to use TR1 versions of the functions below,
99 // otherwise fall back to Boost Math.
100 //
101 // complex acos
102 // complex asin
103 // complex atan
104 //
105 // real acosh
106 // real asinh
107 // real atanh
108 //
109 // complex acosh
110 // complex asinh
111 // complex atanh
112 //
113 //
114 // If TR1 not present and Boost math not present,
115 // we have our own rudimentary versions of:
116 //
117 // real acosh
118 // real asinh
119 // real atanh
120
121
122
123 #if defined(ARMA_USE_BOOST)
124 #define arma_boost_wrap(trig_fn, val) ( (boost::math::trig_fn)(val) )
125 #else
126 #define arma_boost_wrap(trig_fn, val) ( arma_stop( #trig_fn "(): need Boost libraries" ), val )
127 #endif
128
129
130 template<typename T>
131 arma_inline
132 std::complex<T>
133 arma_acos(const std::complex<T>& x)
134 {
135 #if defined(ARMA_HAVE_STD_TR1)
136 {
137 return std::tr1::acos(x);
138 }
139 #else
140 {
141 return arma_boost_wrap(acos, x);
142 }
143 #endif
144 }
145
146
147
148 template<typename T>
149 arma_inline
150 std::complex<T>
151 arma_asin(const std::complex<T>& x)
152 {
153 #if defined(ARMA_HAVE_STD_TR1)
154 {
155 return std::tr1::asin(x);
156 }
157 #else
158 {
159 return arma_boost_wrap(asin, x);
160 }
161 #endif
162 }
163
164
165
166 template<typename T>
167 arma_inline
168 std::complex<T>
169 arma_atan(const std::complex<T>& x)
170 {
171 #if defined(ARMA_HAVE_STD_TR1)
172 {
173 return std::tr1::atan(x);
174 }
175 #else
176 {
177 return arma_boost_wrap(atan, x);
178 }
179 #endif
180 }
181
182
183
184 template<typename eT>
185 arma_inline
186 eT
187 arma_acosh(const eT x)
188 {
189 #if defined(ARMA_HAVE_STD_TR1)
190 {
191 return std::tr1::acosh(x);
192 }
193 #elif defined(ARMA_USE_BOOST)
194 {
195 return boost::math::acosh(x);
196 }
197 #else
198 {
199 if(x >= eT(1))
200 {
201 // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/
202 return std::log( x + std::sqrt(x*x - eT(1)) );
203 }
204 else
205 {
206 if(std::numeric_limits<eT>::has_quiet_NaN == true)
207 {
208 return -(std::numeric_limits<eT>::quiet_NaN());
209 }
210 else
211 {
212 return eT(0);
213 }
214 }
215 }
216 #endif
217 }
218
219
220
221 template<typename eT>
222 arma_inline
223 eT
224 arma_asinh(const eT x)
225 {
226 #if defined(ARMA_HAVE_STD_TR1)
227 {
228 return std::tr1::asinh(x);
229 }
230 #elif defined(ARMA_USE_BOOST)
231 {
232 return boost::math::asinh(x);
233 }
234 #else
235 {
236 // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/
237 return std::log( x + std::sqrt(x*x + eT(1)) );
238 }
239 #endif
240 }
241
242
243
244 template<typename eT>
245 arma_inline
246 eT
247 arma_atanh(const eT x)
248 {
249 #if defined(ARMA_HAVE_STD_TR1)
250 {
251 return std::tr1::atanh(x);
252 }
253 #elif defined(ARMA_USE_BOOST)
254 {
255 return boost::math::atanh(x);
256 }
257 #else
258 {
259 if( (x >= eT(-1)) && (x <= eT(+1)) )
260 {
261 // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/
262 return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2);
263 }
264 else
265 {
266 if(std::numeric_limits<eT>::has_quiet_NaN == true)
267 {
268 return -(std::numeric_limits<eT>::quiet_NaN());
269 }
270 else
271 {
272 return eT(0);
273 }
274 }
275 }
276 #endif
277 }
278
279
280
281 template<typename T>
282 arma_inline
283 std::complex<T>
284 arma_acosh(const std::complex<T>& x)
285 {
286 #if defined(ARMA_HAVE_STD_TR1)
287 {
288 return std::tr1::acosh(x);
289 }
290 #else
291 {
292 return arma_boost_wrap(acosh, x);
293 }
294 #endif
295 }
296
297
298
299 template<typename T>
300 arma_inline
301 std::complex<T>
302 arma_asinh(const std::complex<T>& x)
303 {
304 #if defined(ARMA_HAVE_STD_TR1)
305 {
306 return std::tr1::asinh(x);
307 }
308 #else
309 {
310 return arma_boost_wrap(asinh, x);
311 }
312 #endif
313 }
314
315
316
317 template<typename T>
318 arma_inline
319 std::complex<T>
320 arma_atanh(const std::complex<T>& x)
321 {
322 #if defined(ARMA_HAVE_STD_TR1)
323 {
324 return std::tr1::atanh(x);
325 }
326 #else
327 {
328 return arma_boost_wrap(atanh, x);
329 }
330 #endif
331 }
332
333
334
335 #undef arma_boost_wrap
336
337
338
339 //! @}