21#ifndef _libint2_include_numeric_h_
22#define _libint2_include_numeric_h_
24#include <libint2/config.h>
39#include <libint2/util/generated/libint2_params.h>
40#include <libint2/util/type_traits.h>
45inline mpf_class exp(mpf_class x) {
46 const auto prec = x.get_prec();
48 mpfr_init2(x_r, prec);
49 mpfr_set_f(x_r, x.get_mpf_t(), MPFR_RNDN);
52 mpfr_init2(expx_r, prec);
53 mpfr_exp(expx_r, x_r, MPFR_RNDN);
56 mpf_init2(expx, prec);
57 mpfr_get_f(expx, expx_r, MPFR_RNDN);
58 mpf_class result(expx, prec);
68inline mpf_class pow(mpf_class x,
int a) {
69 const auto prec = x.get_prec();
71 mpf_init2(x_to_a, prec);
73 mpf_pow_ui(x_to_a, x.get_mpf_t(), (
unsigned int)a);
75 mpf_pow_ui(x_to_a, x.get_mpf_t(), (
unsigned int)(-a));
76 mpf_class result(x_to_a, prec);
77 if (a < 0) result = 1.0 / result;
84inline double pow(
double x,
int a) {
85 return std::pow(x,
static_cast<double>(a));
90inline mpf_class erf(mpf_class x) {
91 const auto prec = x.get_prec();
93 mpfr_init2(x_r, prec);
94 mpfr_set_f(x_r, x.get_mpf_t(), MPFR_RNDN);
97 mpfr_init2(erfx_r, prec);
98 mpfr_erf(erfx_r, x_r, MPFR_RNDN);
101 mpf_init2(erfx, prec);
102 mpfr_get_f(erfx, erfx_r, MPFR_RNDN);
103 mpf_class result(erfx, prec);
113inline mpf_class acos(mpf_class x) {
114 const auto prec = x.get_prec();
116 mpfr_init2(x_r, prec);
117 mpfr_set_f(x_r, x.get_mpf_t(), MPFR_RNDN);
120 mpfr_init2(acosx_r, prec);
121 mpfr_acos(acosx_r, x_r, MPFR_RNDN);
124 mpf_init2(acosx, prec);
125 mpfr_get_f(acosx, acosx_r, MPFR_RNDN);
126 mpf_class result(acosx, prec);
136inline mpf_class log(mpf_class x) {
137 const auto prec = x.get_prec();
139 mpfr_init2(x_r, prec);
140 mpfr_set_f(x_r, x.get_mpf_t(), MPFR_RNDN);
143 mpfr_init2(logx_r, prec);
144 mpfr_log(logx_r, x_r, MPFR_RNDN);
147 mpf_init2(logx, prec);
148 mpfr_get_f(logx, logx_r, MPFR_RNDN);
149 mpf_class result(logx, prec);
159#ifdef LIBINT_HAS_MPFR
160using LIBINT2_REF_REALTYPE = mpf_class;
162using LIBINT2_REF_REALTYPE = double;
166using value_type = LIBINT2_REALTYPE;
167using scalar_type = libint2::vector_traits<value_type>::scalar_type;
169template <
typename Real>
170inline Real get_epsilon(
const Real& value);
172#ifdef LIBINT_HAS_MPFR
174inline mpf_class get_epsilon(
const mpf_class& value) {
175 const auto nbits = value.get_prec();
176 return pow(mpf_class(2, nbits), -nbits);
180template <
typename Real>
181inline Real get_epsilon(
const Real& value) {
182 return std::numeric_limits<Real>::epsilon();
185template <
typename Real>
186inline int get_max_digits10(
const Real& value);
188#ifdef LIBINT_HAS_MPFR
190inline int get_max_digits10(
const mpf_class& value) {
191 const auto nbits = value.get_prec();
192 return std::ceil(nbits * std::log10(2) + 1);
196template <
typename Real>
197inline int get_max_digits10(
const Real& value) {
198 return std::numeric_limits<Real>::max_digits10;
201template <
typename To,
typename From>
202typename std::enable_if<!std::is_same<typename std::decay<To>::type,
203 typename std::decay<From>::type>::value,
205sstream_convert(From&& from) {
206 std::stringstream ss;
207 ss << std::scientific << std::setprecision(get_max_digits10(from)) << from;
208 To to(ss.str().c_str());
212template <
typename To>
213To sstream_convert(
const To& from) {
Defaults definitions for various parameters assumed by Libint.
Definition algebra.cc:24