Add exam for ex::collect().
authorRichard Kreckel <kreckel@ginac.de>
Mon, 5 Apr 2021 18:57:34 +0000 (20:57 +0200)
committerRichard Kreckel <kreckel@ginac.de>
Mon, 5 Apr 2021 19:06:45 +0000 (21:06 +0200)
check/.gitignore
check/CMakeLists.txt
check/Makefile.am
check/exam_collect.cpp [new file with mode: 0644]

index c9cd5f25ea1b344245b8fddedbe051090fdd774a..633cf233b8f0a733be1570c15fb87fb1c2702265 100644 (file)
@@ -4,6 +4,7 @@
 exam.gar
 exam_archive
 exam_clifford
+exam_collect
 exam_color
 exam_differentiation
 exam_factor
index 768b192b53fc6236e8392dd0c1a5f41d296f00c3..663dbbdeb150f4a6ad67c5c0a50e8ee077baaed0 100644 (file)
@@ -6,6 +6,7 @@ set(ginac_exams
        exam_parser
        exam_numeric
        exam_powerlaws
+       exam_collect
        exam_inifcns
        exam_inifcns_nstdsums
        exam_inifcns_elliptic
index 9f8039ea6957f91a0f3ca282674e1dd3092c1fcc..8fa225f3f4847238b636cd1604bdb9145c601e23 100644 (file)
@@ -6,6 +6,7 @@ EXAMS = exam_paranoia \
        exam_parser \
        exam_numeric \
        exam_powerlaws \
+       exam_collect \
        exam_inifcns \
        exam_inifcns_nstdsums \
        exam_inifcns_elliptic \
@@ -83,6 +84,9 @@ exam_numeric_LDADD = ../ginac/libginac.la
 exam_powerlaws_SOURCES = exam_powerlaws.cpp
 exam_powerlaws_LDADD = ../ginac/libginac.la
 
+exam_collect_SOURCES = exam_collect.cpp
+exam_collect_LDADD = ../ginac/libginac.la
+
 exam_inifcns_SOURCES = exam_inifcns.cpp
 exam_inifcns_LDADD = ../ginac/libginac.la
 
diff --git a/check/exam_collect.cpp b/check/exam_collect.cpp
new file mode 100644 (file)
index 0000000..270722d
--- /dev/null
@@ -0,0 +1,152 @@
+/** @file exam_collect.cpp
+ *
+ */
+
+/*
+ *  GiNaC Copyright (C) 1999-2021 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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "ginac.h"
+using namespace GiNaC;
+
+#include <iostream>
+using namespace std;
+
+// Correctness of .collect(Z[x], x).
+static unsigned exam_collect_1()
+{
+       unsigned result = 0;
+       symbol x("x"), y("y");
+       ex a = (pow(x, 3) - 2*pow(x, 2) + 4*x) * pow(y, 2)
+              + (pow(x, 2) - x - 1) * y
+              + (x + 1);
+       ex b = pow(y, 2) * pow(x, 3)
+              + (y - 2*pow(y, 2)) * pow(x, 2)
+              + (4*pow(y, 2) - y + 1) * x
+              + (1 - y);
+
+       ex a_x = collect(a, x);
+       if (a_x != b) {
+               clog << "collect(" << a << ", " << x << ") erroneously returned "
+                    << a_x << " instead of " << b << endl;
+               ++result;
+       }
+
+       ex b_y = collect(b, y);
+       if (b_y != a) {
+               clog << "collect(" << b << ", " << y << ") erroneously returned "
+                    << b_y << " instead of " << a << endl;
+               ++result;
+       }
+
+       ex amb_x = collect(a - b, x);
+       if (amb_x != 0) {
+               clog << "collect(" << a - b << ", " << x << ") erroneously returned "
+                    << amb_x << " instead of 0" << endl;
+               ++result;
+       }
+
+       ex amb_y = collect(a - b, y);
+       if (amb_y != 0) {
+               clog << "collect(" << a - b << ", " << y << ") erroneously returned "
+                    << amb_y << " instead of 0" << endl;
+               ++result;
+       }
+
+       return result;
+}
+
+// Consistency of .collect(Z[x,y], {x,y}) with .coeff(x).
+static unsigned exam_collect_2()
+{
+       unsigned result = 0;
+       symbol x("x"), y("y"), p("p"), q("q");
+
+       ex e1 = x + y;
+       ex e2 = 1 + p + q;
+       ex a = expand(e1 * e2);
+
+       ex a_x = a.collect(x).coeff(x, 1);
+       if (a_x != e2) {
+               clog << "collect(" << a << ", " << x << ") erroneously returned "
+                    << a_x << " as coefficient of " << x << endl;
+               ++result;
+       }
+
+       ex a_p = a.collect(p).coeff(p, 1);
+       if (a_p != e1) {
+               clog << "collect(" << a << ", " << p << ") erroneously returned "
+                    << a_p << " as coefficient of " << p << endl;
+               ++result;
+       }
+
+       ex a_xy = a.collect(lst{x,y});
+       ex ref = e2*x + e2*y;
+       if (a_xy != ref) {
+               clog << "collect(" << a << ", {" << x << ", " << y << "}) erroneously returned "
+                    << a_xy << " instead of " << ref << endl;
+               ++result;
+       }
+
+       return result;
+}
+
+// Consistency of .collect(Z[f(x)], f(x)) with .coeff(f(x)).
+static unsigned exam_collect_3()
+{
+       unsigned result = 0;
+       symbol x("x"), p("p"), q("q");
+
+       for (unsigned deg = 2; deg < 7; ++deg) {
+
+               ex a1 = expand(pow(p + q + x, deg));
+               a1 = a1.collect(x);
+
+               ex a2 = expand(pow(p + q + sin(x), deg));
+               a2 = a2.collect(sin(x));
+
+               for (unsigned i = 0; i < deg; ++i) {
+                       ex a1_i = a1.coeff(x, i);
+                       ex a2_i = a2.coeff(sin(x), i);
+                       if (!expand(a1_i - a2_i).is_zero()) {
+                               clog << "collect(" << a1 << ",sin(x)) inconsistent with "
+                                       "collect(" << a2 << ",x)" << endl;
+                               ++result;
+                       }
+               }
+       }
+
+       return result;
+}
+
+unsigned exam_collect()
+{
+       unsigned result = 0;
+
+       cout << "examining collect coefficients" << flush;
+
+       result += exam_collect_1();  cout << '.' << flush;
+       result += exam_collect_2();  cout << '.' << flush;
+       result += exam_collect_3();  cout << '.' << flush;
+
+       return result;
+}
+
+int main(int argc, char** argv)
+{
+       return exam_collect();
+}