- Timestamp:
- Jun 20, 2014, 12:25:12 PM (10 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- 5b4953b0435d257dfff1b9b6848b8c2a28e0f347
- Parents:
- baa2c3a8e2d77600e598268aca866716d7070466
- git-author:
- Martin Lee <martinlee84@web.de>2014-06-20 12:25:12+02:00
- git-committer:
- Martin Lee <martinlee84@web.de>2014-06-24 12:06:05+02:00
- Location:
- factory
- Files:
-
- 1 added
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
factory/cfEzgcd.cc
rbaa2c3a rf1e3bf5 2 2 * Computer Algebra System SINGULAR 3 3 \*****************************************************************************/ 4 /** @file fac_ezgcd.cc4 /** @file cfEzgcd.cc 5 5 * 6 * This file implements the GCD of two multivariate polynomials over Q using7 * EZ-GCD as described in "Algorithms for Computer Algebra" by Geddes, Czapor,8 * Labahnn6 * This file implements the GCD of two multivariate polynomials over Q or F_q 7 * using EZ-GCD as described in "Algorithms for Computer Algebra" by Geddes, 8 * Czapor, Labahnn 9 9 * 10 10 * @author Martin Lee … … 23 23 #include "cf_defs.h" 24 24 #include "canonicalform.h" 25 #include "fac_util.h" // HEADER for this file 25 #include "cfEzgcd.h" 26 #include "cf_gcd_smallp.h" 27 #include "cf_util.h" 28 #include "cf_map_ext.h" 26 29 #include "cf_algorithm.h" 27 30 #include "cf_reval.h" … … 33 36 34 37 #ifdef HAVE_NTL 38 #include "NTLconvert.h" 39 40 static const double log2exp= 1.442695041; 35 41 36 42 TIMING_DEFINE_PRINT(ez_eval) … … 783 789 } 784 790 791 static inline 792 int Hensel_P (const CanonicalForm & UU, CFArray & G, const Evaluation & AA, 793 const CFArray& LeadCoeffs ) 794 { 795 CFList factors; 796 factors.append (G[1]); 797 factors.append (G[2]); 798 799 CFMap NN, MM; 800 Evaluation A= optimize4Lift (UU, MM, NN, AA); 801 802 CanonicalForm U= MM (UU); 803 CFArray LCs= CFArray (1,2); 804 LCs [1]= MM (LeadCoeffs [1]); 805 LCs [2]= MM (LeadCoeffs [2]); 806 807 CFList evaluation; 808 long termEstimate= size (U); 809 for (int i= A.min(); i <= A.max(); i++) 810 { 811 if (!A[i].isZero() && (getCharacteristic() > degree (U,i))) //TODO find a good estimate for getCharacteristic() <= degree (U,i) 812 { 813 termEstimate *= degree (U,i)*2; 814 termEstimate /= 3; 815 } 816 evaluation.append (A [i]); 817 } 818 if (termEstimate/getNumVars(U) > 500) 819 return -1; 820 CFList UEval; 821 CanonicalForm shiftedU= myShift2Zero (U, UEval, evaluation); 822 823 if (size (shiftedU)/getNumVars (U) > 500) 824 return -1; 825 826 CFArray shiftedLCs= CFArray (2); 827 CFList shiftedLCsEval1, shiftedLCsEval2; 828 shiftedLCs[0]= myShift2Zero (LCs[1], shiftedLCsEval1, evaluation); 829 shiftedLCs[1]= myShift2Zero (LCs[2], shiftedLCsEval2, evaluation); 830 factors.insert (1); 831 int liftBound= degree (UEval.getLast(), 2) + 1; 832 CFArray Pi; 833 CFMatrix M= CFMatrix (liftBound, factors.length() - 1); 834 CFList diophant; 835 CFArray lcs= CFArray (2); 836 lcs [0]= shiftedLCsEval1.getFirst(); 837 lcs [1]= shiftedLCsEval2.getFirst(); 838 nonMonicHenselLift12 (UEval.getFirst(), factors, liftBound, Pi, diophant, M, 839 lcs, false); 840 841 for (CFListIterator i= factors; i.hasItem(); i++) 842 { 843 if (!fdivides (i.getItem(), UEval.getFirst())) 844 return 0; 845 } 846 847 int * liftBounds; 848 bool noOneToOne= false; 849 if (U.level() > 2) 850 { 851 liftBounds= new int [U.level() - 1]; /* index: 0.. U.level()-2 */ 852 liftBounds[0]= liftBound; 853 for (int i= 1; i < U.level() - 1; i++) 854 liftBounds[i]= degree (shiftedU, Variable (i + 2)) + 1; 855 factors= nonMonicHenselLift2 (UEval, factors, liftBounds, U.level() - 1, 856 false, shiftedLCsEval1, shiftedLCsEval2, Pi, 857 diophant, noOneToOne); 858 delete [] liftBounds; 859 if (noOneToOne) 860 return 0; 861 } 862 G[1]= factors.getFirst(); 863 G[2]= factors.getLast(); 864 G[1]= myReverseShift (G[1], evaluation); 865 G[2]= myReverseShift (G[2], evaluation); 866 G[1]= NN (G[1]); 867 G[2]= NN (G[2]); 868 return 1; 869 } 870 871 static inline 872 bool findeval_P (const CanonicalForm & F, const CanonicalForm & G, 873 CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, 874 REvaluation & b, int delta, int degF, int degG, int maxeval, 875 int & count, int& k, int bound, int& l) 876 { 877 if( count == 0 && delta != 0) 878 { 879 if( count++ > maxeval ) 880 return false; 881 } 882 if (count > 0) 883 { 884 b.nextpoint(k); 885 if (k == 0) 886 k++; 887 l++; 888 if (l > bound) 889 { 890 l= 1; 891 k++; 892 if (k > tmax (F.level(), G.level()) - 1) 893 return false; 894 b.nextpoint (k); 895 } 896 if (count++ > maxeval) 897 return false; 898 } 899 while( true ) 900 { 901 Fb = b( F ); 902 if( degree( Fb, 1 ) == degF ) 903 { 904 Gb = b( G ); 905 if( degree( Gb, 1 ) == degG ) 906 { 907 Db = gcd( Fb, Gb ); 908 if( delta > 0 ) 909 { 910 if( degree( Db, 1 ) <= delta ) 911 return true; 912 } 913 else 914 return true; 915 } 916 } 917 if (k == 0) 918 k++; 919 b.nextpoint(k); 920 l++; 921 if (l > bound) 922 { 923 l= 1; 924 k++; 925 if (k > tmax (F.level(), G.level()) - 1) 926 return false; 927 b.nextpoint (k); 928 } 929 if( count++ > maxeval ) 930 return false; 931 } 932 } 933 934 // parameters for heuristic 935 static int maxNumEval= 200; 936 static int sizePerVars1= 500; //try dense gcd if size/#variables is bigger 937 938 /// Extended Zassenhaus GCD for finite fields 939 CanonicalForm EZGCD_P( const CanonicalForm & FF, const CanonicalForm & GG ) 940 { 941 if (FF.isZero() && degree(GG) > 0) return GG/Lc(GG); 942 else if (GG.isZero() && degree (FF) > 0) return FF/Lc(FF); 943 else if (FF.isZero() && GG.isZero()) return FF.genOne(); 944 if (FF.inBaseDomain() || GG.inBaseDomain()) return FF.genOne(); 945 if (FF.isUnivariate() && fdivides(FF, GG)) return FF/Lc(FF); 946 if (GG.isUnivariate() && fdivides(GG, FF)) return GG/Lc(GG); 947 if (FF == GG) return FF/Lc(FF); 948 949 int maxNumVars= tmax (getNumVars (FF), getNumVars (GG)); 950 Variable a, oldA; 951 int sizeF= size (FF); 952 int sizeG= size (GG); 953 954 if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1) 955 { 956 if (hasFirstAlgVar (FF, a) || hasFirstAlgVar (GG, a)) 957 return GCD_Fp_extension (FF, GG, a); 958 else if (CFFactory::gettype() == GaloisFieldDomain) 959 return GCD_GF (FF, GG); 960 else 961 return GCD_small_p (FF, GG); 962 } 963 964 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, 965 lcD; 966 CFArray DD( 1, 2 ), lcDD( 1, 2 ); 967 int degF, degG, delta, count; 968 int maxeval; 969 maxeval= tmin((getCharacteristic()/ 970 (int)(ilog2(getCharacteristic())*log2exp))*2, maxNumEval); 971 count= 0; // number of eval. used 972 REvaluation b, bt; 973 int gcdfound = 0; 974 Variable x = Variable(1); 975 976 F= FF; 977 G= GG; 978 979 CFMap M,N; 980 int smallestDegLev; 981 TIMING_START (ez_p_compress) 982 int best_level= compress4EZGCD (F, G, M, N, smallestDegLev); 983 984 if (best_level == 0) return G.genOne(); 985 986 F= M (F); 987 G= M (G); 988 TIMING_END_AND_PRINT (ez_p_compress, "time for compression in EZ_P: ") 989 990 TIMING_START (ez_p_content) 991 f = content( F, x ); g = content( G, x ); 992 d = gcd( f, g ); 993 F /= f; G /= g; 994 TIMING_END_AND_PRINT (ez_p_content, "time to extract content in EZ_P: ") 995 996 if( F.isUnivariate() && G.isUnivariate() ) 997 { 998 if( F.mvar() == G.mvar() ) 999 d *= gcd( F, G ); 1000 else 1001 return N (d); 1002 return N (d); 1003 } 1004 if ( F.isUnivariate()) 1005 { 1006 g= content (G,G.mvar()); 1007 return N(d*gcd(F,g)); 1008 } 1009 if ( G.isUnivariate()) 1010 { 1011 f= content (F,F.mvar()); 1012 return N(d*gcd(G,f)); 1013 } 1014 1015 maxNumVars= tmax (getNumVars (F), getNumVars (G)); 1016 sizeF= size (F); 1017 sizeG= size (G); 1018 1019 if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1) 1020 { 1021 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a)) 1022 return N (d*GCD_Fp_extension (F, G, a)); 1023 else if (CFFactory::gettype() == GaloisFieldDomain) 1024 return N (d*GCD_GF (F, G)); 1025 else 1026 return N (d*GCD_small_p (F, G)); 1027 } 1028 1029 int dummy= 0; 1030 if( gcd_test_one( F, G, false, dummy ) ) 1031 { 1032 return N (d); 1033 } 1034 1035 bool passToGF= false; 1036 bool extOfExt= false; 1037 int p= getCharacteristic(); 1038 bool algExtension= (hasFirstAlgVar(F,a) || hasFirstAlgVar(G,a)); 1039 int k= 1; 1040 CanonicalForm primElem, imPrimElem; 1041 CFList source, dest; 1042 if (p < 50 && CFFactory::gettype() != GaloisFieldDomain && !algExtension) 1043 { 1044 if (p == 2) 1045 setCharacteristic (2, 12, 'Z'); 1046 else if (p == 3) 1047 setCharacteristic (3, 4, 'Z'); 1048 else if (p == 5 || p == 7) 1049 setCharacteristic (p, 3, 'Z'); 1050 else 1051 setCharacteristic (p, 2, 'Z'); 1052 passToGF= true; 1053 F= F.mapinto(); 1054 G= G.mapinto(); 1055 maxeval= 2*ipower (p, getGFDegree()); 1056 } 1057 else if (CFFactory::gettype() == GaloisFieldDomain && 1058 ipower (p , getGFDegree()) < 50) 1059 { 1060 k= getGFDegree(); 1061 if (ipower (p, 2*k) > 50) 1062 setCharacteristic (p, 2*k, gf_name); 1063 else 1064 setCharacteristic (p, 3*k, gf_name); 1065 F= GFMapUp (F, k); 1066 G= GFMapUp (G, k); 1067 maxeval= tmin (2*ipower (p, getGFDegree()), maxNumEval); 1068 } 1069 else if (p < 50 && algExtension && CFFactory::gettype() != GaloisFieldDomain) 1070 { 1071 int d= degree (getMipo (a)); 1072 oldA= a; 1073 Variable v2; 1074 if (p == 2 && d < 6) 1075 { 1076 if (fac_NTL_char != p) 1077 { 1078 fac_NTL_char= p; 1079 zz_p::init (p); 1080 } 1081 bool primFail= false; 1082 Variable vBuf; 1083 primElem= primitiveElement (a, vBuf, primFail); 1084 ASSERT (!primFail, "failure in integer factorizer"); 1085 if (d < 3) 1086 { 1087 zz_pX NTLIrredpoly; 1088 BuildIrred (NTLIrredpoly, d*3); 1089 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1)); 1090 v2= rootOf (newMipo); 1091 } 1092 else 1093 { 1094 zz_pX NTLIrredpoly; 1095 BuildIrred (NTLIrredpoly, d*2); 1096 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1)); 1097 v2= rootOf (newMipo); 1098 } 1099 imPrimElem= mapPrimElem (primElem, a, v2); 1100 extOfExt= true; 1101 } 1102 else if ((p == 3 && d < 4) || ((p == 5 || p == 7) && d < 3)) 1103 { 1104 if (fac_NTL_char != p) 1105 { 1106 fac_NTL_char= p; 1107 zz_p::init (p); 1108 } 1109 bool primFail= false; 1110 Variable vBuf; 1111 primElem= primitiveElement (a, vBuf, primFail); 1112 ASSERT (!primFail, "failure in integer factorizer"); 1113 zz_pX NTLIrredpoly; 1114 BuildIrred (NTLIrredpoly, d*2); 1115 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1)); 1116 v2= rootOf (newMipo); 1117 imPrimElem= mapPrimElem (primElem, a, v2); 1118 extOfExt= true; 1119 } 1120 if (extOfExt) 1121 { 1122 maxeval= tmin (2*ipower (p, degree (getMipo (v2))), maxNumEval); 1123 F= mapUp (F, a, v2, primElem, imPrimElem, source, dest); 1124 G= mapUp (G, a, v2, primElem, imPrimElem, source, dest); 1125 a= v2; 1126 } 1127 } 1128 1129 lcF = LC( F, x ); lcG = LC( G, x ); 1130 lcD = gcd( lcF, lcG ); 1131 1132 delta = 0; 1133 degF = degree( F, x ); degG = degree( G, x ); 1134 1135 if(hasFirstAlgVar(G,a)) 1136 b = REvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) ); 1137 else 1138 { // both not in extension given by algebraic variable 1139 if (CFFactory::gettype() != GaloisFieldDomain) 1140 b = REvaluation( 2, tmax(F.level(), G.level()), FFRandom() ); 1141 else 1142 b = REvaluation( 2, tmax(F.level(), G.level()), GFRandom() ); 1143 } 1144 1145 CanonicalForm cand, contcand; 1146 CanonicalForm result; 1147 int o, t; 1148 o= 0; 1149 t= 1; 1150 int goodPointCount= 0; 1151 while( !gcdfound ) 1152 { 1153 TIMING_START (ez_p_eval); 1154 if( !findeval_P( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count, o, 1155 maxeval/maxNumVars, t )) 1156 { // too many eval. used --> try another method 1157 Off (SW_USE_EZGCD_P); 1158 result= gcd (F,G); 1159 On (SW_USE_EZGCD_P); 1160 if (passToGF) 1161 { 1162 CanonicalForm mipo= gf_mipo; 1163 setCharacteristic (p); 1164 Variable alpha= rootOf (mipo.mapinto()); 1165 result= GF2FalphaRep (result, alpha); 1166 } 1167 if (k > 1) 1168 { 1169 result= GFMapDown (result, k); 1170 setCharacteristic (p, k, gf_name); 1171 } 1172 if (extOfExt) 1173 result= mapDown (result, primElem, imPrimElem, oldA, dest, source); 1174 return N (d*result); 1175 } 1176 TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P1: "); 1177 delta = degree( Db ); 1178 if (delta == degF) 1179 { 1180 if (degF <= degG && fdivides (F, G)) 1181 { 1182 if (passToGF) 1183 { 1184 CanonicalForm mipo= gf_mipo; 1185 setCharacteristic (p); 1186 Variable alpha= rootOf (mipo.mapinto()); 1187 F= GF2FalphaRep (F, alpha); 1188 } 1189 if (k > 1) 1190 { 1191 F= GFMapDown (F, k); 1192 setCharacteristic (p, k, gf_name); 1193 } 1194 if (extOfExt) 1195 F= mapDown (F, primElem, imPrimElem, oldA, dest, source); 1196 return N (d*F); 1197 } 1198 else 1199 delta--; 1200 } 1201 else if (delta == degG) 1202 { 1203 if (degG <= degF && fdivides (G, F)) 1204 { 1205 if (passToGF) 1206 { 1207 CanonicalForm mipo= gf_mipo; 1208 setCharacteristic (p); 1209 Variable alpha= rootOf (mipo.mapinto()); 1210 G= GF2FalphaRep (G, alpha); 1211 } 1212 if (k > 1) 1213 { 1214 G= GFMapDown (G, k); 1215 setCharacteristic (p, k, gf_name); 1216 } 1217 if (extOfExt) 1218 G= mapDown (G, primElem, imPrimElem, oldA, dest, source); 1219 return N (d*G); 1220 } 1221 else 1222 delta--; 1223 } 1224 if( delta == 0 ) 1225 { 1226 if (passToGF) 1227 setCharacteristic (p); 1228 if (k > 1) 1229 setCharacteristic (p, k, gf_name); 1230 return N (d); 1231 } 1232 while( true ) 1233 { 1234 bt = b; 1235 TIMING_START (ez_p_eval); 1236 if( !findeval_P(F,G,Fbt,Gbt,Dbt, bt, delta, degF, degG, maxeval, count, o, 1237 maxeval/maxNumVars, t )) 1238 { // too many eval. used --> try another method 1239 Off (SW_USE_EZGCD_P); 1240 result= gcd (F,G); 1241 On (SW_USE_EZGCD_P); 1242 if (passToGF) 1243 { 1244 CanonicalForm mipo= gf_mipo; 1245 setCharacteristic (p); 1246 Variable alpha= rootOf (mipo.mapinto()); 1247 result= GF2FalphaRep (result, alpha); 1248 } 1249 if (k > 1) 1250 { 1251 result= GFMapDown (result, k); 1252 setCharacteristic (p, k, gf_name); 1253 } 1254 if (extOfExt) 1255 result= mapDown (result, primElem, imPrimElem, oldA, dest, source); 1256 return N (d*result); 1257 } 1258 TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P2: "); 1259 int dd = degree( Dbt ); 1260 if( dd == 0 ) 1261 { 1262 if (passToGF) 1263 setCharacteristic (p); 1264 if (k > 1) 1265 setCharacteristic (p, k, gf_name); 1266 return N (d); 1267 } 1268 if( dd == delta ) 1269 { 1270 goodPointCount++; 1271 if (goodPointCount == 5) 1272 break; 1273 } 1274 if( dd < delta ) 1275 { 1276 goodPointCount= 0; 1277 delta = dd; 1278 b = bt; 1279 Db = Dbt; Fb = Fbt; Gb = Gbt; 1280 } 1281 if (delta == degF) 1282 { 1283 if (degF <= degG && fdivides (F, G)) 1284 { 1285 if (passToGF) 1286 { 1287 CanonicalForm mipo= gf_mipo; 1288 setCharacteristic (p); 1289 Variable alpha= rootOf (mipo.mapinto()); 1290 F= GF2FalphaRep (F, alpha); 1291 } 1292 if (k > 1) 1293 { 1294 F= GFMapDown (F, k); 1295 setCharacteristic (p, k, gf_name); 1296 } 1297 if (extOfExt) 1298 F= mapDown (F, primElem, imPrimElem, oldA, dest, source); 1299 return N (d*F); 1300 } 1301 else 1302 delta--; 1303 } 1304 else if (delta == degG) 1305 { 1306 if (degG <= degF && fdivides (G, F)) 1307 { 1308 if (passToGF) 1309 { 1310 CanonicalForm mipo= gf_mipo; 1311 setCharacteristic (p); 1312 Variable alpha= rootOf (mipo.mapinto()); 1313 G= GF2FalphaRep (G, alpha); 1314 } 1315 if (k > 1) 1316 { 1317 G= GFMapDown (G, k); 1318 setCharacteristic (p, k, gf_name); 1319 } 1320 if (extOfExt) 1321 G= mapDown (G, primElem, imPrimElem, oldA, dest, source); 1322 return N (d*G); 1323 } 1324 else 1325 delta--; 1326 } 1327 if( delta == 0 ) 1328 { 1329 if (passToGF) 1330 setCharacteristic (p); 1331 if (k > 1) 1332 setCharacteristic (p, k, gf_name); 1333 return N (d); 1334 } 1335 } 1336 if( delta != degF && delta != degG ) 1337 { 1338 bool B_is_F; 1339 CanonicalForm xxx1, xxx2; 1340 CanonicalForm buf; 1341 DD[1] = Fb / Db; 1342 buf= Gb/Db; 1343 xxx1 = gcd( DD[1], Db ); 1344 xxx2 = gcd( buf, Db ); 1345 if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 1346 (size (F) <= size (G))) 1347 || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain())) 1348 { 1349 B = F; 1350 DD[2] = Db; 1351 lcDD[1] = lcF; 1352 lcDD[2] = lcD; 1353 B_is_F = true; 1354 } 1355 else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 1356 (size (G) < size (F))) 1357 || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain())) 1358 { 1359 DD[1] = buf; 1360 B = G; 1361 DD[2] = Db; 1362 lcDD[1] = lcG; 1363 lcDD[2] = lcD; 1364 B_is_F = false; 1365 } 1366 else // special case handling 1367 { 1368 Off (SW_USE_EZGCD_P); 1369 result= gcd (F,G); 1370 On (SW_USE_EZGCD_P); 1371 if (passToGF) 1372 { 1373 CanonicalForm mipo= gf_mipo; 1374 setCharacteristic (p); 1375 Variable alpha= rootOf (mipo.mapinto()); 1376 result= GF2FalphaRep (result, alpha); 1377 } 1378 if (k > 1) 1379 { 1380 result= GFMapDown (result, k); 1381 setCharacteristic (p, k, gf_name); 1382 } 1383 if (extOfExt) 1384 result= mapDown (result, primElem, imPrimElem, oldA, dest, source); 1385 return N (d*result); 1386 } 1387 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) ); 1388 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) ); 1389 1390 if (size (B*lcDD[2])/maxNumVars > sizePerVars1) 1391 { 1392 if (algExtension) 1393 { 1394 result= GCD_Fp_extension (F, G, a); 1395 if (extOfExt) 1396 result= mapDown (result, primElem, imPrimElem, oldA, dest, source); 1397 return N (d*result); 1398 } 1399 if (CFFactory::gettype() == GaloisFieldDomain) 1400 { 1401 result= GCD_GF (F, G); 1402 if (passToGF) 1403 { 1404 CanonicalForm mipo= gf_mipo; 1405 setCharacteristic (p); 1406 Variable alpha= rootOf (mipo.mapinto()); 1407 result= GF2FalphaRep (result, alpha); 1408 } 1409 if (k > 1) 1410 { 1411 result= GFMapDown (result, k); 1412 setCharacteristic (p, k, gf_name); 1413 } 1414 return N (d*result); 1415 } 1416 else 1417 return N (d*GCD_small_p (F,G)); 1418 } 1419 1420 TIMING_START (ez_p_hensel_lift); 1421 gcdfound= Hensel_P (B*lcD, DD, b, lcDD); 1422 TIMING_END_AND_PRINT (ez_p_hensel_lift, "time for Hensel lift in EZ_P: "); 1423 1424 if (gcdfound == -1) //things became dense 1425 { 1426 if (algExtension) 1427 { 1428 result= GCD_Fp_extension (F, G, a); 1429 if (extOfExt) 1430 result= mapDown (result, primElem, imPrimElem, oldA, dest, source); 1431 return N (d*result); 1432 } 1433 if (CFFactory::gettype() == GaloisFieldDomain) 1434 { 1435 result= GCD_GF (F, G); 1436 if (passToGF) 1437 { 1438 CanonicalForm mipo= gf_mipo; 1439 setCharacteristic (p); 1440 Variable alpha= rootOf (mipo.mapinto()); 1441 result= GF2FalphaRep (result, alpha); 1442 } 1443 if (k > 1) 1444 { 1445 result= GFMapDown (result, k); 1446 setCharacteristic (p, k, gf_name); 1447 } 1448 return N (d*result); 1449 } 1450 else 1451 { 1452 if (p >= cf_getBigPrime(0)) 1453 return N (d*sparseGCDFp (F,G)); 1454 else 1455 return N (d*GCD_small_p (F,G)); 1456 } 1457 } 1458 1459 if (gcdfound == 1) 1460 { 1461 TIMING_START (termination_test); 1462 contcand= content (DD[2], Variable (1)); 1463 cand = DD[2] / contcand; 1464 if (B_is_F) 1465 gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F; 1466 else 1467 gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G; 1468 TIMING_END_AND_PRINT (termination_test, 1469 "time for termination test EZ_P: "); 1470 1471 if (passToGF && gcdfound) 1472 { 1473 CanonicalForm mipo= gf_mipo; 1474 setCharacteristic (p); 1475 Variable alpha= rootOf (mipo.mapinto()); 1476 cand= GF2FalphaRep (cand, alpha); 1477 } 1478 if (k > 1 && gcdfound) 1479 { 1480 cand= GFMapDown (cand, k); 1481 setCharacteristic (p, k, gf_name); 1482 } 1483 if (extOfExt && gcdfound) 1484 cand= mapDown (cand, primElem, imPrimElem, oldA, dest, source); 1485 } 1486 } 1487 delta--; 1488 goodPointCount= 0; 1489 } 1490 return N (d*cand); 1491 } 1492 -
factory/cf_gcd_smallp.cc
rbaa2c3a rf1e3bf5 3856 3856 } 3857 3857 3858 static inline3859 int compress4EZGCD (const CanonicalForm& F, const CanonicalForm& G, CFMap & M,3860 CFMap & N, int& both_non_zero)3861 {3862 int n= tmax (F.level(), G.level());3863 int * degsf= new int [n + 1];3864 int * degsg= new int [n + 1];3865 3866 for (int i = 0; i <= n; i++)3867 degsf[i]= degsg[i]= 0;3868 3869 degsf= degrees (F, degsf);3870 degsg= degrees (G, degsg);3871 3872 both_non_zero= 0;3873 int f_zero= 0;3874 int g_zero= 0;3875 3876 for (int i= 1; i <= n; i++)3877 {3878 if (degsf[i] != 0 && degsg[i] != 0)3879 {3880 both_non_zero++;3881 continue;3882 }3883 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())3884 {3885 f_zero++;3886 continue;3887 }3888 if (degsg[i] == 0 && degsf[i] && i <= F.level())3889 {3890 g_zero++;3891 continue;3892 }3893 }3894 3895 if (both_non_zero == 0)3896 {3897 delete [] degsf;3898 delete [] degsg;3899 return 0;3900 }3901 3902 // map Variables which do not occur in both polynomials to higher levels3903 int k= 1;3904 int l= 1;3905 for (int i= 1; i <= n; i++)3906 {3907 if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level())3908 {3909 if (k + both_non_zero != i)3910 {3911 M.newpair (Variable (i), Variable (k + both_non_zero));3912 N.newpair (Variable (k + both_non_zero), Variable (i));3913 }3914 k++;3915 }3916 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level())3917 {3918 if (l + g_zero + both_non_zero != i)3919 {3920 M.newpair (Variable (i), Variable (l + g_zero + both_non_zero));3921 N.newpair (Variable (l + g_zero + both_non_zero), Variable (i));3922 }3923 l++;3924 }3925 }3926 3927 // sort Variables x_{i} in decreasing order of3928 // min(deg_{x_{i}}(f),deg_{x_{i}}(g))3929 int m= tmin (F.level(), G.level());3930 int max_min_deg;3931 k= both_non_zero;3932 l= 0;3933 int i= 1;3934 while (k > 0)3935 {3936 max_min_deg= tmin (degsf[i], degsg[i]);3937 while (max_min_deg == 0)3938 {3939 i++;3940 max_min_deg= tmin (degsf[i], degsg[i]);3941 }3942 for (int j= i + 1; j <= m; j++)3943 {3944 if ((tmin (degsf[j],degsg[j]) < max_min_deg) &&3945 (tmin (degsf[j], degsg[j]) != 0))3946 {3947 max_min_deg= tmin (degsf[j], degsg[j]);3948 l= j;3949 }3950 }3951 3952 if (l != 0)3953 {3954 if (l != k)3955 {3956 M.newpair (Variable (l), Variable(k));3957 N.newpair (Variable (k), Variable(l));3958 degsf[l]= 0;3959 degsg[l]= 0;3960 l= 0;3961 }3962 else3963 {3964 degsf[l]= 0;3965 degsg[l]= 0;3966 l= 0;3967 }3968 }3969 else if (l == 0)3970 {3971 if (i != k)3972 {3973 M.newpair (Variable (i), Variable (k));3974 N.newpair (Variable (k), Variable (i));3975 degsf[i]= 0;3976 degsg[i]= 0;3977 }3978 else3979 {3980 degsf[i]= 0;3981 degsg[i]= 0;3982 }3983 i++;3984 }3985 k--;3986 }3987 3988 delete [] degsf;3989 delete [] degsg;3990 3991 return both_non_zero;3992 }3993 3994 static inline3995 CanonicalForm myShift2Zero (const CanonicalForm& F, CFList& Feval,3996 const CFList& evaluation)3997 {3998 CanonicalForm A= F;3999 int k= 2;4000 for (CFListIterator i= evaluation; i.hasItem(); i++, k++)4001 A= A (Variable (k) + i.getItem(), k);4002 4003 CanonicalForm buf= A;4004 Feval= CFList();4005 Feval.append (buf);4006 for (k= evaluation.length() + 1; k > 2; k--)4007 {4008 buf= mod (buf, Variable (k));4009 Feval.insert (buf);4010 }4011 return A;4012 }4013 4014 static inline4015 CanonicalForm myReverseShift (const CanonicalForm& F, const CFList& evaluation)4016 {4017 int l= evaluation.length() + 1;4018 CanonicalForm result= F;4019 CFListIterator j= evaluation;4020 for (int i= 2; i < l + 1; i++, j++)4021 {4022 if (F.level() < i)4023 continue;4024 result= result (Variable (i) - j.getItem(), i);4025 }4026 return result;4027 }4028 4029 static inline4030 Evaluation optimize4Lift (const CanonicalForm& F, CFMap & M,4031 CFMap & N, const Evaluation& A)4032 {4033 int n= F.level();4034 int * degsf= new int [n + 1];4035 4036 for (int i = 0; i <= n; i++)4037 degsf[i]= 0;4038 4039 degsf= degrees (F, degsf);4040 4041 Evaluation result= Evaluation (A.min(), A.max());4042 ASSERT (A.min() == 2, "expected A.min() == 2");4043 int max_deg;4044 int k= n;4045 int l= 1;4046 int i= 2;4047 int pos= 2;4048 while (k > 1)4049 {4050 max_deg= degsf [i];4051 while (max_deg == 0)4052 {4053 i++;4054 max_deg= degsf [i];4055 }4056 l= i;4057 for (int j= i + 1; j <= n; j++)4058 {4059 if (degsf[j] > max_deg)4060 {4061 max_deg= degsf[j];4062 l= j;4063 }4064 }4065 4066 if (l <= n)4067 {4068 if (l != pos)4069 {4070 result.setValue (pos, A [l]);4071 M.newpair (Variable (l), Variable (pos));4072 N.newpair (Variable (pos), Variable (l));4073 degsf[l]= 0;4074 l= 2;4075 if (k == 2 && n == 3)4076 {4077 result.setValue (l, A [pos]);4078 M.newpair (Variable (pos), Variable (l));4079 N.newpair (Variable (l), Variable (pos));4080 degsf[pos]= 0;4081 }4082 }4083 else4084 {4085 result.setValue (l, A [l]);4086 degsf [l]= 0;4087 }4088 }4089 pos++;4090 k--;4091 l= 2;4092 }4093 4094 delete [] degsf;4095 4096 return result;4097 }4098 4099 static inline4100 int Hensel_P (const CanonicalForm & UU, CFArray & G, const Evaluation & AA,4101 const CFArray& LeadCoeffs )4102 {4103 CFList factors;4104 factors.append (G[1]);4105 factors.append (G[2]);4106 4107 CFMap NN, MM;4108 Evaluation A= optimize4Lift (UU, MM, NN, AA);4109 4110 CanonicalForm U= MM (UU);4111 CFArray LCs= CFArray (1,2);4112 LCs [1]= MM (LeadCoeffs [1]);4113 LCs [2]= MM (LeadCoeffs [2]);4114 4115 CFList evaluation;4116 long termEstimate= size (U);4117 for (int i= A.min(); i <= A.max(); i++)4118 {4119 if (!A[i].isZero() && (getCharacteristic() > degree (U,i))) //TODO find a good estimate for getCharacteristic() <= degree (U,i)4120 {4121 termEstimate *= degree (U,i)*2;4122 termEstimate /= 3;4123 }4124 evaluation.append (A [i]);4125 }4126 if (termEstimate/getNumVars(U) > 500)4127 return -1;4128 CFList UEval;4129 CanonicalForm shiftedU= myShift2Zero (U, UEval, evaluation);4130 4131 if (size (shiftedU)/getNumVars (U) > 500)4132 return -1;4133 4134 CFArray shiftedLCs= CFArray (2);4135 CFList shiftedLCsEval1, shiftedLCsEval2;4136 shiftedLCs[0]= myShift2Zero (LCs[1], shiftedLCsEval1, evaluation);4137 shiftedLCs[1]= myShift2Zero (LCs[2], shiftedLCsEval2, evaluation);4138 factors.insert (1);4139 int liftBound= degree (UEval.getLast(), 2) + 1;4140 CFArray Pi;4141 CFMatrix M= CFMatrix (liftBound, factors.length() - 1);4142 CFList diophant;4143 CFArray lcs= CFArray (2);4144 lcs [0]= shiftedLCsEval1.getFirst();4145 lcs [1]= shiftedLCsEval2.getFirst();4146 nonMonicHenselLift12 (UEval.getFirst(), factors, liftBound, Pi, diophant, M,4147 lcs, false);4148 4149 for (CFListIterator i= factors; i.hasItem(); i++)4150 {4151 if (!fdivides (i.getItem(), UEval.getFirst()))4152 return 0;4153 }4154 4155 int * liftBounds;4156 bool noOneToOne= false;4157 if (U.level() > 2)4158 {4159 liftBounds= new int [U.level() - 1]; /* index: 0.. U.level()-2 */4160 liftBounds[0]= liftBound;4161 for (int i= 1; i < U.level() - 1; i++)4162 liftBounds[i]= degree (shiftedU, Variable (i + 2)) + 1;4163 factors= nonMonicHenselLift2 (UEval, factors, liftBounds, U.level() - 1,4164 false, shiftedLCsEval1, shiftedLCsEval2, Pi,4165 diophant, noOneToOne);4166 delete [] liftBounds;4167 if (noOneToOne)4168 return 0;4169 }4170 G[1]= factors.getFirst();4171 G[2]= factors.getLast();4172 G[1]= myReverseShift (G[1], evaluation);4173 G[2]= myReverseShift (G[2], evaluation);4174 G[1]= NN (G[1]);4175 G[2]= NN (G[2]);4176 return 1;4177 }4178 4179 static inline4180 bool findeval_P (const CanonicalForm & F, const CanonicalForm & G,4181 CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db,4182 REvaluation & b, int delta, int degF, int degG, int maxeval,4183 int & count, int& k, int bound, int& l)4184 {4185 if( count == 0 && delta != 0)4186 {4187 if( count++ > maxeval )4188 return false;4189 }4190 if (count > 0)4191 {4192 b.nextpoint(k);4193 if (k == 0)4194 k++;4195 l++;4196 if (l > bound)4197 {4198 l= 1;4199 k++;4200 if (k > tmax (F.level(), G.level()) - 1)4201 return false;4202 b.nextpoint (k);4203 }4204 if (count++ > maxeval)4205 return false;4206 }4207 while( true )4208 {4209 Fb = b( F );4210 if( degree( Fb, 1 ) == degF )4211 {4212 Gb = b( G );4213 if( degree( Gb, 1 ) == degG )4214 {4215 Db = gcd( Fb, Gb );4216 if( delta > 0 )4217 {4218 if( degree( Db, 1 ) <= delta )4219 return true;4220 }4221 else4222 return true;4223 }4224 }4225 if (k == 0)4226 k++;4227 b.nextpoint(k);4228 l++;4229 if (l > bound)4230 {4231 l= 1;4232 k++;4233 if (k > tmax (F.level(), G.level()) - 1)4234 return false;4235 b.nextpoint (k);4236 }4237 if( count++ > maxeval )4238 return false;4239 }4240 }4241 4242 // parameters for heuristic4243 static int maxNumEval= 200;4244 static int sizePerVars1= 500; //try dense gcd if size/#variables is bigger4245 4246 /// Extended Zassenhaus GCD for finite fields4247 CanonicalForm EZGCD_P( const CanonicalForm & FF, const CanonicalForm & GG )4248 {4249 if (FF.isZero() && degree(GG) > 0) return GG/Lc(GG);4250 else if (GG.isZero() && degree (FF) > 0) return FF/Lc(FF);4251 else if (FF.isZero() && GG.isZero()) return FF.genOne();4252 if (FF.inBaseDomain() || GG.inBaseDomain()) return FF.genOne();4253 if (FF.isUnivariate() && fdivides(FF, GG)) return FF/Lc(FF);4254 if (GG.isUnivariate() && fdivides(GG, FF)) return GG/Lc(GG);4255 if (FF == GG) return FF/Lc(FF);4256 4257 int maxNumVars= tmax (getNumVars (FF), getNumVars (GG));4258 Variable a, oldA;4259 int sizeF= size (FF);4260 int sizeG= size (GG);4261 4262 if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1)4263 {4264 if (hasFirstAlgVar (FF, a) || hasFirstAlgVar (GG, a))4265 return GCD_Fp_extension (FF, GG, a);4266 else if (CFFactory::gettype() == GaloisFieldDomain)4267 return GCD_GF (FF, GG);4268 else4269 return GCD_small_p (FF, GG);4270 }4271 4272 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG,4273 lcD;4274 CFArray DD( 1, 2 ), lcDD( 1, 2 );4275 int degF, degG, delta, count;4276 int maxeval;4277 maxeval= tmin((getCharacteristic()/4278 (int)(ilog2(getCharacteristic())*log2exp))*2, maxNumEval);4279 count= 0; // number of eval. used4280 REvaluation b, bt;4281 int gcdfound = 0;4282 Variable x = Variable(1);4283 4284 F= FF;4285 G= GG;4286 4287 CFMap M,N;4288 int smallestDegLev;4289 TIMING_START (ez_p_compress)4290 int best_level= compress4EZGCD (F, G, M, N, smallestDegLev);4291 4292 if (best_level == 0) return G.genOne();4293 4294 F= M (F);4295 G= M (G);4296 TIMING_END_AND_PRINT (ez_p_compress, "time for compression in EZ_P: ")4297 4298 TIMING_START (ez_p_content)4299 f = content( F, x ); g = content( G, x );4300 d = gcd( f, g );4301 F /= f; G /= g;4302 TIMING_END_AND_PRINT (ez_p_content, "time to extract content in EZ_P: ")4303 4304 if( F.isUnivariate() && G.isUnivariate() )4305 {4306 if( F.mvar() == G.mvar() )4307 d *= gcd( F, G );4308 else4309 return N (d);4310 return N (d);4311 }4312 if ( F.isUnivariate())4313 {4314 g= content (G,G.mvar());4315 return N(d*gcd(F,g));4316 }4317 if ( G.isUnivariate())4318 {4319 f= content (F,F.mvar());4320 return N(d*gcd(G,f));4321 }4322 4323 maxNumVars= tmax (getNumVars (F), getNumVars (G));4324 sizeF= size (F);4325 sizeG= size (G);4326 4327 if (sizeF/maxNumVars > sizePerVars1 && sizeG/maxNumVars > sizePerVars1)4328 {4329 if (hasFirstAlgVar (F, a) || hasFirstAlgVar (G, a))4330 return N (d*GCD_Fp_extension (F, G, a));4331 else if (CFFactory::gettype() == GaloisFieldDomain)4332 return N (d*GCD_GF (F, G));4333 else4334 return N (d*GCD_small_p (F, G));4335 }4336 4337 int dummy= 0;4338 if( gcd_test_one( F, G, false, dummy ) )4339 {4340 return N (d);4341 }4342 4343 bool passToGF= false;4344 bool extOfExt= false;4345 int p= getCharacteristic();4346 bool algExtension= (hasFirstAlgVar(F,a) || hasFirstAlgVar(G,a));4347 int k= 1;4348 CanonicalForm primElem, imPrimElem;4349 CFList source, dest;4350 if (p < 50 && CFFactory::gettype() != GaloisFieldDomain && !algExtension)4351 {4352 if (p == 2)4353 setCharacteristic (2, 12, 'Z');4354 else if (p == 3)4355 setCharacteristic (3, 4, 'Z');4356 else if (p == 5 || p == 7)4357 setCharacteristic (p, 3, 'Z');4358 else4359 setCharacteristic (p, 2, 'Z');4360 passToGF= true;4361 F= F.mapinto();4362 G= G.mapinto();4363 maxeval= 2*ipower (p, getGFDegree());4364 }4365 else if (CFFactory::gettype() == GaloisFieldDomain &&4366 ipower (p , getGFDegree()) < 50)4367 {4368 k= getGFDegree();4369 if (ipower (p, 2*k) > 50)4370 setCharacteristic (p, 2*k, gf_name);4371 else4372 setCharacteristic (p, 3*k, gf_name);4373 F= GFMapUp (F, k);4374 G= GFMapUp (G, k);4375 maxeval= tmin (2*ipower (p, getGFDegree()), maxNumEval);4376 }4377 else if (p < 50 && algExtension && CFFactory::gettype() != GaloisFieldDomain)4378 {4379 int d= degree (getMipo (a));4380 oldA= a;4381 Variable v2;4382 if (p == 2 && d < 6)4383 {4384 if (fac_NTL_char != p)4385 {4386 fac_NTL_char= p;4387 zz_p::init (p);4388 }4389 bool primFail= false;4390 Variable vBuf;4391 primElem= primitiveElement (a, vBuf, primFail);4392 ASSERT (!primFail, "failure in integer factorizer");4393 if (d < 3)4394 {4395 zz_pX NTLIrredpoly;4396 BuildIrred (NTLIrredpoly, d*3);4397 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));4398 v2= rootOf (newMipo);4399 }4400 else4401 {4402 zz_pX NTLIrredpoly;4403 BuildIrred (NTLIrredpoly, d*2);4404 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));4405 v2= rootOf (newMipo);4406 }4407 imPrimElem= mapPrimElem (primElem, a, v2);4408 extOfExt= true;4409 }4410 else if ((p == 3 && d < 4) || ((p == 5 || p == 7) && d < 3))4411 {4412 if (fac_NTL_char != p)4413 {4414 fac_NTL_char= p;4415 zz_p::init (p);4416 }4417 bool primFail= false;4418 Variable vBuf;4419 primElem= primitiveElement (a, vBuf, primFail);4420 ASSERT (!primFail, "failure in integer factorizer");4421 zz_pX NTLIrredpoly;4422 BuildIrred (NTLIrredpoly, d*2);4423 CanonicalForm newMipo= convertNTLzzpX2CF (NTLIrredpoly, Variable (1));4424 v2= rootOf (newMipo);4425 imPrimElem= mapPrimElem (primElem, a, v2);4426 extOfExt= true;4427 }4428 if (extOfExt)4429 {4430 maxeval= tmin (2*ipower (p, degree (getMipo (v2))), maxNumEval);4431 F= mapUp (F, a, v2, primElem, imPrimElem, source, dest);4432 G= mapUp (G, a, v2, primElem, imPrimElem, source, dest);4433 a= v2;4434 }4435 }4436 4437 lcF = LC( F, x ); lcG = LC( G, x );4438 lcD = gcd( lcF, lcG );4439 4440 delta = 0;4441 degF = degree( F, x ); degG = degree( G, x );4442 4443 if(hasFirstAlgVar(G,a))4444 b = REvaluation( 2, tmax(F.level(), G.level()), AlgExtRandomF( a ) );4445 else4446 { // both not in extension given by algebraic variable4447 if (CFFactory::gettype() != GaloisFieldDomain)4448 b = REvaluation( 2, tmax(F.level(), G.level()), FFRandom() );4449 else4450 b = REvaluation( 2, tmax(F.level(), G.level()), GFRandom() );4451 }4452 4453 CanonicalForm cand, contcand;4454 CanonicalForm result;4455 int o, t;4456 o= 0;4457 t= 1;4458 int goodPointCount= 0;4459 while( !gcdfound )4460 {4461 TIMING_START (ez_p_eval);4462 if( !findeval_P( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count, o,4463 maxeval/maxNumVars, t ))4464 { // too many eval. used --> try another method4465 Off (SW_USE_EZGCD_P);4466 result= gcd (F,G);4467 On (SW_USE_EZGCD_P);4468 if (passToGF)4469 {4470 CanonicalForm mipo= gf_mipo;4471 setCharacteristic (p);4472 Variable alpha= rootOf (mipo.mapinto());4473 result= GF2FalphaRep (result, alpha);4474 }4475 if (k > 1)4476 {4477 result= GFMapDown (result, k);4478 setCharacteristic (p, k, gf_name);4479 }4480 if (extOfExt)4481 result= mapDown (result, primElem, imPrimElem, oldA, dest, source);4482 return N (d*result);4483 }4484 TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P1: ");4485 delta = degree( Db );4486 if (delta == degF)4487 {4488 if (degF <= degG && fdivides (F, G))4489 {4490 if (passToGF)4491 {4492 CanonicalForm mipo= gf_mipo;4493 setCharacteristic (p);4494 Variable alpha= rootOf (mipo.mapinto());4495 F= GF2FalphaRep (F, alpha);4496 }4497 if (k > 1)4498 {4499 F= GFMapDown (F, k);4500 setCharacteristic (p, k, gf_name);4501 }4502 if (extOfExt)4503 F= mapDown (F, primElem, imPrimElem, oldA, dest, source);4504 return N (d*F);4505 }4506 else4507 delta--;4508 }4509 else if (delta == degG)4510 {4511 if (degG <= degF && fdivides (G, F))4512 {4513 if (passToGF)4514 {4515 CanonicalForm mipo= gf_mipo;4516 setCharacteristic (p);4517 Variable alpha= rootOf (mipo.mapinto());4518 G= GF2FalphaRep (G, alpha);4519 }4520 if (k > 1)4521 {4522 G= GFMapDown (G, k);4523 setCharacteristic (p, k, gf_name);4524 }4525 if (extOfExt)4526 G= mapDown (G, primElem, imPrimElem, oldA, dest, source);4527 return N (d*G);4528 }4529 else4530 delta--;4531 }4532 if( delta == 0 )4533 {4534 if (passToGF)4535 setCharacteristic (p);4536 if (k > 1)4537 setCharacteristic (p, k, gf_name);4538 return N (d);4539 }4540 while( true )4541 {4542 bt = b;4543 TIMING_START (ez_p_eval);4544 if( !findeval_P(F,G,Fbt,Gbt,Dbt, bt, delta, degF, degG, maxeval, count, o,4545 maxeval/maxNumVars, t ))4546 { // too many eval. used --> try another method4547 Off (SW_USE_EZGCD_P);4548 result= gcd (F,G);4549 On (SW_USE_EZGCD_P);4550 if (passToGF)4551 {4552 CanonicalForm mipo= gf_mipo;4553 setCharacteristic (p);4554 Variable alpha= rootOf (mipo.mapinto());4555 result= GF2FalphaRep (result, alpha);4556 }4557 if (k > 1)4558 {4559 result= GFMapDown (result, k);4560 setCharacteristic (p, k, gf_name);4561 }4562 if (extOfExt)4563 result= mapDown (result, primElem, imPrimElem, oldA, dest, source);4564 return N (d*result);4565 }4566 TIMING_END_AND_PRINT (ez_p_eval, "time for eval point search in EZ_P2: ");4567 int dd = degree( Dbt );4568 if( dd == 0 )4569 {4570 if (passToGF)4571 setCharacteristic (p);4572 if (k > 1)4573 setCharacteristic (p, k, gf_name);4574 return N (d);4575 }4576 if( dd == delta )4577 {4578 goodPointCount++;4579 if (goodPointCount == 5)4580 break;4581 }4582 if( dd < delta )4583 {4584 goodPointCount= 0;4585 delta = dd;4586 b = bt;4587 Db = Dbt; Fb = Fbt; Gb = Gbt;4588 }4589 if (delta == degF)4590 {4591 if (degF <= degG && fdivides (F, G))4592 {4593 if (passToGF)4594 {4595 CanonicalForm mipo= gf_mipo;4596 setCharacteristic (p);4597 Variable alpha= rootOf (mipo.mapinto());4598 F= GF2FalphaRep (F, alpha);4599 }4600 if (k > 1)4601 {4602 F= GFMapDown (F, k);4603 setCharacteristic (p, k, gf_name);4604 }4605 if (extOfExt)4606 F= mapDown (F, primElem, imPrimElem, oldA, dest, source);4607 return N (d*F);4608 }4609 else4610 delta--;4611 }4612 else if (delta == degG)4613 {4614 if (degG <= degF && fdivides (G, F))4615 {4616 if (passToGF)4617 {4618 CanonicalForm mipo= gf_mipo;4619 setCharacteristic (p);4620 Variable alpha= rootOf (mipo.mapinto());4621 G= GF2FalphaRep (G, alpha);4622 }4623 if (k > 1)4624 {4625 G= GFMapDown (G, k);4626 setCharacteristic (p, k, gf_name);4627 }4628 if (extOfExt)4629 G= mapDown (G, primElem, imPrimElem, oldA, dest, source);4630 return N (d*G);4631 }4632 else4633 delta--;4634 }4635 if( delta == 0 )4636 {4637 if (passToGF)4638 setCharacteristic (p);4639 if (k > 1)4640 setCharacteristic (p, k, gf_name);4641 return N (d);4642 }4643 }4644 if( delta != degF && delta != degG )4645 {4646 bool B_is_F;4647 CanonicalForm xxx1, xxx2;4648 CanonicalForm buf;4649 DD[1] = Fb / Db;4650 buf= Gb/Db;4651 xxx1 = gcd( DD[1], Db );4652 xxx2 = gcd( buf, Db );4653 if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&4654 (size (F) <= size (G)))4655 || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain()))4656 {4657 B = F;4658 DD[2] = Db;4659 lcDD[1] = lcF;4660 lcDD[2] = lcD;4661 B_is_F = true;4662 }4663 else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) &&4664 (size (G) < size (F)))4665 || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain()))4666 {4667 DD[1] = buf;4668 B = G;4669 DD[2] = Db;4670 lcDD[1] = lcG;4671 lcDD[2] = lcD;4672 B_is_F = false;4673 }4674 else // special case handling4675 {4676 Off (SW_USE_EZGCD_P);4677 result= gcd (F,G);4678 On (SW_USE_EZGCD_P);4679 if (passToGF)4680 {4681 CanonicalForm mipo= gf_mipo;4682 setCharacteristic (p);4683 Variable alpha= rootOf (mipo.mapinto());4684 result= GF2FalphaRep (result, alpha);4685 }4686 if (k > 1)4687 {4688 result= GFMapDown (result, k);4689 setCharacteristic (p, k, gf_name);4690 }4691 if (extOfExt)4692 result= mapDown (result, primElem, imPrimElem, oldA, dest, source);4693 return N (d*result);4694 }4695 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) );4696 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) );4697 4698 if (size (B*lcDD[2])/maxNumVars > sizePerVars1)4699 {4700 if (algExtension)4701 {4702 result= GCD_Fp_extension (F, G, a);4703 if (extOfExt)4704 result= mapDown (result, primElem, imPrimElem, oldA, dest, source);4705 return N (d*result);4706 }4707 if (CFFactory::gettype() == GaloisFieldDomain)4708 {4709 result= GCD_GF (F, G);4710 if (passToGF)4711 {4712 CanonicalForm mipo= gf_mipo;4713 setCharacteristic (p);4714 Variable alpha= rootOf (mipo.mapinto());4715 result= GF2FalphaRep (result, alpha);4716 }4717 if (k > 1)4718 {4719 result= GFMapDown (result, k);4720 setCharacteristic (p, k, gf_name);4721 }4722 return N (d*result);4723 }4724 else4725 return N (d*GCD_small_p (F,G));4726 }4727 4728 TIMING_START (ez_p_hensel_lift);4729 gcdfound= Hensel_P (B*lcD, DD, b, lcDD);4730 TIMING_END_AND_PRINT (ez_p_hensel_lift, "time for Hensel lift in EZ_P: ");4731 4732 if (gcdfound == -1) //things became dense4733 {4734 if (algExtension)4735 {4736 result= GCD_Fp_extension (F, G, a);4737 if (extOfExt)4738 result= mapDown (result, primElem, imPrimElem, oldA, dest, source);4739 return N (d*result);4740 }4741 if (CFFactory::gettype() == GaloisFieldDomain)4742 {4743 result= GCD_GF (F, G);4744 if (passToGF)4745 {4746 CanonicalForm mipo= gf_mipo;4747 setCharacteristic (p);4748 Variable alpha= rootOf (mipo.mapinto());4749 result= GF2FalphaRep (result, alpha);4750 }4751 if (k > 1)4752 {4753 result= GFMapDown (result, k);4754 setCharacteristic (p, k, gf_name);4755 }4756 return N (d*result);4757 }4758 else4759 {4760 if (p >= cf_getBigPrime(0))4761 return N (d*sparseGCDFp (F,G));4762 else4763 return N (d*GCD_small_p (F,G));4764 }4765 }4766 4767 if (gcdfound == 1)4768 {4769 TIMING_START (termination_test);4770 contcand= content (DD[2], Variable (1));4771 cand = DD[2] / contcand;4772 if (B_is_F)4773 gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F;4774 else4775 gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G;4776 TIMING_END_AND_PRINT (termination_test,4777 "time for termination test EZ_P: ");4778 4779 if (passToGF && gcdfound)4780 {4781 CanonicalForm mipo= gf_mipo;4782 setCharacteristic (p);4783 Variable alpha= rootOf (mipo.mapinto());4784 cand= GF2FalphaRep (cand, alpha);4785 }4786 if (k > 1 && gcdfound)4787 {4788 cand= GFMapDown (cand, k);4789 setCharacteristic (p, k, gf_name);4790 }4791 if (extOfExt && gcdfound)4792 cand= mapDown (cand, primElem, imPrimElem, oldA, dest, source);4793 }4794 }4795 delta--;4796 goodPointCount= 0;4797 }4798 return N (d*cand);4799 }4800 4801 4802 3858 #endif -
factory/cf_gcd_smallp.h
rbaa2c3a rf1e3bf5 100 100 } 101 101 102 /// extended Zassenhaus GCD103 CanonicalForm104 EZGCD_P (const CanonicalForm& A, const CanonicalForm& B);105 106 102 CanonicalForm 107 103 randomIrredpoly (int i, const Variable & x) ; -
factory/fac_util.h
rbaa2c3a rf1e3bf5 47 47 bool gcd_test_one ( const CanonicalForm & f, const CanonicalForm & g, bool swap, int & d ); 48 48 49 CanonicalForm ezgcd ( const CanonicalForm & f, const CanonicalForm & g );50 51 49 void extgcd ( const CanonicalForm & a, const CanonicalForm & b, CanonicalForm & S, CanonicalForm & T, const modpk & pk ); 52 50
Note: See TracChangeset
for help on using the changeset viewer.