From 032070a4dffdf1bf88abde707b6282ce51c40e77 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Sat, 10 Mar 2018 20:23:51 +0000 Subject: [PATCH] complex/mpc: more or less complete the transcendental functions. --- .../multiprecision/detail/default_ops.hpp | 13 ++ include/boost/multiprecision/mpc.hpp | 197 +++--------------- test/test_arithmetic.hpp | 19 ++ 3 files changed, 57 insertions(+), 172 deletions(-) diff --git a/include/boost/multiprecision/detail/default_ops.hpp b/include/boost/multiprecision/detail/default_ops.hpp index fa604b81..57723ec9 100644 --- a/include/boost/multiprecision/detail/default_ops.hpp +++ b/include/boost/multiprecision/detail/default_ops.hpp @@ -1493,6 +1493,13 @@ template typename enable_if_c::type eval_ldexp(); template typename enable_if_c::type eval_frexp(); +// TODO implement default versions of these: +template +typename enable_if_c::type eval_asinh(); +template +typename enable_if_c::type eval_acosh(); +template +typename enable_if_c::type eval_atanh(); // // eval_logb and eval_scalbn simply assume base 2 and forward to @@ -3200,6 +3207,12 @@ UNARY_OP_FUNCTOR(tan, number_kind_complex) UNARY_OP_FUNCTOR(asin, number_kind_complex) UNARY_OP_FUNCTOR(acos, number_kind_complex) UNARY_OP_FUNCTOR(atan, number_kind_complex) +UNARY_OP_FUNCTOR(sinh, number_kind_complex) +UNARY_OP_FUNCTOR(cosh, number_kind_complex) +UNARY_OP_FUNCTOR(tanh, number_kind_complex) +UNARY_OP_FUNCTOR(asinh, number_kind_complex) +UNARY_OP_FUNCTOR(acosh, number_kind_complex) +UNARY_OP_FUNCTOR(atanh, number_kind_complex) // // Integer functions: diff --git a/include/boost/multiprecision/mpc.hpp b/include/boost/multiprecision/mpc.hpp index 907d3d1d..65d9c741 100644 --- a/include/boost/multiprecision/mpc.hpp +++ b/include/boost/multiprecision/mpc.hpp @@ -6,15 +6,13 @@ #ifndef BOOST_MULTIPRECISION_MPC_HPP #define BOOST_MULTIPRECISION_MPC_HPP -#include #include -#include #include -#include #include #include -#include -#include +#include +#include +#include #include #include #include @@ -850,28 +848,40 @@ inline void eval_atan(mpc_float_backend& result, const mpc_float_backe mpc_atan(result.data(), arg.data(), GMP_RNDN); } -template -inline void eval_atan2(mpc_float_backend& result, const mpc_float_backend& arg1, const mpc_float_backend& arg2) -{ - mpc_atan2(result.data(), arg1.data(), arg2.data()); -} - template inline void eval_sinh(mpc_float_backend& result, const mpc_float_backend& arg) { - mpc_sinh(result.data(), arg.data()); + mpc_sinh(result.data(), arg.data(), GMP_RNDN); } template inline void eval_cosh(mpc_float_backend& result, const mpc_float_backend& arg) { - mpc_cosh(result.data(), arg.data()); + mpc_cosh(result.data(), arg.data(), GMP_RNDN); } template inline void eval_tanh(mpc_float_backend& result, const mpc_float_backend& arg) { - mpc_tanh(result.data(), arg.data()); + mpc_tanh(result.data(), arg.data(), GMP_RNDN); +} + +template +inline void eval_asinh(mpc_float_backend& result, const mpc_float_backend& arg) +{ + mpc_asinh(result.data(), arg.data(), GMP_RNDN); +} + +template +inline void eval_acosh(mpc_float_backend& result, const mpc_float_backend& arg) +{ + mpc_acosh(result.data(), arg.data(), GMP_RNDN); +} + +template +inline void eval_atanh(mpc_float_backend& result, const mpc_float_backend& arg) +{ + mpc_atanh(result.data(), arg.data(), GMP_RNDN); } template @@ -946,165 +956,8 @@ inline typename component_type -inline int digits() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpc_float::default_precision()); -} -template <> -inline int digits, boost::multiprecision::et_off> >() -#ifdef BOOST_MATH_NOEXCEPT - BOOST_NOEXCEPT -#endif -{ - return multiprecision::detail::digits10_2_2(boost::multiprecision::mpc_float::default_precision()); -} - -} // namespace tools - -namespace constants{ namespace detail{ - -template struct constant_pi; -template struct constant_ln_two; -template struct constant_euler; -template struct constant_catalan; - -// -// Initializer: ensure all our constants are initialized prior to the first call of main: -// -template -struct mpc_initializer -{ - struct init - { - init() - { - boost::math::constants::pi(); - boost::math::constants::ln_two(); - boost::math::constants::euler(); - boost::math::constants::catalan(); - } - void force_instantiate()const{} - }; - static const init initializer; - static void force_instantiate() - { - initializer.force_instantiate(); - } -}; - -template -const typename mpc_initializer::init mpc_initializer::initializer; - -template -struct constant_pi, ExpressionTemplates> > -{ - typedef boost::multiprecision::number, ExpressionTemplates> result_type; - template - static inline const result_type& get(const mpl::int_&) - { - mpc_initializer::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpc_const_pi(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpc_const_pi(result.backend().data()); - return result; - } -}; -template -struct constant_ln_two, ExpressionTemplates> > -{ - typedef boost::multiprecision::number, ExpressionTemplates> result_type; - template - static inline const result_type& get(const mpl::int_&) - { - mpc_initializer::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpc_const_log2(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpc_const_log2(result.backend().data()); - return result; - } -}; -template -struct constant_euler, ExpressionTemplates> > -{ - typedef boost::multiprecision::number, ExpressionTemplates> result_type; - template - static inline result_type const& get(const mpl::int_&) - { - mpc_initializer::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpc_const_euler(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpc_const_euler(result.backend().data()); - return result; - } -}; -template -struct constant_catalan, ExpressionTemplates> > -{ - typedef boost::multiprecision::number, ExpressionTemplates> result_type; - template - static inline result_type const& get(const mpl::int_&) - { - mpc_initializer::force_instantiate(); - static result_type result; - static bool has_init = false; - if(!has_init) - { - has_init = true; - mpc_const_catalan(result.backend().data()); - } - return result; - } - static inline result_type get(const mpl::int_<0>&) - { - result_type result; - mpc_const_catalan(result.backend().data()); - return result; - } -}; - -}} // namespaces - -}} // namespaces +} // namespaces #endif diff --git a/test/test_arithmetic.hpp b/test/test_arithmetic.hpp index 1facee73..3b177445 100644 --- a/test/test_arithmetic.hpp +++ b/test/test_arithmetic.hpp @@ -2020,6 +2020,25 @@ typename boost::enable_if_c::value a = atan(c); BOOST_CHECK_CLOSE_FRACTION(real_type("1.409921049596575522530619384460420782588207051908724814771070766475530084440199227135813201495737846771570458568"), real(a), tol); BOOST_CHECK_CLOSE_FRACTION(real_type("0.2290726829685387662958818029420027678625253049770656169479919704951963414344907622560676377741902308144912055002"), imag(a), tol); + + a = sinh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("-3.5905645899857799520125654477948167931949136757293015099986213974178826801534614215227593814301490087307920223"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("0.53092108624851980526704009066067655967277345095149103008706855371803528753067068552935673000832252607835087747"), imag(a), tol); + a = cosh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("-3.7245455049153225654739707032559725286749657732153307267858945686649501059065292889110148294141744084833329553"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("0.51182256998738460883446384980187563424555660949074386745538379123585339045741119409984041226187262097496424111"), imag(a), tol); + a = tanh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("0.965385879022133124278480269394560685879729650005757773636908240066639772853967550095754361348005358178253777920"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("-0.00988437503832249372031403430350121097961813353467039031861010606115560355679254344335582852193041894874685555114"), imag(a), tol); + a = asinh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("1.968637925793096291788665095245498189520731012682010573842811017352748255492485345887875752070076230641308014923"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("0.9646585044076027920454110594995323555197773725073316527132580297155508786089335572049608301897631767195194427315"), imag(a), tol); + a = acosh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("1.983387029916535432347076902894039565014248302909345356125267430944752731616095111727103650117987412058949254132"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("1.000143542473797218521037811954081791915781454591512773957199036332934196716853565071982697727425908742684531873"), imag(a), tol); + a = atanh(c); + BOOST_CHECK_CLOSE_FRACTION(real_type("0.1469466662255297520474327851547159424423449403442452953891851939502023996823900422792744078835711416939934387775"), real(a), tol); + BOOST_CHECK_CLOSE_FRACTION(real_type("1.338972522294493561124193575909144241084316172544492778582005751793809271060233646663717270678614587712809117131"), imag(a), tol); } template