00001
00006
00007
00008 extern "C"
00009 {
00010 #include <sys/times.h>
00011 }
00012
00013 #define USER_GMP_WRAP
00014 #include "modulo.cc"
00015 #include "polynomial.cc"
00016
00017
00018
00019
00020 using namespace polynomial;
00021
00022
00023 double difftimes(clock_t t1, clock_t t0)
00024 {
00025
00026 return static_cast<double>(t1-t0)/static_cast<double>(sysconf(_SC_CLK_TCK));
00027 }
00028
00029
00030 bool do_check(const int maxk, const int anzPoints, const mpz_t m)
00031 {
00032 cout << endl << endl << "====================================" << endl;
00033 cout << " MULTIPOINT POLYNOM-EVAL SANITY " << maxk << ", " << anzPoints << endl;
00034
00035 int i;
00036
00037 mpz_t Polynom [maxk];
00038 mpz_t Points [anzPoints];
00039
00040 {
00041 const size_t bits = mpz_sizeinbase(m,2);
00042
00043 gmp_randstate_t randstate;
00044 gmp_randinit_default(randstate);
00045
00046 for (i=0; i<maxk; ++i) { mpz_init(Polynom[i]); mpz_rrandomb(Polynom[i],randstate,bits); mpz_mod(Polynom[i],Polynom[i],m); }
00047 for (i=0; i<anzPoints; ++i) { mpz_init(Points[i]); mpz_rrandomb(Points[i],randstate,bits); mpz_mod(Points[i],Points[i],m); }
00048
00049 gmp_randclear(randstate);
00050 }
00051
00052 mpz_t Res_Horner [anzPoints];
00053 for (i=0; i<anzPoints; ++i) mpz_init(Res_Horner[i]);
00054
00055 mpz_t Res_Multipoint [anzPoints];
00056 for (i=0; i<anzPoints; ++i) mpz_init(Res_Multipoint[i]);
00057
00058
00059 cout << "Starting evaluation using Horner scheme" << endl;
00060 clock_t Start = times(NULL);
00061 for (i=0; i<anzPoints; ++i) eval(Res_Horner[i],Polynom,maxk,Points[i],m);
00062 clock_t Stop = times(NULL);
00063 cout << difftimes(Stop,Start) << " seconds (user time)." << endl;
00064
00065
00066 cout << "Starting fast multipoint evaluation" << endl;
00067 Start = times(NULL);
00068 multipoint_eval(Res_Multipoint,Polynom,maxk,Points,anzPoints,m);
00069 Stop = times(NULL);
00070 cout << difftimes(Stop,Start) << " seconds (user time)." << endl;
00071
00072 cout << "verifying points for Horner <-> Multipoint..." << endl;
00073 bool error = false;
00074 for (int i=0; i<anzPoints; ++i)
00075 {
00076 #ifdef DEBUG
00077 mpz_out_str(stdout,10,Points[i]); cout << " -> ";
00078 mpz_out_str(stdout,10,Res_Horner[i]); cout << " (Horner) ";
00079 mpz_out_str(stdout,10,Res_Multipoint[i]); cout << " (Multipoint)" << endl;
00080 #endif
00081 if (mpz_cmp(Res_Horner[i],Res_Multipoint[i]))
00082 {
00083 error=true;
00084 cerr << "values differ!!" << i << endl;
00085 mpz_out_str(stdout,10,Points[i]); cout << " -> ";
00086 mpz_out_str(stdout,10,Res_Horner[i]); cout << " (Horner) ";
00087 mpz_out_str(stdout,10,Res_Multipoint[i]); cout << " (Multipoint)" << endl;
00088 break;
00089 }
00090 }
00091 if (error)
00092 {
00093 cout << "FAILED!" << endl;
00094 exit(1);
00095 }
00096
00097 cout << "conforming; test passed." << endl;
00098 cout << "PASSED." << endl;
00099
00100 for (i=0; i<maxk; ++i) { mpz_clear(Polynom[i]); }
00101 for (i=0; i<anzPoints; ++i) mpz_clear(Points[i]);
00102 for (i=0; i<anzPoints; ++i) mpz_clear(Res_Horner[i]);
00103 for (i=0; i<anzPoints; ++i) mpz_clear(Res_Multipoint[i]);
00104 return true;
00105 }
00106
00107 bool performance_check(const int maxk, const int anzPoints, const mpz_t m)
00108 {
00109 cout << endl << endl << "====================================" << endl;
00110 cout << " MULTIPOINT POLYNOM-EVAL PERFORMANCE " << maxk << ", " << anzPoints << endl;
00111
00112 int i;
00113
00114 mpz_t Polynom [maxk];
00115 mpz_t Points [anzPoints];
00116
00117 {
00118 const size_t bits = mpz_sizeinbase(m,2);
00119
00120 gmp_randstate_t randstate;
00121 gmp_randinit_default(randstate);
00122
00123 for (i=0; i<maxk; ++i) { mpz_init(Polynom[i]); mpz_rrandomb(Polynom[i],randstate,bits); mpz_mod(Polynom[i],Polynom[i],m); }
00124 for (i=0; i<anzPoints; ++i) { mpz_init(Points[i]); mpz_rrandomb(Points[i],randstate,bits); mpz_mod(Points[i],Points[i],m); }
00125
00126 gmp_randclear(randstate);
00127 }
00128
00129
00130 mpz_t Res_Multipoint [anzPoints];
00131 for (i=0; i<anzPoints; ++i) mpz_init(Res_Multipoint[i]);
00132
00133
00134 cout << "Starting fast multipoint evaluation" << endl;
00135 clock_t Start = times(NULL);
00136 multipoint_eval(Res_Multipoint,Polynom,maxk,Points,anzPoints,m);
00137 clock_t Stop = times(NULL);
00138 cout << difftimes(Stop,Start) << " seconds (user time)." << endl;
00139
00140 for (i=0; i<maxk; ++i) { mpz_clear(Polynom[i]); }
00141 for (i=0; i<anzPoints; ++i) mpz_clear(Points[i]);
00142 for (i=0; i<anzPoints; ++i) mpz_clear(Res_Multipoint[i]);
00143 return true;
00144 }
00145
00146
00147 int main()
00148 {
00149 cout << endl << endl
00150 << "===============================================" << endl;
00151 cout << "POLYNOMIAL-MULTIPOINT-EVAL doing some checks..." << endl;
00152 cout << "===============================================" << endl;
00153
00154 mpz_t m;
00155 mpz_init(m);
00156
00157
00158 mpz_set_ui(m,10); mpz_pow_ui(m,m,120); mpz_add_ui(m,m,3);
00159
00160
00161 #if 0
00162
00163 for (int maxk=4; maxk<(1<<14); maxk*=2)
00164 {
00165 for (int i=3; i<maxk; ++i) do_check(maxk,i,m);
00166 for (int i=3; i<maxk+1; ++i) do_check(maxk+1,i,m);
00167 }
00168 #endif
00169
00170
00171 #if 1
00172 for (int maxk=1024; maxk<(1<<19); maxk*=2)
00173 {
00174 performance_check(maxk+1,maxk,m);
00175 }
00176 #endif
00177
00178
00179
00180 #if 0
00181
00182 for (int maxk=4; maxk<(1<<16); maxk*=2)
00183 {
00184 do_check(maxk,maxk-1,m);
00185 do_check(maxk+1,maxk,m);
00186 }
00187
00188 mpz_set_str(m,"3923385745693995079670229419275984584311007321932374190635656246740175165573932140787529348954892963218868359081838772941945556717",10);
00189 for (int maxk=4; maxk<2048; maxk*=2)
00190 {
00191 do_check(maxk,maxk-1,m);
00192 do_check(maxk+1,maxk,m);
00193 }
00194 #endif
00195
00196 mpz_clear(m);
00197 }