$search
00001 // Copyright (C) 2008-2010 NICTA (www.nicta.com.au) 00002 // Copyright (C) 2008-2010 Conrad Sanderson 00003 // 00004 // This file is part of the Armadillo C++ library. 00005 // It is provided without any warranty of fitness 00006 // for any purpose. You can redistribute this file 00007 // and/or modify it under the terms of the GNU 00008 // Lesser General Public License (LGPL) as published 00009 // by the Free Software Foundation, either version 3 00010 // of the License or (at your option) any later version. 00011 // (see http://www.opensource.org/licenses for more info) 00012 00013 00014 00017 00018 00019 00020 // 00021 // wrappers for isfinite 00022 // 00023 00024 00025 00026 template<typename eT> 00027 arma_inline 00028 bool 00029 arma_isfinite(eT val) 00030 { 00031 arma_ignore(val); 00032 00033 return true; 00034 } 00035 00036 00037 00038 template<> 00039 arma_inline 00040 bool 00041 arma_isfinite(float x) 00042 { 00043 #if defined(ARMA_HAVE_STD_ISFINITE) 00044 { 00045 return (std::isfinite(x) != 0); 00046 } 00047 #else 00048 { 00049 const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) ); 00050 const bool x_is_nan = (x != x); 00051 00052 return ( (x_is_inf == false) && (x_is_nan == false) ); 00053 } 00054 #endif 00055 } 00056 00057 00058 00059 template<> 00060 arma_inline 00061 bool 00062 arma_isfinite(double x) 00063 { 00064 #if defined(ARMA_HAVE_STD_ISFINITE) 00065 { 00066 return (std::isfinite(x) != 0); 00067 } 00068 #else 00069 { 00070 const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) ); 00071 const bool x_is_nan = (x != x); 00072 00073 return ( (x_is_inf == false) && (x_is_nan == false) ); 00074 } 00075 #endif 00076 } 00077 00078 00079 00080 template<typename T> 00081 arma_inline 00082 bool 00083 arma_isfinite(const std::complex<T>& x) 00084 { 00085 if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) ) 00086 { 00087 return false; 00088 } 00089 else 00090 { 00091 return true; 00092 } 00093 } 00094 00095 00096 00097 // 00098 // wrappers for trigonometric functions 00099 // 00100 00101 00102 00103 // Wherever possible, try to use TR1 versions of the functions below, 00104 // otherwise fall back to Boost Math. 00105 // 00106 // complex acos 00107 // complex asin 00108 // complex atan 00109 // 00110 // real acosh 00111 // real asinh 00112 // real atanh 00113 // 00114 // complex acosh 00115 // complex asinh 00116 // complex atanh 00117 // 00118 // 00119 // If TR1 not present and Boost math not present, 00120 // we have our own rudimentary versions of: 00121 // 00122 // real acosh 00123 // real asinh 00124 // real atanh 00125 00126 00127 00128 #if defined(ARMA_USE_BOOST) 00129 #define arma_boost_wrap(trig_fn, val) ( (boost::math::trig_fn)(val) ) 00130 #else 00131 #define arma_boost_wrap(trig_fn, val) ( arma_stop( #trig_fn "(): need Boost libraries" ), val ) 00132 #endif 00133 00134 00135 template<typename T> 00136 arma_inline 00137 std::complex<T> 00138 arma_acos(const std::complex<T>& x) 00139 { 00140 #if defined(ARMA_HAVE_STD_TR1) 00141 { 00142 return std::tr1::acos(x); 00143 } 00144 #else 00145 { 00146 return arma_boost_wrap(acos, x); 00147 } 00148 #endif 00149 } 00150 00151 00152 00153 template<typename T> 00154 arma_inline 00155 std::complex<T> 00156 arma_asin(const std::complex<T>& x) 00157 { 00158 #if defined(ARMA_HAVE_STD_TR1) 00159 { 00160 return std::tr1::asin(x); 00161 } 00162 #else 00163 { 00164 return arma_boost_wrap(asin, x); 00165 } 00166 #endif 00167 } 00168 00169 00170 00171 template<typename T> 00172 arma_inline 00173 std::complex<T> 00174 arma_atan(const std::complex<T>& x) 00175 { 00176 #if defined(ARMA_HAVE_STD_TR1) 00177 { 00178 return std::tr1::atan(x); 00179 } 00180 #else 00181 { 00182 return arma_boost_wrap(atan, x); 00183 } 00184 #endif 00185 } 00186 00187 00188 00189 template<typename eT> 00190 arma_inline 00191 eT 00192 arma_acosh(const eT x) 00193 { 00194 #if defined(ARMA_HAVE_STD_TR1) 00195 { 00196 return std::tr1::acosh(x); 00197 } 00198 #elif defined(ARMA_USE_BOOST) 00199 { 00200 return boost::math::acosh(x); 00201 } 00202 #else 00203 { 00204 if(x >= eT(1)) 00205 { 00206 // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ 00207 return std::log( x + std::sqrt(x*x - eT(1)) ); 00208 } 00209 else 00210 { 00211 if(std::numeric_limits<eT>::has_quiet_NaN == true) 00212 { 00213 return -(std::numeric_limits<eT>::quiet_NaN()); 00214 } 00215 else 00216 { 00217 return eT(0); 00218 } 00219 } 00220 } 00221 #endif 00222 } 00223 00224 00225 00226 template<typename eT> 00227 arma_inline 00228 eT 00229 arma_asinh(const eT x) 00230 { 00231 #if defined(ARMA_HAVE_STD_TR1) 00232 { 00233 return std::tr1::asinh(x); 00234 } 00235 #elif defined(ARMA_USE_BOOST) 00236 { 00237 return boost::math::asinh(x); 00238 } 00239 #else 00240 { 00241 // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ 00242 return std::log( x + std::sqrt(x*x + eT(1)) ); 00243 } 00244 #endif 00245 } 00246 00247 00248 00249 template<typename eT> 00250 arma_inline 00251 eT 00252 arma_atanh(const eT x) 00253 { 00254 #if defined(ARMA_HAVE_STD_TR1) 00255 { 00256 return std::tr1::atanh(x); 00257 } 00258 #elif defined(ARMA_USE_BOOST) 00259 { 00260 return boost::math::atanh(x); 00261 } 00262 #else 00263 { 00264 if( (x >= eT(-1)) && (x <= eT(+1)) ) 00265 { 00266 // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ 00267 return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2); 00268 } 00269 else 00270 { 00271 if(std::numeric_limits<eT>::has_quiet_NaN == true) 00272 { 00273 return -(std::numeric_limits<eT>::quiet_NaN()); 00274 } 00275 else 00276 { 00277 return eT(0); 00278 } 00279 } 00280 } 00281 #endif 00282 } 00283 00284 00285 00286 template<typename T> 00287 arma_inline 00288 std::complex<T> 00289 arma_acosh(const std::complex<T>& x) 00290 { 00291 #if defined(ARMA_HAVE_STD_TR1) 00292 { 00293 return std::tr1::acosh(x); 00294 } 00295 #else 00296 { 00297 return arma_boost_wrap(acosh, x); 00298 } 00299 #endif 00300 } 00301 00302 00303 00304 template<typename T> 00305 arma_inline 00306 std::complex<T> 00307 arma_asinh(const std::complex<T>& x) 00308 { 00309 #if defined(ARMA_HAVE_STD_TR1) 00310 { 00311 return std::tr1::asinh(x); 00312 } 00313 #else 00314 { 00315 return arma_boost_wrap(asinh, x); 00316 } 00317 #endif 00318 } 00319 00320 00321 00322 template<typename T> 00323 arma_inline 00324 std::complex<T> 00325 arma_atanh(const std::complex<T>& x) 00326 { 00327 #if defined(ARMA_HAVE_STD_TR1) 00328 { 00329 return std::tr1::atanh(x); 00330 } 00331 #else 00332 { 00333 return arma_boost_wrap(atanh, x); 00334 } 00335 #endif 00336 } 00337 00338 00339 00340 #undef arma_boost_wrap 00341 00342 00343