c4ad95f98cc1ccc7af28bf794308052fdf106333
[ginac.git] / check / time_lw_N.cpp
1 /** @file time_lw_N.cpp
2  *
3  *  Test N from the paper "Comparison of Polynomial-Oriented CAS" by Robert H.
4  *  Lewis and Michael Wester (also known as the smaller version of the first
5  *  Fermat-test). */
6
7 /*
8  *  GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
9  *
10  *  This program is free software; you can redistribute it and/or modify
11  *  it under the terms of the GNU General Public License as published by
12  *  the Free Software Foundation; either version 2 of the License, or
13  *  (at your option) any later version.
14  *
15  *  This program is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  *  GNU General Public License for more details.
19  *
20  *  You should have received a copy of the GNU General Public License
21  *  along with this program; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
23  */
24
25 #include "ginac.h"
26 #include "timer.h"
27 using namespace GiNaC;
28
29 #include <iostream>
30 #include <vector>
31 using namespace std;
32
33 constexpr bool do_test = false;  // set to true in order to run this beast
34
35 static unsigned test()
36 {
37         symbol p11("p11"), p12("p12"), p21("p21"), p22("p22");
38         symbol a12("a12"), a21("a21"), a22("a22");
39         symbol n11("n11"), n22("n22");
40         symbol g("g");
41         symbol q1("q1"), q2("q2"), q3("q3"), q4("q4");
42         
43         ex ss1 = ex("(4*g*a22^3-g*a12*a21*a22^2-4*n22*a21*a22^2+4*n11*a21*a22^2+7*g*a12*a22^2+4*g^2*a22^2-4*n11*n22*a22^2+4*n11*a22^2+n22*a12*a21^2*a22-n11*a12*a21^2*a22-4*g*a21^2*a22-g*a12^2*a21*a22-5*g^2*a12*a21*a22+5*n11*n22*a12*a21*a22-7*n22*a12*a21*a22+2*n11*a12*a21*a22-4*g*a21*a22+3*g*a12^2*a22+3*g^2*a12*a22-3*n11*n22*a12*a22+3*n11*a12*a22+g*a12*a21^3+g^2*a12^2*a21^2-n11*n22*a12^2*a21^2+n22*a12^2*a21^2-2*g*a12*a21^2-3*g^2*a12^2*a21+3*n11*n22*a12^2*a21-3*n22*a12^2*a21-3*g*a12*a21)/(3*g*a12*a21*a22^2-3*n22*a21*a22^2+g*a12*a22^2-n22*a22^2+3*n11*a12*a21^2*a22-3*g*a21^2*a22+5*g*a12^2*a21*a22-5*n22*a12*a21*a22+4*n11*a12*a21*a22-4*g*a21*a22+g*a12^2*a22-n22*a12*a22+n11*a12*a22-g*a22+2*n11*a12^2*a21^2-2*g*a12*a21^2+2*g*a12^3*a21-2*n22*a12^2*a21+2*n11*a12^2*a21-2*g*a12*a21)",lst(g,a12,a21,a22,n11,n22));
44         
45         ex ss2 = ex("(4*g*a12*a22^2-4*n22*a22^2+4*a22^2-g*a12^2*a21*a22+n22*a12*a21*a22+4*n11*a12*a21*a22-5*a12*a21*a22-4*g*a21*a22+3*g*a12^2*a22-3*n22*a12*a22+3*a12*a22-n11*a12^2*a21^2+a12^2*a21^2+g*a12*a21^2+3*n11*a12^2*a21-3*a12^2*a21-3*g*a12*a21)/(2*g*a12*a22^2-2*n22*a22^2+g*a12^2*a21*a22-n22*a12*a21*a22+2*n11*a12*a21*a22-2*g*a21*a22+2*g*a12^2*a22-2*n22*a12*a22+2*n11*a12*a22-2*g*a22+n11*a12^2*a21^2-g*a12*a21^2+g*a12^3*a21-n22*a12^2*a21+n11*a12^2*a21-g*a12*a21)",lst(g,a12,a21,a22,n11,n22));
46         
47         ex ss3 = ex("(4*p21*a22^3-p21*a12*a21*a22^2-4*p22*a21*a22^2+4*p11*a21*a22^2+7*p21*a12*a22^2-4*p11*p22*a22^2+4*p12*p21*a22^2+4*p11*a22^2+p22*a12*a21^2*a22-p11*a12*a21^2*a22-4*p12*a21^2*a22-p21*a12^2*a21*a22+5*p11*p22*a12*a21*a22-7*p22*a12*a21*a22-5*p12*p21*a12*a21*a22+2*p11*a12*a21*a22-4*p12*a21*a22+3*p21*a12^2*a22-3*p11*p22*a12*a22+3*p12*p21*a12*a22+3*p11*a12*a22+p12*a12*a21^3-p11*p22*a12^2*a21^2+p22*a12^2*a21^2+p12*p21*a12^2*a21^2-2*p12*a12*a21^2+3*p11*p22*a12^2*a21-3*p22*a12^2*a21-3*p12*p21*a12^2*a21-3*p12*a12*a21)/(3*p21*a12*a21*a22^2-3*p22*a21*a22^2+p21*a12*a22^2-p22*a22^2+3*p11*a12*a21^2*a22-3*p12*a21^2*a22+5*p21*a12^2*a21*a22-5*p22*a12*a21*a22+4*p11*a12*a21*a22-4*p12*a21*a22+p21*a12^2*a22-p22*a12*a22+p11*a12*a22-p12*a22+2*p11*a12^2*a21^2-2*p12*a12*a21^2+2*p21*a12^3*a21-2*p22*a12^2*a21+2*p11*a12^2*a21-2*p12*a12*a21)",lst(a12,a21,a22,p11,p12,p21,p22));
48         
49         ex ss4 = ex("(4*p21*a12*a22^2-4*p22*a22^2+4*a22^2-p21*a12^2*a21*a22+p22*a12*a21*a22+4*p11*a12*a21*a22-5*a12*a21*a22-4*p12*a21*a22+3*p21*a12^2*a22-3*p22*a12*a22+3*a12*a22-p11*a12^2*a21^2+a12^2*a21^2+p12*a12*a21^2+3*p11*a12^2*a21-3*a12^2*a21-3*p12*a12*a21)/(2*p21*a12*a22^2-2*p22*a22^2+p21*a12^2*a21*a22-p22*a12*a21*a22+2*p11*a12*a21*a22-2*p12*a21*a22+2*p21*a12^2*a22-2*p22*a12*a22+2*p11*a12*a22-2*p12*a22+p11*a12^2*a21^2-p12*a12*a21^2+p21*a12^3*a21-p22*a12^2*a21+p11*a12^2*a21-p12*a12*a21)",lst(p11,p12,p21,p22,a12,a21,a22));
50         
51         ex res1 = ex("p11*p22*q1^2*q4^2-p12*p21*q1^2*q4^2-n22*p11*p22*q1*q4^2+2*n11*p11*p22*q1*q4^2-p11*p22*q1*q4^2+n22*p12*p21*q1*q4^2-2*n11*p12*p21*q1*q4^2+p12*p21*q1*q4^2+2*g^2*p11*p22*q4^2-2*n11*n22*p11*p22*q4^2+2*n22*p11*p22*q4^2+2*n11*p11*p22*q4^2-2*p11*p22*q4^2-2*g^2*p12*p21*q4^2+2*n11*n22*p12*p21*q4^2-2*n22*p12*p21*q4^2-2*n11*p12*p21*q4^2+2*p12*p21*q4^2-n11*p22*q1*q2*q3*q4+g*p21*q1*q2*q3*q4+g*p12*q1*q2*q3*q4-n22*p11*q1*q2*q3*q4-g^2*p22*q2*q3*q4+n11*n22*p22*q2*q3*q4-n11*p22*q2*q3*q4-2*g*p21*q2*q3*q4+g*p12*q2*q3*q4+2*g^2*p11*q2*q3*q4-2*n11*n22*p11*q2*q3*q4+2*n22*p11*q2*q3*q4-n11*p22*q1*q3*q4+p22*q1*q3*q4+g*p21*q1*q3*q4-2*g*p12*q1*q3*q4+2*n22*p11*q1*q3*q4-2*p11*q1*q3*q4-g^2*p22*q3*q4+n11*n22*p22*q3*q4-n22*p22*q3*q4-n11*p22*q3*q4+p22*q3*q4-4*g^2*p11*q3*q4+4*n11*n22*p11*q3*q4-4*n22*p11*q3*q4-4*n11*p11*q3*q4+4*p11*q3*q4+n22*p11*p22*q1*q2*q4-2*n11*p11*p22*q1*q2*q4+2*n11*p22*q1*q2*q4-n22*p12*p21*q1*q2*q4+2*n11*p12*p21*q1*q2*q4+g*p21*q1*q2*q4-2*g*p12*q1*q2*q4-n22*p11*q1*q2*q4-4*g^2*p11*p22*q2*q4+4*n11*n22*p11*p22*q2*q4-2*n22*p11*p22*q2*q4-2*n11*p11*p22*q2*q4+2*g^2*p22*q2*q4-2*n11*n22*p22*q2*q4+2*n11*p22*q2*q4+4*g^2*p12*p21*q2*q4-4*n11*n22*p12*p21*q2*q4+2*n22*p12*p21*q2*q4+2*n11*p12*p21*q2*q4-2*g*p21*q2*q4-2*g*p12*q2*q4+2*g^2*p11*q2*q4-2*n11*n22*p11*q2*q4+2*n22*p11*q2*q4-p11*p22*q1^2*q4-p22*q1^2*q4+p12*p21*q1^2*q4+2*p11*q1^2*q4-n22*p11*p22*q1*q4-4*n11*p11*p22*q1*q4+5*p11*p22*q1*q4+n22*p22*q1*q4-p22*q1*q4+n22*p12*p21*q1*q4+4*n11*p12*p21*q1*q4-5*p12*p21*q1*q4+g*p21*q1*q4+4*g*p12*q1*q4+4*n11*p11*q1*q4-4*p11*q1*q4-g^2*q2^2*q3^2+n11*n22*q2^2*q3^2+g^2*q2*q3^2-n11*n22*q2*q3^2-n22*q2*q3^2+2*n11*q2*q3^2+2*g^2*q3^2-2*n11*n22*q3^2+2*n22*q3^2+2*n11*q3^2-2*q3^2+g^2*p22*q2^2*q3-n11*n22*p22*q2^2*q3-2*g^2*p11*q2^2*q3+2*n11*n22*p11*q2^2*q3+g^2*q2^2*q3-n11*n22*q2^2*q3+2*n11*p22*q1*q2*q3-2*g*p21*q1*q2*q3+g*p12*q1*q2*q3-n22*p11*q1*q2*q3+n22*q1*q2*q3-2*n11*q1*q2*q3+g^2*p22*q2*q3-n11*n22*p22*q2*q3+n22*p22*q2*q3+4*g*p21*q2*q3+g*p12*q2*q3+4*g^2*p11*q2*q3-4*n11*n22*p11*q2*q3+4*n11*p11*q2*q3-5*g^2*q2*q3+5*n11*n22*q2*q3-n22*q2*q3-4*n11*q2*q3+2*n11*p22*q1*q3-2*p22*q1*q3-2*g*p21*q1*q3-2*g*p12*q1*q3+2*n22*p11*q1*q3-2*p11*q1*q3-2*n22*q1*q3-2*n11*q1*q3+4*q1*q3+2*g^2*p11*p22*q2^2-2*n11*n22*p11*p22*q2^2-2*g^2*p22*q2^2+2*n11*n22*p22*q2^2-2*g^2*p12*p21*q2^2+2*n11*n22*p12*p21*q2^2-2*g^2*p11*q2^2+2*n11*n22*p11*q2^2+2*g^2*q2^2-2*n11*n22*q2^2+n22*p11*p22*q1*q2+4*n11*p11*p22*q1*q2-n22*p22*q1*q2-4*n11*p22*q1*q2-n22*p12*p21*q1*q2-4*n11*p12*p21*q1*q2-n22*p11*q1*q2-4*n11*p11*q1*q2+n22*q1*q2+4*n11*q1*q2-2*p11*p22*q1^2+2*p22*q1^2+2*p12*p21*q1^2+2*p11*q1^2-2*q1^2",lst(p11,p12,p21,p22,n11,n22,g,q1,q2,q3,q4));
52         ex result = res1.subs(lst(q1==ss1, q2==ss2, q3==ss3, q4==ss4));
53         ex normalresult = normal(result);
54         if (!normalresult.is_zero()) {
55                 clog << "Normalization should have returned 0." << endl;
56                 return 1;
57         }
58         return 0;
59 }
60
61 unsigned time_lw_N()
62 {
63         unsigned result = 0;
64         unsigned count = 0;
65         timer tag_heuer;
66         double time = .0;
67         
68         cout << "timing Lewis-Wester test N (poly at rational fcns)" << flush;
69         
70         if (do_test) {
71                 tag_heuer.start();
72                 // correct for very small times:
73                 do {
74                         result = test();
75                         ++count;
76                 } while ((time=tag_heuer.read())<0.1 && !result);
77                 cout << '.' << flush;
78                 cout << time/count << 's' << endl;
79         } else {
80                 cout << " disabled" << endl;
81         }
82         
83         return result;
84 }
85
86 extern void randomify_symbol_serials();
87
88 int main(int argc, char** argv)
89 {
90         randomify_symbol_serials();
91         cout << setprecision(2) << showpoint;
92         return time_lw_N();
93 }