Add exam for ex::collect().
[ginac.git] / check / exam_collect.cpp
1 /** @file exam_collect.cpp
2  *
3  */
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 <iostream>
27 using namespace std;
28
29 // Correctness of .collect(Z[x], x).
30 static unsigned exam_collect_1()
31 {
32         unsigned result = 0;
33         symbol x("x"), y("y");
34         ex a = (pow(x, 3) - 2*pow(x, 2) + 4*x) * pow(y, 2)
35                + (pow(x, 2) - x - 1) * y
36                + (x + 1);
37         ex b = pow(y, 2) * pow(x, 3)
38                + (y - 2*pow(y, 2)) * pow(x, 2)
39                + (4*pow(y, 2) - y + 1) * x
40                + (1 - y);
41
42         ex a_x = collect(a, x);
43         if (a_x != b) {
44                 clog << "collect(" << a << ", " << x << ") erroneously returned "
45                      << a_x << " instead of " << b << endl;
46                 ++result;
47         }
48
49         ex b_y = collect(b, y);
50         if (b_y != a) {
51                 clog << "collect(" << b << ", " << y << ") erroneously returned "
52                      << b_y << " instead of " << a << endl;
53                 ++result;
54         }
55
56         ex amb_x = collect(a - b, x);
57         if (amb_x != 0) {
58                 clog << "collect(" << a - b << ", " << x << ") erroneously returned "
59                      << amb_x << " instead of 0" << endl;
60                 ++result;
61         }
62
63         ex amb_y = collect(a - b, y);
64         if (amb_y != 0) {
65                 clog << "collect(" << a - b << ", " << y << ") erroneously returned "
66                      << amb_y << " instead of 0" << endl;
67                 ++result;
68         }
69
70         return result;
71 }
72
73 // Consistency of .collect(Z[x,y], {x,y}) with .coeff(x).
74 static unsigned exam_collect_2()
75 {
76         unsigned result = 0;
77         symbol x("x"), y("y"), p("p"), q("q");
78
79         ex e1 = x + y;
80         ex e2 = 1 + p + q;
81         ex a = expand(e1 * e2);
82
83         ex a_x = a.collect(x).coeff(x, 1);
84         if (a_x != e2) {
85                 clog << "collect(" << a << ", " << x << ") erroneously returned "
86                      << a_x << " as coefficient of " << x << endl;
87                 ++result;
88         }
89
90         ex a_p = a.collect(p).coeff(p, 1);
91         if (a_p != e1) {
92                 clog << "collect(" << a << ", " << p << ") erroneously returned "
93                      << a_p << " as coefficient of " << p << endl;
94                 ++result;
95         }
96
97         ex a_xy = a.collect(lst{x,y});
98         ex ref = e2*x + e2*y;
99         if (a_xy != ref) {
100                 clog << "collect(" << a << ", {" << x << ", " << y << "}) erroneously returned "
101                      << a_xy << " instead of " << ref << endl;
102                 ++result;
103         }
104
105         return result;
106 }
107
108 // Consistency of .collect(Z[f(x)], f(x)) with .coeff(f(x)).
109 static unsigned exam_collect_3()
110 {
111         unsigned result = 0;
112         symbol x("x"), p("p"), q("q");
113
114         for (unsigned deg = 2; deg < 7; ++deg) {
115
116                 ex a1 = expand(pow(p + q + x, deg));
117                 a1 = a1.collect(x);
118
119                 ex a2 = expand(pow(p + q + sin(x), deg));
120                 a2 = a2.collect(sin(x));
121
122                 for (unsigned i = 0; i < deg; ++i) {
123                         ex a1_i = a1.coeff(x, i);
124                         ex a2_i = a2.coeff(sin(x), i);
125                         if (!expand(a1_i - a2_i).is_zero()) {
126                                 clog << "collect(" << a1 << ",sin(x)) inconsistent with "
127                                         "collect(" << a2 << ",x)" << endl;
128                                 ++result;
129                         }
130                 }
131         }
132
133         return result;
134 }
135
136 unsigned exam_collect()
137 {
138         unsigned result = 0;
139
140         cout << "examining collect coefficients" << flush;
141
142         result += exam_collect_1();  cout << '.' << flush;
143         result += exam_collect_2();  cout << '.' << flush;
144         result += exam_collect_3();  cout << '.' << flush;
145
146         return result;
147 }
148
149 int main(int argc, char** argv)
150 {
151         return exam_collect();
152 }