]> www.ginac.de Git - ginac.git/blob - check/exam_inifcns_nstdsums.cpp
0fbfaec6bbf7ba397753bb5088107a6541af18b2
[ginac.git] / check / exam_inifcns_nstdsums.cpp
1 /** @file exam_inifcns_nstdsums.cpp
2  *
3  *  This test routine applies assorted tests on initially known higher level
4  *  functions. */
5
6 /*
7  *  GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
8  *
9  *  This program is free software; you can redistribute it and/or modify
10  *  it under the terms of the GNU General Public License as published by
11  *  the Free Software Foundation; either version 2 of the License, or
12  *  (at your option) any later version.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 #include "ginac.h"
25 using namespace GiNaC;
26
27 #include <iostream>
28 #include <fstream>
29 using namespace std;
30
31
32 ////////////////////////////////////////////////////////////////////////////////
33 ////////////////////////////////////////////////////////////////////////////////
34 //  S exam
35 ////////////////////////////////////////////////////////////////////////////////
36 ////////////////////////////////////////////////////////////////////////////////
37
38
39 /*
40  * The data in the following include file has been produced by the following
41  * Mathematica (V4.1) script:
42  *
43  *
44  *    x={2/10,1,14/10,30/10}
45  *    y={0,3/10,-14/10}
46  *    st = OpenAppend["exam_inifcns_nstdsums_data.raw"]
47  *    $NumberMarks = False
48  *    Do[
49  *      Do[
50  *        Do[Write[st, i]; Write[st,j]; Write[st,x[[k]]+I*y[[l]]];
51  *          Write[st,Chop[N[PolyLog[i,j,x[[k]]+I*y[[l]]],25]]],{i,3},{j,3}], {k,4}],{l,3}]
52  *    Do[
53  *      Do[
54  *        Do[Write[st, i]; Write[st,j]; Write[st,-x[[k]]+I*y[[l]]];
55  *          Write[st,Chop[N[PolyLog[i,j,-x[[k]]+I*y[[l]]],25]]],{i,3},{j,3}], {k,4}], {l,3}]
56  *    Close[st]
57  *
58  *    
59  * and postprocessed by the following shell script
60  *
61  *
62  *    #/bin/sh
63  *    IFS=$'\n'
64  *    cat exam_inifcns_nstdsums_data.raw | sed -e 's/\*\^/E/g' > exam_inifcns_nstdsums_data.raw2
65  *    echo 'const char *data[] = {' > exam_inifcns_nstdsums_data.raw3
66  *    for i in `cat exam_inifcns_nstdsums_data.raw2`; do echo \"$i\",; done >> exam_inifcns_nstdsums_data.raw3
67  *    echo '"-999"};' >> exam_inifcns_nstdsums.h
68  *
69  *
70  */
71 #include "exam_inifcns_nstdsums.h"
72
73
74 // signals end of data
75 const int ENDMARK = -999;
76
77
78 static unsigned inifcns_test_S()
79 {
80         int digitsbuf = Digits;
81         // precision of data
82         Digits = 22;
83         ex prec = 5 * pow(10, -(ex)Digits);
84         
85         unsigned result = 0;
86         
87         int i = 0;
88         while (true) {
89                 ex n(data[i++],symbol());
90                 if (n == ENDMARK) {
91                         break;
92                 }
93                 ex p(data[i++],symbol());
94                 ex x(data[i++],symbol());
95                 ex res(data[i++],symbol());
96                 ex res2 = S(n, p, x).evalf();
97                 if (abs(res-res2) > prec) {
98                         clog << "S(" << n << "," << p << "," << x << ") seems to be wrong:" << endl;
99                         clog << "GiNaC           : " << res2 << endl;
100                         clog << "Reference       : " << res << endl;
101                         clog << "Abs. Difference : " << res2-res << endl;
102                         if (res2 != 0) {
103                                 ex reldiff = abs((res2-res)/res2);
104                                 clog << "Rel. Difference : " << reldiff << endl;
105                         }
106                         result++;
107                 }
108                 if (i % 80) {
109                         cout << "." << flush;
110                 }
111         }
112
113         Digits = digitsbuf;
114
115         return result;
116 }
117
118
119 ////////////////////////////////////////////////////////////////////////////////
120 ////////////////////////////////////////////////////////////////////////////////
121 //  H/Li exam
122 ////////////////////////////////////////////////////////////////////////////////
123 ////////////////////////////////////////////////////////////////////////////////
124
125
126 static unsigned inifcns_test_HLi()
127 {
128         using GiNaC::log;
129         int digitsbuf = Digits;
130         Digits = 17;
131         ex prec = 5 * pow(10, -(ex)Digits);
132         numeric almostone("0.999999999999999999");
133         unsigned result = 0;
134
135         lst res;
136         
137         res.append(H(lst{2,1},numeric(1)/2).hold() - (zeta(3)/8 - pow(log(2),3)/6));
138         res.append(H(lst{2,1,3},numeric(1)/3).hold() - Li(lst{2,1,3},lst{numeric(1)/3,1,1}).hold());
139         res.append(H(lst{2,1,3},numeric(98)/100).hold() - Li(lst{2,1,3},lst{numeric(98)/100,1,1}).hold());
140         res.append(H(lst{2,1,3},numeric(245)/100).hold() - Li(lst{2,1,3},lst{numeric(245)/100,1,1}).hold());
141         res.append(H(lst{4,1,1,1},numeric(1)/3).hold() - S(3,4,numeric(1)/3).hold());
142         res.append(H(lst{4,1,1,1},numeric(98)/100).hold() - S(3,4,numeric(98)/100).hold());
143         res.append(H(lst{4,1,1,1},numeric(245)/100).hold() - S(3,4,numeric(245)/100).hold());
144         res.append(H(lst{2,2,3},almostone).hold() - zeta(lst{2,2,3}));
145         res.append(H(lst{-3,-1,2,1},almostone).hold() - zeta(lst{3,1,2,1},lst{-1,1,-1,1}));
146         res.append(H(lst{-2,1,3},numeric(1)/3).hold() - -Li(lst{2,1,3},lst{-numeric(1)/3,-1,1}).hold());
147         res.append(H(lst{-2,1,3},numeric(98)/100).hold() - -Li(lst{2,1,3},lst{-numeric(98)/100,-1,1}).hold());
148         res.append(H(lst{-2,1,3},numeric(245)/100).hold() - -Li(lst{2,1,3},lst{-numeric(245)/100,-1,1}).hold());
149         res.append(H(lst{-3,1,-2,0,0},numeric(3)/10).hold() - convert_H_to_Li(lst{-3,1,-2,0,0},numeric(3)/10).eval());
150         
151         for (lst::const_iterator it = res.begin(); it != res.end(); it++) {
152                 ex diff = abs((*it).evalf());
153                 if (diff > prec) {
154                         clog << *it << " seems to be wrong: " << diff << endl;
155                         result++;
156                 }
157                 cout << "." << flush;
158         }
159
160         Digits = digitsbuf;
161
162         // conjugate test
163         numeric cdif = ex_to<numeric>(H(lst{2,2,1},5.0-5.0*I) - H(lst{2,2,1},5.0+5.0*I));
164         numeric cadd = ex_to<numeric>(H(lst{2,2,1},5.0-5.0*I) + H(lst{2,2,1},5.0+5.0*I));
165         if ((cdif.real() > prec) || (cadd.imag() > prec)) {
166                 clog << "complex conjugation test of H({2,2,1},5.0-5.0*I) seems to be wrong: " << cdif << " " << cadd << endl;
167                 result++;
168         }
169
170         return result;
171 }
172
173
174 ////////////////////////////////////////////////////////////////////////////////
175 ////////////////////////////////////////////////////////////////////////////////
176 //  zeta exam
177 ////////////////////////////////////////////////////////////////////////////////
178 ////////////////////////////////////////////////////////////////////////////////
179
180
181 static unsigned inifcns_test_zeta()
182 {
183         int digitsbuf = Digits;
184         
185         unsigned result = 0;
186
187         lst res;
188         
189         res.append(zeta(lst{2,1}) - zeta(3));
190         res.append(zeta(lst{2,1,1,1,1}) - zeta(6));
191         res.append(zeta(lst{6,3}) - (zeta(9)*83/2 - zeta(2)*zeta(7)*21 - zeta(2)*zeta(2)*zeta(5)*12/5));
192         res.append(zeta(lst{4,2,3}) - (-zeta(9)*59 + zeta(2)*zeta(7)*28 + pow(zeta(2),2)*zeta(5)*4 -
193                                        pow(zeta(3),3)/3 + pow(zeta(2),3)*zeta(3)*8/21));
194         res.append(zeta(lst{3,1,3,1,3,1,3,1}) - (2*pow(Pi,16)/factorial(18)));
195         res.append(zeta(lst{2},lst{-1}) - -zeta(2)/2);
196         res.append(zeta(lst{1,2},lst{-1,1}) - (-zeta(3)/4 - zeta(lst{1},lst{-1})*zeta(2)/2));
197         res.append(zeta(lst{2,1,1},lst{-1,-1,1}) - (-pow(zeta(2),2)*23/40 - pow(zeta(lst{1},lst{-1}),2)*zeta(2)*3/4
198                                                     - zeta(lst{3,1},lst{-1,1})*3/2 - zeta(lst{1},lst{-1})*zeta(3)*21/8));
199         
200         for (lst::const_iterator it = res.begin(); it != res.end(); it++) {
201                 Digits = 17;
202                 ex prec = 5 * pow(10, -(ex)Digits);
203                 ex diff = abs((*it).evalf());
204                 if (diff > prec) {
205                         clog << *it << " seems to be wrong: " << diff << endl;
206                         clog << "Digits: " << Digits << endl;
207                         result++;
208                 }
209                 cout << "." << flush;
210                 Digits = 40;
211                 prec = 5 * pow(10, -(ex)Digits);
212                 diff = abs((*it).evalf());
213                 if (diff > prec) {
214                         clog << *it << " seems to be wrong: " << diff << endl;
215                         clog << "Digits: " << Digits << endl;
216                         result++;
217                 }
218                 cout << "." << flush;
219         }
220
221         Digits = digitsbuf;
222
223         return result;
224 }
225
226
227 ////////////////////////////////////////////////////////////////////////////////
228 ////////////////////////////////////////////////////////////////////////////////
229 //  H/Li exam
230 ////////////////////////////////////////////////////////////////////////////////
231 ////////////////////////////////////////////////////////////////////////////////
232
233
234 static unsigned inifcns_test_LiG()
235 {
236         int digitsbuf = Digits;
237         Digits = 17;
238         ex prec = 5 * pow(10, -(ex)Digits);
239         numeric almostone("0.99999999999999999999");
240         unsigned result = 0;
241
242         lst res;
243         
244         res.append(Li(lst{4}, lst{6}).hold() - Li(4, 6.0));
245         res.append(G(lst{0,0,5.0,0,2.0,0,0,0,3.0},0.5).hold()
246                    + Li(lst{3,2,4}, lst{numeric(1,10), numeric(5,2), numeric(2,3)}));
247         res.append(Li(lst{2,1,1}, lst{almostone, almostone, almostone}) - zeta(lst{2,1,1}));
248
249         // check Li_{1,1} against known expression
250         symbol x("x"), y("y");
251         ex eps = 1e-30*I;
252         ex s1 = Li(lst{1,1},lst{x,y});
253         ex s2 = log(1-1/x/y-eps)*log((1-1/x-eps)/(1/x/y-1/x)) + Li(2,(1-1/x/y-eps)/(1/x-1/x/y))
254                         - log(-1/x/y-eps)*log((-1/x-eps)/(1/x/y-1/x)) - Li(2,(-1/x/y-eps)/(1/x-1/x/y))
255                         - log(-1/x/y-eps)*log(1-1/x-eps) + log(-1/x/y-eps)*log(-1/x-eps);
256         res.append(s1.subs(lst{x==numeric(1)/2, y==3}) - s2.subs(lst{x==numeric(1)/2, y==3}));
257         res.append(s1.subs(lst{x==numeric(3)/2, y==numeric(1)/2}) - s2.subs(lst{x==numeric(3)/2, y==numeric(1)/2}));
258         res.append(s1.subs(lst{x==2, y==numeric(4)/5}) - s2.subs(lst{x==2, y==numeric(4)/5}));
259
260         // shuffle and quasi-shuffle identities
261         res.append(G(lst{0,0.2},1).hold() * G(lst{0.5},1).hold() - G(lst{0.5,0,0.2},1).hold()
262                  - G(lst{0,0.5,0.2},1).hold() - G(lst{0,0.2,0.5},1).hold());
263         res.append(G(lst{0,0.5},1).hold() * G(lst{0.6},1).hold() - G(lst{0,0.5,0.5*0.6},1).hold()
264                  - G(lst{0.6,0,0.5*0.6},1).hold() + G(lst{0,0,0.5*0.6},1).hold());
265         res.append(Li(lst{2},lst{numeric(1,5)}).hold() * Li(lst{3},lst{7}).hold() - Li(lst{2,3},lst{numeric(1,5),7}).hold()
266                  - Li(lst{3,2},lst{7,numeric(1,5)}).hold() - Li(lst{5},lst{numeric(7,5)}).hold());
267         symbol a1, a2, a3, a4;
268         res.append((G(lst{a1,a2},1) * G(lst{a3,a4},1) - G(lst{a1,a2,a3,a4},1)
269                   - G(lst{a1,a3,a2,a4},1) - G(lst{a3,a1,a2,a4},1)
270                   - G(lst{a1,a3,a4,a2},1) - G(lst{a3,a1,a4,a2},1) - G(lst{a3,a4,a1,a2},1))
271                    .subs(lst{a1==numeric(1)/10, a2==numeric(3)/10, a3==numeric(7)/10, a4==5}));
272         res.append(G(lst{-0.009},1).hold() * G(lst{-8,1.4999},1).hold() - G(lst{-0.009,-8,1.4999},1).hold()
273                  - G(lst{-8,-0.009,1.4999},1).hold() - G(lst{-8,1.4999,-0.009},1).hold());
274         res.append(G(lst{sqrt(numeric(1)/2)+I*sqrt(numeric(1)/2)},1).hold() * G(lst{1.51,-0.999},1).hold()
275                  - G(lst{sqrt(numeric(1)/2)+I*sqrt(numeric(1)/2),1.51,-0.999},1).hold()
276                  - G(lst{1.51,sqrt(numeric(1)/2)+I*sqrt(numeric(1)/2),-0.999},1).hold()
277                  - G(lst{1.51,-0.999,sqrt(numeric(1)/2)+I*sqrt(numeric(1)/2)},1).hold());
278         // checks for hoelder convolution which is used if one argument has a distance to one smaller than 0.01 
279         res.append(G(lst{0, 1.2, 1, 1.01}, 1).hold() - G(lst{0, 1.2, 1, numeric("1.009999999999999999")}, 1).hold());
280
281         for (lst::const_iterator it = res.begin(); it != res.end(); it++) {
282                 ex diff = abs((*it).evalf());
283                 if (diff > prec) {
284                         clog << *it << " seems to be wrong: " << diff << endl;
285                         result++;
286                 }
287                 cout << "." << flush;
288         }
289
290         Digits = digitsbuf;
291
292         return result;
293 }
294
295
296 ////////////////////////////////////////////////////////////////////////////////
297 ////////////////////////////////////////////////////////////////////////////////
298 //  legacy exam - checking for historical bugs
299 ////////////////////////////////////////////////////////////////////////////////
300 ////////////////////////////////////////////////////////////////////////////////
301
302
303 static unsigned inifcns_test_legacy()
304 {
305         int digitsbuf = Digits;
306         Digits = 17;
307         ex prec = 5 * pow(10, -(ex)Digits);
308
309         unsigned result = 0;
310
311         ex r1 = zeta(lst{1,1,1,1,1,1}, lst{-1,-1,-1,1,1,1});
312         if ((r1.evalf() - numeric("-0.0012588769028204890704")) > prec) {
313                 clog << "zeta({1,1,1,1,1,1},{-1,-1,-1,1,1,1}) seems to be wrong." << endl;
314                 result++;
315         }
316
317         ex x1 = exp(2*Pi*I/13).evalf();
318         ex x2 = exp(24*Pi*I/13).evalf();
319         ex r2 = Li(lst{2},lst{x1}).hold().evalf();
320         ex r3 = Li(lst{2},lst{x2}).hold().evalf();
321         if ( abs(r2-conjugate(r3)) > prec ) {
322                 clog << "Legacy test 2 seems to be wrong." << endl;
323                 result++;
324         }
325
326         ex x3 = exp(5*Pi*I/3).evalf();
327         ex r4 = Li(lst{3},lst{x3}).hold().evalf();
328         if ( abs(r4 - numeric("0.40068563438653142847-0.95698384815740185713*I")) > prec ) {
329                 clog << "Legacy test 3 seems to be wrong." << endl;
330                 result++;
331         }
332
333         Digits = 100;
334         prec = 5 * pow(10, -(ex)Digits);
335         ex x0 = 1.;
336            x1 = exp(Pi*I/3).evalf();
337            x2 = exp(2*Pi*I/3).evalf();
338            x3 = -1.;
339         ex x4 = exp(4*Pi*I/3).evalf();
340         ex x5 = exp(5*Pi*I/3).evalf();
341
342         ex r5 = Li(lst{1,1,1,1},lst{x2,x4,x3,x0}).hold().evalf();
343         ex r6 = Li(lst{1,1,1,1},lst{x4,x2,x3,x0}).hold().evalf();
344         if ( abs(r5-conjugate(r6)) > prec ) {
345                 clog << "Legacy test 4 seems to be wrong." << endl;
346                 result++;
347         }
348
349         ex r7 = Li(lst{1,2,1},lst{x3,x2,x4}).hold().evalf()
350                 +Li(lst{1,1,2},lst{x3,x2,x4}).hold().evalf()
351                 +Li(lst{1,1,1,1},lst{x3,x0,x2,x4}).hold().evalf()
352                 +Li(lst{1,1,1,1},lst{x3,x2,x0,x4}).hold().evalf()
353                 +Li(lst{1,1,1,1},lst{x3,x2,x4,x0}).hold().evalf()
354                 +Li(lst{1,2,1},lst{x2,x1,x0}).hold().evalf()
355                 +Li(lst{1,1,2},lst{x2,x3,x4}).hold().evalf()
356                 +Li(lst{1,1,1,1},lst{x2,x4,x3,x0}).hold().evalf()
357                 +Li(lst{1,1,1,1},lst{x2,x3,x4,x0}).hold().evalf()
358                 +Li(lst{1,1,1,1},lst{x2,x3,x0,x4}).hold().evalf()
359                 +Li(lst{2,2},lst{x5,x4}).hold().evalf()
360                 +Li(lst{2,1,1},lst{x5,x0,x4}).hold().evalf()
361                 +Li(lst{2,1,1},lst{x5,x4,x0}).hold().evalf()
362                 -Li(lst{1,1},lst{x3,x0}).hold().evalf()*Li(lst{1,1},lst{x2,x4}).hold().evalf();
363         if ( abs(r7) > prec ) {
364                 clog << "Legacy test 5 seems to be wrong." << endl;
365                 result++;
366         }
367
368         Digits = digitsbuf;
369
370         return result;
371 }
372
373 static unsigned check_G_y_one_bug()
374 {
375         exvector exprs;
376         exprs.push_back(G(lst{-1,-1, 1,-1, 0}, 1));
377         exprs.push_back(G(lst{-1, 0, 1,-1, 0}, 1));
378         exprs.push_back(G(lst{-1, 1,-1,-1, 0}, 1));
379         exprs.push_back(G(lst{-1, 1,-1, 0, 0}, 1));
380         exprs.push_back(G(lst{-1, 1,-1, 1, 0}, 1));
381         exprs.push_back(G(lst{-1, 1, 0,-1, 0}, 1));
382         exprs.push_back(G(lst{-1, 1, 1,-1, 0}, 1));
383         exprs.push_back(G(lst{ 0,-1, 1,-1, 0}, 1));
384         exprs.push_back(G(lst{ 0, 1, 1,-1, 0}, 1));
385         unsigned err = 0;
386         for (exvector::const_iterator ep = exprs.begin(); ep != exprs.end(); ++ep) {
387                 try {
388                         ex val = ep->evalf();
389                         if (!is_a<numeric>(val)) {
390                                 clog << "evalf(" << *ep << ") is not a number: " << val << endl;
391                                 ++err;
392                         }
393                 } catch (std::exception& oops) {
394                         clog << "evalf(" << *ep << "): got an exception" << oops.what() << endl;
395                         ++err;
396                 }
397         }
398         return err;
399 }
400
401 unsigned exam_inifcns_nstdsums(void)
402 {
403         unsigned result = 0;
404         
405         cout << "examining consistency of nestedsums functions" << flush;
406         
407         result += inifcns_test_zeta();
408         result += inifcns_test_S();
409         result += inifcns_test_HLi();
410         result += inifcns_test_LiG();
411         result += inifcns_test_legacy();
412         result += check_G_y_one_bug();
413         
414         return result;
415 }
416
417 int main(int argc, char** argv)
418 {
419         return exam_inifcns_nstdsums();
420 }