mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-18 14:12:32 +00:00
complex/mpc: more or less complete the transcendental functions.
This commit is contained in:
@@ -1493,6 +1493,13 @@ template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_ldexp();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_frexp();
|
||||
// TODO implement default versions of these:
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_asinh();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_acosh();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::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:
|
||||
|
||||
@@ -6,15 +6,13 @@
|
||||
#ifndef BOOST_MULTIPRECISION_MPC_HPP
|
||||
#define BOOST_MULTIPRECISION_MPC_HPP
|
||||
|
||||
#include <boost/multiprecision/mpfi.hpp>
|
||||
#include <boost/multiprecision/number.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/multiprecision/detail/big_lanczos.hpp>
|
||||
#include <boost/multiprecision/detail/digits.hpp>
|
||||
#include <boost/multiprecision/mpfr.hpp>
|
||||
#include <boost/multiprecision/logged_adaptor.hpp>
|
||||
#include <boost/math/constants/constants.hpp>
|
||||
#include <boost/math/special_functions/asinh.hpp>
|
||||
#include <boost/math/special_functions/acosh.hpp>
|
||||
#include <boost/math/special_functions/atanh.hpp>
|
||||
#include <boost/functional/hash_fwd.hpp>
|
||||
#include <mpc.h>
|
||||
#include <cmath>
|
||||
@@ -850,28 +848,40 @@ inline void eval_atan(mpc_float_backend<Digits10>& result, const mpc_float_backe
|
||||
mpc_atan(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_atan2(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg1, const mpc_float_backend<Digits10>& arg2)
|
||||
{
|
||||
mpc_atan2(result.data(), arg1.data(), arg2.data());
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_sinh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_sinh(result.data(), arg.data());
|
||||
mpc_sinh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_cosh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_cosh(result.data(), arg.data());
|
||||
mpc_cosh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_tanh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_tanh(result.data(), arg.data());
|
||||
mpc_tanh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_asinh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_asinh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_acosh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_acosh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_atanh(mpc_float_backend<Digits10>& result, const mpc_float_backend<Digits10>& arg)
|
||||
{
|
||||
mpc_atanh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
@@ -946,165 +956,8 @@ inline typename component_type<boost::multiprecision::number<boost::multiprecisi
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace multiprecision
|
||||
|
||||
namespace math{
|
||||
|
||||
namespace tools{
|
||||
|
||||
template <>
|
||||
inline int digits<boost::multiprecision::mpc_float>()
|
||||
#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::number<boost::multiprecision::mpc_float_backend<0>, 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 <class T> struct constant_pi;
|
||||
template <class T> struct constant_ln_two;
|
||||
template <class T> struct constant_euler;
|
||||
template <class T> struct constant_catalan;
|
||||
|
||||
//
|
||||
// Initializer: ensure all our constants are initialized prior to the first call of main:
|
||||
//
|
||||
template <class T>
|
||||
struct mpc_initializer
|
||||
{
|
||||
struct init
|
||||
{
|
||||
init()
|
||||
{
|
||||
boost::math::constants::pi<T>();
|
||||
boost::math::constants::ln_two<T>();
|
||||
boost::math::constants::euler<T>();
|
||||
boost::math::constants::catalan<T>();
|
||||
}
|
||||
void force_instantiate()const{}
|
||||
};
|
||||
static const init initializer;
|
||||
static void force_instantiate()
|
||||
{
|
||||
initializer.force_instantiate();
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
const typename mpc_initializer<T>::init mpc_initializer<T>::initializer;
|
||||
|
||||
template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >
|
||||
{
|
||||
typedef boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> result_type;
|
||||
template<int N>
|
||||
static inline const result_type& get(const mpl::int_<N>&)
|
||||
{
|
||||
mpc_initializer<result_type>::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<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >
|
||||
{
|
||||
typedef boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> result_type;
|
||||
template<int N>
|
||||
static inline const result_type& get(const mpl::int_<N>&)
|
||||
{
|
||||
mpc_initializer<result_type>::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<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >
|
||||
{
|
||||
typedef boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> result_type;
|
||||
template<int N>
|
||||
static inline result_type const& get(const mpl::int_<N>&)
|
||||
{
|
||||
mpc_initializer<result_type>::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<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
|
||||
struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> >
|
||||
{
|
||||
typedef boost::multiprecision::number<boost::multiprecision::mpc_float_backend<Digits10>, ExpressionTemplates> result_type;
|
||||
template<int N>
|
||||
static inline result_type const& get(const mpl::int_<N>&)
|
||||
{
|
||||
mpc_initializer<result_type>::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
|
||||
|
||||
@@ -2020,6 +2020,25 @@ typename boost::enable_if_c<boost::multiprecision::number_category<Real>::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 <class Real>
|
||||
|
||||
Reference in New Issue
Block a user