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