From 2406529f5ceb193a46b1b5a07a8810880a8ceceb Mon Sep 17 00:00:00 2001 From: Alexei Sheplyakov Date: Wed, 19 Mar 2008 12:24:36 +0300 Subject: [PATCH 1/1] inifcns_nstdsums.cpp: S_num takes cl_N as an argument instead of numeric. Implicit conversion from cl_N to numeric considered harmful. Using GiNaC::numeric for numerical computations incurs significant overhead, so one might want to do these computations using proper CLN types. Unfortunately, it's not easy due to automatic conversion from cln::cl_N to GiNaC::numeric. Here is a simple example: cl_N x, y; // initialize them return sin(x) + y*exp(y); The compiler complains about ambigously overloaded of functions, i.e. cl_N cln::sin(const cl_N&) versus numeric GiNaC::sin(const numeric&). Hence, I propose to disable *implicit* conversion from cl_N to numeric (this can be done by marking the numeric ctor as `explicit'). However, this change happens to be a bit nontrivial, because that evil conversion is used in GiNaC itself. So, I decided to rewrite those fragments of code. --- ginac/inifcns_nstdsums.cpp | 50 +++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/ginac/inifcns_nstdsums.cpp b/ginac/inifcns_nstdsums.cpp index 43add280..bd61fd30 100644 --- a/ginac/inifcns_nstdsums.cpp +++ b/ginac/inifcns_nstdsums.cpp @@ -320,7 +320,7 @@ cln::cl_N Lin_do_sum_Xn(int n, const cln::cl_N& x) // forward declaration needed by function Li_projection and C below -numeric S_num(int n, int p, const numeric& x); +const cln::cl_N S_num(int n, int p, const cln::cl_N& x); // helper function for classical polylog Li @@ -371,7 +371,7 @@ cln::cl_N Li_projection(int n, const cln::cl_N& x, const cln::float_format_t& pr } else { cln::cl_N result = -cln::expt(cln::log(x), n-1) * cln::log(1-x) / cln::factorial(n-1); for (int j=0; j(x).to_cl_N(); cln::cl_N result = -cln::expt(cln::log(x_), n-1) * cln::log(1-x_) / cln::factorial(n-1); for (int j=0; j(cln::realpart(value))); - else if (!x.imag().is_rational()) + else if (!instanceof(imagpart(value), cln::cl_RA_ring)) prec = cln::float_format(cln::the(cln::imagpart(value))); // [Kol] (5.3) @@ -1934,9 +1934,9 @@ numeric S_num(int n, int p, const numeric& x) cln::cl_N res2; for (int r=0; r(n).to_int(); + const int p_ = ex_to(p).to_int(); if (is_a(x)) { - return S_num(ex_to(n).to_int(), ex_to(p).to_int(), ex_to(x)); + const cln::cl_N x_ = ex_to(x).to_cl_N(); + const cln::cl_N result = S_num(n_, p_, x_); + return numeric(result); } else { ex x_val = x.evalf(); if (is_a(x_val)) { - return S_num(ex_to(n).to_int(), ex_to(p).to_int(), ex_to(x_val)); + const cln::cl_N x_val_ = ex_to(x_val).to_cl_N(); + const cln::cl_N result = S_num(n_, p_, x_val_); + return numeric(result); } } } @@ -2017,7 +2023,11 @@ static ex S_eval(const ex& n, const ex& p, const ex& x) return Li(n+1, x); } if (x.info(info_flags::numeric) && (!x.info(info_flags::crational))) { - return S_num(ex_to(n).to_int(), ex_to(p).to_int(), ex_to(x)); + int n_ = ex_to(n).to_int(); + int p_ = ex_to(p).to_int(); + const cln::cl_N x_ = ex_to(x).to_cl_N(); + const cln::cl_N result = S_num(n_, p_, x_); + return numeric(result); } } if (n.is_zero()) { -- 2.44.0