Minor bug fix for the class modular_form_kernel: Ensure that the series-method includ...
[ginac.git] / check / exam_archive.cpp
1 /** @file exam_archive.cpp
2  *
3  *  Here we test GiNaC's archiving system. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2021 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #include "ginac.h"
24 using namespace GiNaC;
25
26 #include <fstream>
27 #include <iostream>
28 using namespace std;
29
30 #include <cln/cln.h>
31
32
33 unsigned exam_archive()
34 {
35         unsigned result = 0;
36         
37         symbol x("x"), y("y"), mu("mu"), dim("dim", "\\Delta");
38         ex e, f;
39
40         // This expression is complete nonsense but it contains every type of
41         // GiNaC object
42         e = -42 * x * pow(y, sin(y*Catalan)) * dirac_ONE()
43             * epsilon_tensor(idx(fail(), 3), idx(0, 3), idx(y/2, 3))
44           + lorentz_g(
45               varidx(lst{x, -11*y, acos(2*x).series(x==3-5*I, 3)} * color_ONE()
46                 * metric_tensor(varidx(log(cos(128.0/(x*y))), 5), varidx(2, 5)), zeta(3)),
47               varidx(diag_matrix({-1, Euler, atan(x/y==-15*I/17)})
48                 * delta_tensor(idx(x, 2), idx(wild(7), 3)), zeta(3), true),
49               true
50             )
51           + dirac_gamma(varidx(mu, dim)) * dirac_gamma(varidx(mu, 4-dim, true))
52             * color_T(idx(x, 8), 1) * color_h(idx(x, 8), idx(y, 8), idx(2, 8))
53             * indexed(x, sy_anti(), idx(2*y+1, x), varidx(-mu, 5))
54           - 2.4275 * spinor_metric(spinidx(0, 2, false, true), spinidx(y))
55           + abs(x).series(x == y, 4);
56
57         archive ar;
58         ar.archive_ex(e, "expr 1");
59         {
60                 std::ofstream fout("exam.gar", std::ios_base::binary);
61                 fout << ar;
62         }
63         ar.clear();
64         {
65                 std::ifstream fin("exam.gar", std::ios_base::binary);
66                 fin >> ar;
67         }
68         f = ar.unarchive_ex(lst{x, y, mu, dim}, "expr 1");
69
70         ex difference = (f - e).expand();
71         if (!difference.is_zero()) {
72                 clog << "archiving/unarchiving " << e << endl
73                      << "erroneously returned " << f << endl;
74                 ++result;
75         }
76
77         return result;
78 }
79
80 /** numeric::archive used to fail if the real part of a complex number
81  *  is a rational number and the imaginary part is a floating point one. */
82 unsigned numeric_complex_bug()
83 {
84         using namespace cln;
85         struct archive_unarchive_check
86         {
87                 unsigned operator()(const cl_N& n) const
88                 {
89                         ex e = numeric(n);
90                         archive ar;
91                         ar.archive_ex(e, "test");
92                         ex check = ar.unarchive_ex(lst{}, "test");
93                         if (!check.is_equal(e)) {
94                                 clog << __FILE__ << ':' << __LINE__ << ": expected: " << e << ", got " << check << endl;
95                                 return 1;
96                         }
97                         return 0;
98                 }
99         } checker;
100         unsigned result = 0;
101         const cl_I one(1);
102         const cl_R three_fp = cl_float(3.0);
103         std::vector<cl_N> numbers = {
104                 complex(one, one),
105                 complex(one, three_fp),
106                 complex(three_fp, one),
107                 complex(three_fp, three_fp)
108         };
109         for (auto & n : numbers) {
110                 result += checker(n);
111         }
112         return result;
113 }
114
115 int main(int argc, char** argv)
116 {
117         unsigned result = 0;
118
119         cout << "examining archiving system" << flush;
120
121         result += exam_archive();  cout << '.' << flush;
122         result += numeric_complex_bug();  cout << '.' << flush;
123
124         return result;
125 }