X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Finifcns_nstdsums.cpp;h=4312377f10cf2d868972db41a56dac127973855d;hp=cb5690889656ac64d1ae61ea51b8de4e68caf624;hb=cc94094751459129e1392a93dfa0264adac789a5;hpb=502e76319b484c32246707e33e70a428ac5dc6ad diff --git a/ginac/inifcns_nstdsums.cpp b/ginac/inifcns_nstdsums.cpp index cb569088..4312377f 100644 --- a/ginac/inifcns_nstdsums.cpp +++ b/ginac/inifcns_nstdsums.cpp @@ -47,7 +47,7 @@ */ /* - * GiNaC Copyright (C) 1999-2008 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2010 Johannes Gutenberg University Mainz, Germany * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -64,11 +64,6 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include -#include -#include - #include "inifcns.h" #include "add.h" @@ -84,6 +79,10 @@ #include "utils.h" #include "wildcard.h" +#include +#include +#include +#include namespace GiNaC { @@ -210,7 +209,7 @@ void double_Xn() } } // X_n - for (int n=2; n& s, const std::vector m_int; - std::vector x_cln; - for (lst::const_iterator itm = m.begin(), itx = x.begin(); itm != m.end(); ++itm, ++itx) { - m_int.push_back(ex_to(*itm).to_int()); - x_cln.push_back(ex_to(*itx).to_cl_N()); - } - return multipleLi_do_sum(m_int, x_cln); -} - - // forward declaration for Li_eval() lst convert_parameter_Li_to_H(const lst& m, const lst& x, ex& pf); @@ -583,11 +569,12 @@ ex G_eval(const Gparameter& a, int scale, const exvector& gsyms) Gparameter newa; Gparameter::const_iterator it2 = short_a.begin(); - for (--it2; it2 != it;) { - ++it2; + for (; it2 != it; ++it2) { newa.push_back(*it2); } + newa.push_back(*it); newa.push_back(a[0]); + it2 = it; ++it2; for (; it2 != short_a.end(); ++it2) { newa.push_back(*it2); @@ -672,6 +659,8 @@ Gparameter::const_iterator check_parameter_G(const Gparameter& a, int scale, ++trailing_zeros; } } + if (lastnonzero == a.end()) + return a.end(); return ++lastnonzero; } @@ -992,86 +981,92 @@ ex shuffle_G(const Gparameter & a0, const Gparameter & a1, const Gparameter & a2 // handles the transformations and the numerical evaluation of G // the parameter x, s and y must only contain numerics -ex G_numeric(const lst& x, const lst& s, const ex& y); +static cln::cl_N +G_numeric(const std::vector& x, const std::vector& s, + const cln::cl_N& y); // do acceleration transformation (hoelder convolution [BBB]) // the parameter x, s and y must only contain numerics -ex G_do_hoelder(const lst& x, const lst& s, const ex& y) +static cln::cl_N +G_do_hoelder(std::vector x, /* yes, it's passed by value */ + const std::vector& s, const cln::cl_N& y) { - ex result; - const int size = x.nops(); - lst newx; - for (lst::const_iterator it = x.begin(); it != x.end(); ++it) { - newx.append(*it / y); - } - - for (int r=0; r<=size; ++r) { - ex buffer = pow(-1, r); - ex p = 2; + cln::cl_N result; + const std::size_t size = x.size(); + for (std::size_t i = 0; i < size; ++i) + x[i] = x[i]/y; + + for (std::size_t r = 0; r <= size; ++r) { + cln::cl_N buffer(1 & r ? -1 : 1); + cln::cl_RA p(2); bool adjustp; do { adjustp = false; - for (lst::const_iterator it = newx.begin(); it != newx.end(); ++it) { - if (*it == 1/p) { - p += (3-p)/2; + for (std::size_t i = 0; i < size; ++i) { + if (x[i] == cln::cl_RA(1)/p) { + p = p/2 + cln::cl_RA(3)/2; adjustp = true; continue; } } } while (adjustp); - ex q = p / (p-1); - lst qlstx; - lst qlsts; - for (int j=r; j>=1; --j) { - qlstx.append(1-newx.op(j-1)); - if (newx.op(j-1).info(info_flags::real) && newx.op(j-1) > 1 && newx.op(j-1) <= 2) { - qlsts.append( s.op(j-1)); + cln::cl_RA q = p/(p-1); + std::vector qlstx; + std::vector qlsts; + for (std::size_t j = r; j >= 1; --j) { + qlstx.push_back(cln::cl_N(1) - x[j-1]); + if (instanceof(x[j-1], cln::cl_R_ring) && + realpart(x[j-1]) > 1 && realpart(x[j-1]) <= 2) { + qlsts.push_back(s[j-1]); } else { - qlsts.append( -s.op(j-1)); + qlsts.push_back(-s[j-1]); } } - if (qlstx.nops() > 0) { - buffer *= G_numeric(qlstx, qlsts, 1/q); + if (qlstx.size() > 0) { + buffer = buffer*G_numeric(qlstx, qlsts, 1/q); } - lst plstx; - lst plsts; - for (int j=r+1; j<=size; ++j) { - plstx.append(newx.op(j-1)); - plsts.append(s.op(j-1)); + std::vector plstx; + std::vector plsts; + for (std::size_t j = r+1; j <= size; ++j) { + plstx.push_back(x[j-1]); + plsts.push_back(s[j-1]); } - if (plstx.nops() > 0) { - buffer *= G_numeric(plstx, plsts, 1/p); + if (plstx.size() > 0) { + buffer = buffer*G_numeric(plstx, plsts, 1/p); } - result += buffer; + result = result + buffer; } return result; } // convergence transformation, used for numerical evaluation of G function. // the parameter x, s and y must only contain numerics -static ex G_do_trafo(const lst& x, const lst& s, const ex& y) +static cln::cl_N +G_do_trafo(const std::vector& x, const std::vector& s, + const cln::cl_N& y) { // sort (|x|<->position) to determine indices - std::multimap sortmap; - int size = 0; - for (int i=0; i(abs(x[i]), i)); + typedef std::multimap sortmap_t; + sortmap_t sortmap; + std::size_t size = 0; + for (std::size_t i = 0; i < x.size(); ++i) { + if (!zerop(x[i])) { + sortmap.insert(std::make_pair(abs(x[i]), i)); ++size; } } // include upper limit (scale) - sortmap.insert(std::pair(abs(y), x.nops())); + sortmap.insert(std::make_pair(abs(y), x.size())); // generate missing dummy-symbols int i = 1; // holding dummy-symbols for the G/Li transformations exvector gsyms; gsyms.push_back(symbol("GSYMS_ERROR")); - ex lastentry; - for (std::multimap::const_iterator it = sortmap.begin(); it != sortmap.end(); ++it) { + cln::cl_N lastentry(0); + for (sortmap_t::const_iterator it = sortmap.begin(); it != sortmap.end(); ++it) { if (it != sortmap.begin()) { - if (it->second < x.nops()) { + if (it->second < x.size()) { if (x[it->second] == lastentry) { gsyms.push_back(gsyms.back()); continue; @@ -1087,7 +1082,7 @@ static ex G_do_trafo(const lst& x, const lst& s, const ex& y) os << "a" << i; gsyms.push_back(symbol(os.str())); ++i; - if (it->second < x.nops()) { + if (it->second < x.size()) { lastentry = x[it->second]; } else { lastentry = y; @@ -1095,21 +1090,21 @@ static ex G_do_trafo(const lst& x, const lst& s, const ex& y) } // fill position data according to sorted indices and prepare substitution list - Gparameter a(x.nops()); - lst subslst; - int pos = 1; - int scale; - for (std::multimap::const_iterator it = sortmap.begin(); it != sortmap.end(); ++it) { - if (it->second < x.nops()) { + Gparameter a(x.size()); + exmap subslst; + std::size_t pos = 1; + int scale = pos; + for (sortmap_t::const_iterator it = sortmap.begin(); it != sortmap.end(); ++it) { + if (it->second < x.size()) { if (s[it->second] > 0) { a[it->second] = pos; } else { - a[it->second] = -pos; + a[it->second] = -int(pos); } - subslst.append(gsyms[pos] == x[it->second]); + subslst[gsyms[pos]] = numeric(x[it->second]); } else { scale = pos; - subslst.append(gsyms[pos] == y); + subslst[gsyms[pos]] = numeric(y); } ++pos; } @@ -1120,35 +1115,40 @@ static ex G_do_trafo(const lst& x, const lst& s, const ex& y) // replace dummy symbols with their values result = result.eval().expand(); result = result.subs(subslst).evalf(); + if (!is_a(result)) + throw std::logic_error("G_do_trafo: G_transform returned non-numeric result"); - return result; + cln::cl_N ret = ex_to(result).to_cl_N(); + return ret; } // handles the transformations and the numerical evaluation of G // the parameter x, s and y must only contain numerics -ex G_numeric(const lst& x, const lst& s, const ex& y) +static cln::cl_N +G_numeric(const std::vector& x, const std::vector& s, + const cln::cl_N& y) { // check for convergence and necessary accelerations bool need_trafo = false; bool need_hoelder = false; - int depth = 0; - for (lst::const_iterator it = x.begin(); it != x.end(); ++it) { - if (!(*it).is_zero()) { + std::size_t depth = 0; + for (std::size_t i = 0; i < x.size(); ++i) { + if (!zerop(x[i])) { ++depth; - if (abs(*it) - y < -pow(10,-Digits+1)) { + const cln::cl_N x_y = abs(x[i]) - y; + if (instanceof(x_y, cln::cl_R_ring) && + realpart(x_y) < cln::least_negative_float(cln::float_format(Digits - 2))) need_trafo = true; - } - if (abs((abs(*it) - y)/y) < 0.01) { + + if (abs(abs(x[i]/y) - 1) < 0.01) need_hoelder = true; - } } } - if (x.op(x.nops()-1).is_zero()) { + if (zerop(x[x.size() - 1])) need_trafo = true; - } - if (depth == 1 && x.nops() == 2 && !need_trafo) { - return -Li(x.nops(), y / x.op(x.nops()-1)).evalf(); - } + + if (depth == 1 && x.size() == 2 && !need_trafo) + return - Li_projection(2, y/x[1], cln::float_format(Digits)); // do acceleration transformation (hoelder convolution [BBB]) if (need_hoelder) @@ -1159,43 +1159,48 @@ ex G_numeric(const lst& x, const lst& s, const ex& y) return G_do_trafo(x, s, y); // do summation - lst newx; - lst m; + std::vector newx; + newx.reserve(x.size()); + std::vector m; + m.reserve(x.size()); int mcount = 1; - ex sign = 1; - ex factor = y; - for (lst::const_iterator it = x.begin(); it != x.end(); ++it) { - if ((*it).is_zero()) { + int sign = 1; + cln::cl_N factor = y; + for (std::size_t i = 0; i < x.size(); ++i) { + if (zerop(x[i])) { ++mcount; } else { - newx.append(factor / (*it)); - factor = *it; - m.append(mcount); + newx.push_back(factor/x[i]); + factor = x[i]; + m.push_back(mcount); mcount = 1; sign = -sign; } } - return sign * numeric(mLi_do_summation(m, newx)); + return sign*multipleLi_do_sum(m, newx); } ex mLi_numeric(const lst& m, const lst& x) { // let G_numeric do the transformation - lst newx; - lst s; - ex factor = 1; + std::vector newx; + newx.reserve(x.nops()); + std::vector s; + s.reserve(x.nops()); + cln::cl_N factor(1); for (lst::const_iterator itm = m.begin(), itx = x.begin(); itm != m.end(); ++itm, ++itx) { for (int i = 1; i < *itm; ++i) { - newx.append(0); - s.append(1); + newx.push_back(cln::cl_N(0)); + s.push_back(1); } - newx.append(factor / *itx); - factor /= *itx; - s.append(1); + const cln::cl_N xi = ex_to(*itx).to_cl_N(); + newx.push_back(factor/xi); + factor = factor/xi; + s.push_back(1); } - return pow(-1, m.nops()) * G_numeric(newx, s, _ex1); + return numeric(cln::cl_N(1 & m.nops() ? - 1 : 1)*G_numeric(newx, s, cln::cl_N(1))); } @@ -1223,7 +1228,8 @@ static ex G2_evalf(const ex& x_, const ex& y) if (x.op(0) == y) { return G(x_, y).hold(); } - lst s; + std::vector s; + s.reserve(x.nops()); bool all_zero = true; for (lst::const_iterator it = x.begin(); it != x.end(); ++it) { if (!(*it).info(info_flags::numeric)) { @@ -1233,16 +1239,21 @@ static ex G2_evalf(const ex& x_, const ex& y) all_zero = false; } if ( !ex_to(*it).is_real() && ex_to(*it).imag() < 0 ) { - s.append(-1); + s.push_back(-1); } else { - s.append(+1); + s.push_back(1); } } if (all_zero) { return pow(log(y), x.nops()) / factorial(x.nops()); } - return G_numeric(x, s, y); + std::vector xv; + xv.reserve(x.nops()); + for (lst::const_iterator it = x.begin(); it != x.end(); ++it) + xv.push_back(ex_to(*it).to_cl_N()); + cln::cl_N result = G_numeric(xv, s, ex_to(y).to_cl_N()); + return numeric(result); } @@ -1260,7 +1271,8 @@ static ex G2_eval(const ex& x_, const ex& y) if (x.op(0) == y) { return G(x_, y).hold(); } - lst s; + std::vector s; + s.reserve(x.nops()); bool all_zero = true; bool crational = true; for (lst::const_iterator it = x.begin(); it != x.end(); ++it) { @@ -1274,10 +1286,10 @@ static ex G2_eval(const ex& x_, const ex& y) all_zero = false; } if ( !ex_to(*it).is_real() && ex_to(*it).imag() < 0 ) { - s.append(-1); + s.push_back(-1); } else { - s.append(+1); + s.push_back(+1); } } if (all_zero) { @@ -1289,7 +1301,12 @@ static ex G2_eval(const ex& x_, const ex& y) if (crational) { return G(x_, y).hold(); } - return G_numeric(x, s, y); + std::vector xv; + xv.reserve(x.nops()); + for (lst::const_iterator it = x.begin(); it != x.end(); ++it) + xv.push_back(ex_to(*it).to_cl_N()); + cln::cl_N result = G_numeric(xv, s, ex_to(y).to_cl_N()); + return numeric(result); } @@ -1319,7 +1336,8 @@ static ex G3_evalf(const ex& x_, const ex& s_, const ex& y) if (x.op(0) == y) { return G(x_, s_, y).hold(); } - lst sn; + std::vector sn; + sn.reserve(s.nops()); bool all_zero = true; for (lst::const_iterator itx = x.begin(), its = s.begin(); itx != x.end(); ++itx, ++its) { if (!(*itx).info(info_flags::numeric)) { @@ -1333,25 +1351,30 @@ static ex G3_evalf(const ex& x_, const ex& s_, const ex& y) } if ( ex_to(*itx).is_real() ) { if ( *its >= 0 ) { - sn.append(+1); + sn.push_back(1); } else { - sn.append(-1); + sn.push_back(-1); } } else { if ( ex_to(*itx).imag() > 0 ) { - sn.append(+1); + sn.push_back(1); } else { - sn.append(-1); + sn.push_back(-1); } } } if (all_zero) { return pow(log(y), x.nops()) / factorial(x.nops()); } - return G_numeric(x, sn, y); + std::vector xn; + xn.reserve(x.nops()); + for (lst::const_iterator it = x.begin(); it != x.end(); ++it) + xn.push_back(ex_to(*it).to_cl_N()); + cln::cl_N result = G_numeric(xn, sn, ex_to(y).to_cl_N()); + return numeric(result); } @@ -1373,7 +1396,8 @@ static ex G3_eval(const ex& x_, const ex& s_, const ex& y) if (x.op(0) == y) { return G(x_, s_, y).hold(); } - lst sn; + std::vector sn; + sn.reserve(s.nops()); bool all_zero = true; bool crational = true; for (lst::const_iterator itx = x.begin(), its = s.begin(); itx != x.end(); ++itx, ++its) { @@ -1391,18 +1415,18 @@ static ex G3_eval(const ex& x_, const ex& s_, const ex& y) } if ( ex_to(*itx).is_real() ) { if ( *its >= 0 ) { - sn.append(+1); + sn.push_back(1); } else { - sn.append(-1); + sn.push_back(-1); } } else { if ( ex_to(*itx).imag() > 0 ) { - sn.append(+1); + sn.push_back(1); } else { - sn.append(-1); + sn.push_back(-1); } } } @@ -1415,7 +1439,12 @@ static ex G3_eval(const ex& x_, const ex& s_, const ex& y) if (crational) { return G(x_, s_, y).hold(); } - return G_numeric(x, sn, y); + std::vector xn; + xn.reserve(x.nops()); + for (lst::const_iterator it = x.begin(); it != x.end(); ++it) + xn.push_back(ex_to(*it).to_cl_N()); + cln::cl_N result = G_numeric(xn, sn, ex_to(y).to_cl_N()); + return numeric(result); } @@ -1657,7 +1686,7 @@ static void Li_print_latex(const ex& m_, const ex& x_, const print_context& c) } else { x = lst(x_); } - c.s << "\\mbox{Li}_{"; + c.s << "\\mathrm{Li}_{"; lst::const_iterator itm = m.begin(); (*itm).print(c); itm++; @@ -2173,7 +2202,7 @@ static ex S_deriv(const ex& n, const ex& p, const ex& x, unsigned deriv_param) static void S_print_latex(const ex& n, const ex& p, const ex& x, const print_context& c) { - c.s << "\\mbox{S}_{"; + c.s << "\\mathrm{S}_{"; n.print(c); c.s << ","; p.print(c); @@ -2254,7 +2283,7 @@ bool convert_parameter_H_to_Li(const lst& l, lst& m, lst& s, ex& pf) } } if (has_negative_parameters) { - for (int i=0; i 0) && (parameter[lastentry-1] == 0)) { lastentry--; } @@ -2465,9 +2494,9 @@ ex trafo_H_mult(const ex& h1, const ex& h2) hlong = h2.op(0).op(0); } } - for (int i=0; i<=hlong.nops(); i++) { + for (std::size_t i=0; i<=hlong.nops(); i++) { lst newparameter; - int j=0; + std::size_t j=0; for (; j(e.op(pos)) && is_a(e.op(pos).op(0))) { std::string name = ex_to(e.op(pos).op(0)).get_name(); if (name == "H") { @@ -2529,7 +2558,7 @@ struct map_trafo_H_mult : public map_function if (Hlst.nops() > 0) { ex buffer = trafo_H_mult(firstH, Hlst.op(0)); result *= buffer; - for (int i=1; i(e.op(i))) { std::string name = ex_to(e.op(i)).get_name(); if (name == "H") { @@ -2589,7 +2618,7 @@ ex trafo_H_prepend_one(const ex& e, const ex& arg) if (name == "H") { h = e; } else { - for (int i=0; i(e.op(i))) { std::string name = ex_to(e.op(i)).get_name(); if (name == "H") { @@ -2620,7 +2649,7 @@ ex trafo_H_1tx_prepend_minusone(const ex& e, const ex& arg) if (name == "H") { h = e; } else { - for (int i=0; i(e.op(i))) { std::string name = ex_to(e.op(i)).get_name(); if (name == "H") { @@ -2653,7 +2682,7 @@ ex trafo_H_1mxt1px_prepend_minusone(const ex& e, const ex& arg) if (name == "H") { h = e; } else { - for (int i=0; i(e.op(i))) { std::string name = ex_to(e.op(i)).get_name(); if (name == "H") { @@ -2684,7 +2713,7 @@ ex trafo_H_1mxt1px_prepend_one(const ex& e, const ex& arg) if (name == "H") { h = e; } else { - for (int i=0; i(e.op(i))) { std::string name = ex_to(e.op(i)).get_name(); if (name == "H") { @@ -2722,7 +2751,7 @@ struct map_trafo_H_1mx : public map_function // special cases if all parameters are either 0, 1 or -1 bool allthesame = true; if (parameter.op(0) == 0) { - for (int i=1; i(buffer)) { - for (int i=0; i(buffer)) { - for (int i=0; i(buffer)) { - for (int i=0; i(buffer)) { - for (int i=0; i(buffer)) { - for (int i=0; i& crX, int Sm = 0; int Smp1 = 0; std::vector > crG(s.size() - 1, std::vector(L2 + 1)); - for (int m=0; m < s.size() - 1; m++) { + for (int m=0; m < (int)s.size() - 1; m++) { Sm += s[m]; Smp1 = Sm + s[m+1]; for (int i = 0; i <= L2; i++) @@ -3681,7 +3710,7 @@ cln::cl_N zeta_do_Hoelder_convolution(const std::vector& m_, const std::vec s_p[0] = s_p[0] * cln::cl_N("1/2"); // convert notations int sig = 1; - for (int i=0; i