[GiNaC-devel] [PATCH] inifscn_nstdsums: make functions handling Li/G transformations reentrant.
Alexei Sheplyakov
varg at theor.jinr.ru
Sun Aug 24 13:25:24 CEST 2008
Explicitly pass the dummy symbols instead of using a global variable.
As a side effect, the code is more clear now (that's a bit subjective, but
anyway).
---
ginac/inifcns_nstdsums.cpp | 128 +++++++++++++++++++++++++------------------
1 files changed, 74 insertions(+), 54 deletions(-)
diff --git a/ginac/inifcns_nstdsums.cpp b/ginac/inifcns_nstdsums.cpp
index 01a5756..dd8625a 100644
--- a/ginac/inifcns_nstdsums.cpp
+++ b/ginac/inifcns_nstdsums.cpp
@@ -518,16 +518,12 @@ cln::cl_N mLi_do_summation(const lst& m, const lst& x)
lst convert_parameter_Li_to_H(const lst& m, const lst& x, ex& pf);
-// holding dummy-symbols for the G/Li transformations
-std::vector<ex> gsyms;
-
-
// type used by the transformation functions for G
typedef std::vector<int> Gparameter;
// G_eval1-function for G transformations
-ex G_eval1(int a, int scale)
+ex G_eval1(int a, int scale, const exvector& gsyms)
{
if (a != 0) {
const ex& scs = gsyms[std::abs(scale)];
@@ -544,7 +540,7 @@ ex G_eval1(int a, int scale)
// G_eval-function for G transformations
-ex G_eval(const Gparameter& a, int scale)
+ex G_eval(const Gparameter& a, int scale, const exvector& gsyms)
{
// check for properties of G
ex sc = gsyms[std::abs(scale)];
@@ -578,7 +574,7 @@ ex G_eval(const Gparameter& a, int scale)
for (; it != a.end(); ++it) {
short_a.push_back(*it);
}
- ex result = G_eval1(a.front(), scale) * G_eval(short_a, scale);
+ ex result = G_eval1(a.front(), scale, gsyms) * G_eval(short_a, scale, gsyms);
it = short_a.begin();
for (int i=1; i<count_ones; ++i) {
++it;
@@ -596,14 +592,14 @@ ex G_eval(const Gparameter& a, int scale)
for (; it2 != short_a.end(); ++it2) {
newa.push_back(*it2);
}
- result -= G_eval(newa, scale);
+ result -= G_eval(newa, scale, gsyms);
}
return result / count_ones;
}
// G({1,...,1};y) -> G({1};y)^k / k!
if (all_ones && a.size() > 1) {
- return pow(G_eval1(a.front(),scale), count_ones) / factorial(count_ones);
+ return pow(G_eval1(a.front(),scale, gsyms), count_ones) / factorial(count_ones);
}
// G({0,...,0};y) -> log(y)^k / k!
@@ -696,7 +692,7 @@ Gparameter prepare_pending_integrals(const Gparameter& pending_integrals, int sc
// handles trailing zeroes for an otherwise convergent integral
-ex trailing_zeros_G(const Gparameter& a, int scale)
+ex trailing_zeros_G(const Gparameter& a, int scale, const exvector& gsyms)
{
bool convergent;
int depth, trailing_zeros;
@@ -708,23 +704,23 @@ ex trailing_zeros_G(const Gparameter& a, int scale)
if ((trailing_zeros > 0) && (depth > 0)) {
ex result;
Gparameter new_a(a.begin(), a.end()-1);
- result += G_eval1(0, scale) * trailing_zeros_G(new_a, scale);
+ result += G_eval1(0, scale, gsyms) * trailing_zeros_G(new_a, scale, gsyms);
for (Gparameter::const_iterator it = a.begin(); it != last; ++it) {
Gparameter new_a(a.begin(), it);
new_a.push_back(0);
new_a.insert(new_a.end(), it, a.end()-1);
- result -= trailing_zeros_G(new_a, scale);
+ result -= trailing_zeros_G(new_a, scale, gsyms);
}
return result / trailing_zeros;
} else {
- return G_eval(a, scale);
+ return G_eval(a, scale, gsyms);
}
}
// G transformation [VSW] (57),(58)
-ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, int scale)
+ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, int scale, const exvector& gsyms)
{
// pendint = ( y1, b1, ..., br )
// a = ( 0, ..., 0, amin )
@@ -755,15 +751,21 @@ ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, i
result -= I*Pi;
}
if (psize) {
- result *= trailing_zeros_G(convert_pending_integrals_G(pending_integrals), pending_integrals.front());
+ result *= trailing_zeros_G(convert_pending_integrals_G(pending_integrals),
+ pending_integrals.front(),
+ gsyms);
}
// G(y2_{-+}; sr)
- result += trailing_zeros_G(convert_pending_integrals_G(new_pending_integrals), new_pending_integrals.front());
+ result += trailing_zeros_G(convert_pending_integrals_G(new_pending_integrals),
+ new_pending_integrals.front(),
+ gsyms);
// G(0; sr)
new_pending_integrals.back() = 0;
- result -= trailing_zeros_G(convert_pending_integrals_G(new_pending_integrals), new_pending_integrals.front());
+ result -= trailing_zeros_G(convert_pending_integrals_G(new_pending_integrals),
+ new_pending_integrals.front(),
+ gsyms);
return result;
}
@@ -775,14 +777,16 @@ ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, i
//term zeta_m
result -= zeta(a.size());
if (psize) {
- result *= trailing_zeros_G(convert_pending_integrals_G(pending_integrals), pending_integrals.front());
+ result *= trailing_zeros_G(convert_pending_integrals_G(pending_integrals),
+ pending_integrals.front(),
+ gsyms);
}
// term int_0^sr dt/t G_{m-1}( (1/y2)_{+-}; 1/t )
// = int_0^sr dt/t G_{m-1}( t_{+-}; y2 )
Gparameter new_a(a.begin()+1, a.end());
new_pending_integrals.push_back(0);
- result -= depth_one_trafo_G(new_pending_integrals, new_a, scale);
+ result -= depth_one_trafo_G(new_pending_integrals, new_a, scale, gsyms);
// term int_0^y2 dt/t G_{m-1}( (1/y2)_{+-}; 1/t )
// = int_0^y2 dt/t G_{m-1}( t_{+-}; y2 )
@@ -790,10 +794,12 @@ ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, i
new_pending_integrals_2.push_back(scale);
new_pending_integrals_2.push_back(0);
if (psize) {
- result += trailing_zeros_G(convert_pending_integrals_G(pending_integrals), pending_integrals.front())
- * depth_one_trafo_G(new_pending_integrals_2, new_a, scale);
+ result += trailing_zeros_G(convert_pending_integrals_G(pending_integrals),
+ pending_integrals.front(),
+ gsyms)
+ * depth_one_trafo_G(new_pending_integrals_2, new_a, scale, gsyms);
} else {
- result += depth_one_trafo_G(new_pending_integrals_2, new_a, scale);
+ result += depth_one_trafo_G(new_pending_integrals_2, new_a, scale, gsyms);
}
return result;
@@ -802,11 +808,13 @@ ex depth_one_trafo_G(const Gparameter& pending_integrals, const Gparameter& a, i
// forward declaration
ex shuffle_G(const Gparameter & a0, const Gparameter & a1, const Gparameter & a2,
- const Gparameter& pendint, const Gparameter& a_old, int scale);
+ const Gparameter& pendint, const Gparameter& a_old, int scale,
+ const exvector& gsyms);
// G transformation [VSW]
-ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
+ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale,
+ const exvector& gsyms)
{
// main recursion routine
//
@@ -832,10 +840,12 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
if (a.size() == 0) {
result = 1;
} else {
- result = G_eval(a, scale);
+ result = G_eval(a, scale, gsyms);
}
if (pendint.size() > 0) {
- result *= trailing_zeros_G(convert_pending_integrals_G(pendint), pendint.front());
+ result *= trailing_zeros_G(convert_pending_integrals_G(pendint),
+ pendint.front(),
+ gsyms);
}
return result;
}
@@ -844,12 +854,12 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
if (trailing_zeros > 0) {
ex result;
Gparameter new_a(a.begin(), a.end()-1);
- result += G_eval1(0, scale) * G_transform(pendint, new_a, scale);
+ result += G_eval1(0, scale, gsyms) * G_transform(pendint, new_a, scale, gsyms);
for (Gparameter::const_iterator it = a.begin(); it != firstzero; ++it) {
Gparameter new_a(a.begin(), it);
new_a.push_back(0);
new_a.insert(new_a.end(), it, a.end()-1);
- result -= G_transform(pendint, new_a, scale);
+ result -= G_transform(pendint, new_a, scale, gsyms);
}
return result / trailing_zeros;
}
@@ -857,15 +867,17 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
// convergence case
if (convergent) {
if (pendint.size() > 0) {
- return G_eval(convert_pending_integrals_G(pendint), pendint.front()) * G_eval(a, scale);
+ return G_eval(convert_pending_integrals_G(pendint),
+ pendint.front(), gsyms)*
+ G_eval(a, scale, gsyms);
} else {
- return G_eval(a, scale);
+ return G_eval(a, scale, gsyms);
}
}
// call basic transformation for depth equal one
if (depth == 1) {
- return depth_one_trafo_G(pendint, a, scale);
+ return depth_one_trafo_G(pendint, a, scale, gsyms);
}
// do recursion
@@ -880,9 +892,10 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
Gparameter a1(a.begin(),min_it+1);
Gparameter a2(min_it+1,a.end());
- ex result = G_transform(pendint,a2,scale)*G_transform(empty,a1,scale);
+ ex result = G_transform(pendint, a2, scale, gsyms)*
+ G_transform(empty, a1, scale, gsyms);
- result -= shuffle_G(empty,a1,a2,pendint,a,scale);
+ result -= shuffle_G(empty, a1, a2, pendint, a, scale, gsyms);
return result;
}
@@ -893,9 +906,10 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
Gparameter new_pendint = prepare_pending_integrals(pendint, a[min_it_pos]);
Gparameter new_a = a;
new_a[min_it_pos] = 0;
- ex result = G_transform(empty, new_a, scale);
+ ex result = G_transform(empty, new_a, scale, gsyms);
if (pendint.size() > 0) {
- result *= trailing_zeros_G(convert_pending_integrals_G(pendint), pendint.front());
+ result *= trailing_zeros_G(convert_pending_integrals_G(pendint),
+ pendint.front(), gsyms);
}
// other terms
@@ -904,29 +918,33 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
if (changeit != new_a.begin()) {
// smallest in the middle
new_pendint.push_back(*changeit);
- result -= trailing_zeros_G(convert_pending_integrals_G(new_pendint), new_pendint.front())
- * G_transform(empty, new_a, scale);
+ result -= trailing_zeros_G(convert_pending_integrals_G(new_pendint),
+ new_pendint.front(), gsyms)*
+ G_transform(empty, new_a, scale, gsyms);
int buffer = *changeit;
*changeit = *min_it;
- result += G_transform(new_pendint, new_a, scale);
+ result += G_transform(new_pendint, new_a, scale, gsyms);
*changeit = buffer;
new_pendint.pop_back();
--changeit;
new_pendint.push_back(*changeit);
- result += trailing_zeros_G(convert_pending_integrals_G(new_pendint), new_pendint.front())
- * G_transform(empty, new_a, scale);
+ result += trailing_zeros_G(convert_pending_integrals_G(new_pendint),
+ new_pendint.front(), gsyms)*
+ G_transform(empty, new_a, scale, gsyms);
*changeit = *min_it;
- result -= G_transform(new_pendint, new_a, scale);
+ result -= G_transform(new_pendint, new_a, scale, gsyms);
} else {
// smallest at the front
new_pendint.push_back(scale);
- result += trailing_zeros_G(convert_pending_integrals_G(new_pendint), new_pendint.front())
- * G_transform(empty, new_a, scale);
+ result += trailing_zeros_G(convert_pending_integrals_G(new_pendint),
+ new_pendint.front(), gsyms)*
+ G_transform(empty, new_a, scale, gsyms);
new_pendint.back() = *changeit;
- result -= trailing_zeros_G(convert_pending_integrals_G(new_pendint), new_pendint.front())
- * G_transform(empty, new_a, scale);
+ result -= trailing_zeros_G(convert_pending_integrals_G(new_pendint),
+ new_pendint.front(), gsyms)*
+ G_transform(empty, new_a, scale, gsyms);
*changeit = *min_it;
- result += G_transform(new_pendint, new_a, scale);
+ result += G_transform(new_pendint, new_a, scale, gsyms);
}
return result;
}
@@ -935,27 +953,28 @@ ex G_transform(const Gparameter& pendint, const Gparameter& a, int scale)
// shuffles the two parameter list a1 and a2 and calls G_transform for every term except
// for the one that is equal to a_old
ex shuffle_G(const Gparameter & a0, const Gparameter & a1, const Gparameter & a2,
- const Gparameter& pendint, const Gparameter& a_old, int scale)
+ const Gparameter& pendint, const Gparameter& a_old, int scale,
+ const exvector& gsyms)
{
if (a1.size()==0 && a2.size()==0) {
// veto the one configuration we don't want
if ( a0 == a_old ) return 0;
- return G_transform(pendint,a0,scale);
+ return G_transform(pendint, a0, scale, gsyms);
}
if (a2.size()==0) {
Gparameter empty;
Gparameter aa0 = a0;
aa0.insert(aa0.end(),a1.begin(),a1.end());
- return shuffle_G(aa0,empty,empty,pendint,a_old,scale);
+ return shuffle_G(aa0, empty, empty, pendint, a_old, scale, gsyms);
}
if (a1.size()==0) {
Gparameter empty;
Gparameter aa0 = a0;
aa0.insert(aa0.end(),a2.begin(),a2.end());
- return shuffle_G(aa0,empty,empty,pendint,a_old,scale);
+ return shuffle_G(aa0, empty, empty, pendint, a_old, scale, gsyms);
}
Gparameter a1_removed(a1.begin()+1,a1.end());
@@ -967,8 +986,8 @@ ex shuffle_G(const Gparameter & a0, const Gparameter & a1, const Gparameter & a2
a01.push_back( a1[0] );
a02.push_back( a2[0] );
- return shuffle_G(a01,a1_removed,a2,pendint,a_old,scale)
- + shuffle_G(a02,a1,a2_removed,pendint,a_old,scale);
+ return shuffle_G(a01, a1_removed, a2, pendint, a_old, scale, gsyms)
+ + shuffle_G(a02, a1, a2_removed, pendint, a_old, scale, gsyms);
}
@@ -1067,7 +1086,8 @@ ex G_numeric(const lst& x, const lst& s, const ex& y)
// generate missing dummy-symbols
int i = 1;
- gsyms.clear();
+ // holding dummy-symbols for the G/Li transformations
+ exvector gsyms;
gsyms.push_back(symbol("GSYMS_ERROR"));
ex lastentry;
for (std::multimap<ex,int>::const_iterator it = sortmap.begin(); it != sortmap.end(); ++it) {
@@ -1117,7 +1137,7 @@ ex G_numeric(const lst& x, const lst& s, const ex& y)
// do transformation
Gparameter pendint;
- ex result = G_transform(pendint, a, scale);
+ ex result = G_transform(pendint, a, scale, gsyms);
// replace dummy symbols with their values
result = result.eval().expand();
result = result.subs(subslst).evalf();
--
1.5.6
Best regards,
Alexei
--
All science is either physics or stamp collecting.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 827 bytes
Desc: Digital signature
Url : http://www.cebix.net/pipermail/ginac-devel/attachments/20080824/d45ee25a/attachment.sig
More information about the GiNaC-devel
mailing list