max@0: // Copyright (C) 2008-2010 NICTA (www.nicta.com.au) max@0: // Copyright (C) 2008-2010 Conrad Sanderson max@0: // max@0: // This file is part of the Armadillo C++ library. max@0: // It is provided without any warranty of fitness max@0: // for any purpose. You can redistribute this file max@0: // and/or modify it under the terms of the GNU max@0: // Lesser General Public License (LGPL) as published max@0: // by the Free Software Foundation, either version 3 max@0: // of the License or (at your option) any later version. max@0: // (see http://www.opensource.org/licenses for more info) max@0: max@0: max@0: max@0: //! \addtogroup cmath_wrap max@0: //! @{ max@0: max@0: max@0: max@0: // max@0: // wrappers for isfinite max@0: // max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: bool max@0: arma_isfinite(eT val) max@0: { max@0: arma_ignore(val); max@0: max@0: return true; max@0: } max@0: max@0: max@0: max@0: template<> max@0: arma_inline max@0: bool max@0: arma_isfinite(float x) max@0: { max@0: #if defined(ARMA_HAVE_STD_ISFINITE) max@0: { max@0: return (std::isfinite(x) != 0); max@0: } max@0: #else max@0: { max@0: const bool x_is_inf = ( (x == x) && ((x - x) != float(0)) ); max@0: const bool x_is_nan = (x != x); max@0: max@0: return ( (x_is_inf == false) && (x_is_nan == false) ); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template<> max@0: arma_inline max@0: bool max@0: arma_isfinite(double x) max@0: { max@0: #if defined(ARMA_HAVE_STD_ISFINITE) max@0: { max@0: return (std::isfinite(x) != 0); max@0: } max@0: #else max@0: { max@0: const bool x_is_inf = ( (x == x) && ((x - x) != double(0)) ); max@0: const bool x_is_nan = (x != x); max@0: max@0: return ( (x_is_inf == false) && (x_is_nan == false) ); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: bool max@0: arma_isfinite(const std::complex& x) max@0: { max@0: if( (arma_isfinite(x.real()) == false) || (arma_isfinite(x.imag()) == false) ) max@0: { max@0: return false; max@0: } max@0: else max@0: { max@0: return true; max@0: } max@0: } max@0: max@0: max@0: max@0: // max@0: // wrappers for trigonometric functions max@0: // max@0: max@0: max@0: max@0: // Wherever possible, try to use TR1 versions of the functions below, max@0: // otherwise fall back to Boost Math. max@0: // max@0: // complex acos max@0: // complex asin max@0: // complex atan max@0: // max@0: // real acosh max@0: // real asinh max@0: // real atanh max@0: // max@0: // complex acosh max@0: // complex asinh max@0: // complex atanh max@0: // max@0: // max@0: // If TR1 not present and Boost math not present, max@0: // we have our own rudimentary versions of: max@0: // max@0: // real acosh max@0: // real asinh max@0: // real atanh max@0: max@0: max@0: max@0: #if defined(ARMA_USE_BOOST) max@0: #define arma_boost_wrap(trig_fn, val) ( (boost::math::trig_fn)(val) ) max@0: #else max@0: #define arma_boost_wrap(trig_fn, val) ( arma_stop( #trig_fn "(): need Boost libraries" ), val ) max@0: #endif max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_acos(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::acos(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(acos, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_asin(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::asin(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(asin, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_atan(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::atan(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(atan, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: eT max@0: arma_acosh(const eT x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::acosh(x); max@0: } max@0: #elif defined(ARMA_USE_BOOST) max@0: { max@0: return boost::math::acosh(x); max@0: } max@0: #else max@0: { max@0: if(x >= eT(1)) max@0: { max@0: // http://functions.wolfram.com/ElementaryFunctions/ArcCosh/02/ max@0: return std::log( x + std::sqrt(x*x - eT(1)) ); max@0: } max@0: else max@0: { max@0: if(std::numeric_limits::has_quiet_NaN == true) max@0: { max@0: return -(std::numeric_limits::quiet_NaN()); max@0: } max@0: else max@0: { max@0: return eT(0); max@0: } max@0: } max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: eT max@0: arma_asinh(const eT x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::asinh(x); max@0: } max@0: #elif defined(ARMA_USE_BOOST) max@0: { max@0: return boost::math::asinh(x); max@0: } max@0: #else max@0: { max@0: // http://functions.wolfram.com/ElementaryFunctions/ArcSinh/02/ max@0: return std::log( x + std::sqrt(x*x + eT(1)) ); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: eT max@0: arma_atanh(const eT x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::atanh(x); max@0: } max@0: #elif defined(ARMA_USE_BOOST) max@0: { max@0: return boost::math::atanh(x); max@0: } max@0: #else max@0: { max@0: if( (x >= eT(-1)) && (x <= eT(+1)) ) max@0: { max@0: // http://functions.wolfram.com/ElementaryFunctions/ArcTanh/02/ max@0: return std::log( ( eT(1)+x ) / ( eT(1)-x ) ) / eT(2); max@0: } max@0: else max@0: { max@0: if(std::numeric_limits::has_quiet_NaN == true) max@0: { max@0: return -(std::numeric_limits::quiet_NaN()); max@0: } max@0: else max@0: { max@0: return eT(0); max@0: } max@0: } max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_acosh(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::acosh(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(acosh, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_asinh(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::asinh(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(asinh, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: template max@0: arma_inline max@0: std::complex max@0: arma_atanh(const std::complex& x) max@0: { max@0: #if defined(ARMA_HAVE_STD_TR1) max@0: { max@0: return std::tr1::atanh(x); max@0: } max@0: #else max@0: { max@0: return arma_boost_wrap(atanh, x); max@0: } max@0: #endif max@0: } max@0: max@0: max@0: max@0: #undef arma_boost_wrap max@0: max@0: max@0: max@0: //! @}