Changeset e7676a in git
- Timestamp:
- May 7, 2012, 3:55:50 PM (11 years ago)
- Branches:
- (u'spielwiese', '0d6b7fcd9813a1ca1ed4220cfa2b104b97a0a003')
- Children:
- 517530b37f04ee705b7b271243a265748c447cf5dccd6db99cc44c93669e843ddb6e06d2682769b8
- Parents:
- a034968a1bff5f6e4e9ad126551a2e9a377d9f6060cc1289a79586c1732ba3885997c3cb49bc01d9
- Files:
-
- 42 added
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
Tst/Short/ok_s.lst
ra03496 re7676a 132 132 factorizep_s 133 133 factorizeQa_s 134 fermat_gcd_1var 135 fermat_gcd_2var 136 fermat_gcd_3var 137 fermat_gcd_4var 138 fermat_gcd_mod_1var 139 fermat_gcd_mod_2var 140 fermat_gcd_mod_3var 141 fermat_gcd_mod_4var 134 142 fetch_s 135 143 fglm1_s … … 141 149 gaussm_ex 142 150 gcd0_s 151 gcd2test 152 gcd3primtest 153 gcd3test 154 gcd4test 155 gcd5primtest 156 gcd5test 143 157 gcdp_s 144 158 gerhard_1_32003_lp -
factory/algext.cc
ra03496 re7676a 1 #include <factory/factoryconf.h>1 #include "config.h" 2 2 3 3 #ifndef NOSTREAMIO … … 24 24 #include "cf_map.h" 25 25 #include "cf_generator.h" 26 27 #ifdef HAVE_NTL 28 #include "NTLconvert.h" 29 #endif 26 30 27 31 /// compressing two polynomials F and G, M is used for compressing, … … 585 589 } 586 590 591 #ifdef HAVE_NTL 592 static CanonicalForm 593 myicontent ( const CanonicalForm & f, const CanonicalForm & c ) 594 { 595 if (f.isOne() || c.isOne()) 596 return 1; 597 if ( f.inBaseDomain() && c.inBaseDomain()) 598 { 599 if (c.isZero()) return abs(f); 600 return bgcd( f, c ); 601 } 602 else if ( (f.inCoeffDomain() && c.inCoeffDomain()) || 603 (f.inCoeffDomain() && c.inBaseDomain()) || 604 (f.inBaseDomain() && c.inCoeffDomain())) 605 { 606 if (c.isZero()) return abs (f); 607 ZZX NTLf= convertFacCF2NTLZZX (f); 608 ZZX NTLc= convertFacCF2NTLZZX (c); 609 NTLc= GCD (NTLc, NTLf); 610 if (f.inCoeffDomain()) 611 return convertNTLZZX2CF(NTLc,f.mvar()); 612 else 613 return convertNTLZZX2CF(NTLc,c.mvar()); 614 } 615 else 616 { 617 CanonicalForm g = c; 618 for ( CFIterator i = f; i.hasTerms() && ! g.isOne(); i++ ) 619 g = myicontent( i.coeff(), g ); 620 return g; 621 } 622 } 623 #endif 624 625 CanonicalForm 626 myicontent ( const CanonicalForm & f ) 627 { 628 #ifdef HAVE_NTL 629 return myicontent( f, 0 ); 630 #else 631 return 1; 632 #endif 633 } 634 587 635 CanonicalForm QGCD( const CanonicalForm & F, const CanonicalForm & G ) 588 636 { // f,g in Q(a)[x1,...,xn] … … 612 660 f = F * bCommonDen(F); 613 661 g = G * bCommonDen(G); 662 CanonicalForm contf= myicontent (f); 663 CanonicalForm contg= myicontent (g); 664 f /= contf; 665 g /= contg; 666 CanonicalForm gcdcfcg= myicontent (contf, contg); 614 667 Variable a, b; 615 668 if(hasFirstAlgVar(f,a)) … … 627 680 Off( SW_RATIONAL ); 628 681 Off( SW_USE_QGCD ); 629 tmp = gcd ( F, G);682 tmp = gcdcfcg*gcd( f, g ); 630 683 On( SW_USE_QGCD ); 631 684 if (off_rational) Off(SW_RATIONAL); … … 682 735 if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL); 683 736 setCharacteristic(0); 684 return CanonicalForm(1);737 return gcdcfcg; 685 738 } 686 739 setCharacteristic(0); … … 712 765 setReduce(a,true); 713 766 if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL); 714 return tmp ;767 return tmp*gcdcfcg; 715 768 } 716 769 Off( SW_RATIONAL ); … … 729 782 setReduce(a,true); 730 783 Off( SW_USE_QGCD ); 731 D = gcd ( f, g );784 D = gcdcfcg*gcd( f, g ); 732 785 On( SW_USE_QGCD ); 733 786 if (off_rational) Off(SW_RATIONAL); else On(SW_RATIONAL); -
factory/cfNewtonPolygon.cc
ra03496 re7676a 222 222 } 223 223 224 int ** 225 merge (int ** points1, int sizePoints1, int ** points2, int sizePoints2, 226 int& sizeResult) 227 { 228 int i, j; 229 sizeResult= sizePoints1+sizePoints2; 230 for (i= 0; i < sizePoints1; i++) 231 { 232 for (j= 0; j < sizePoints2; j++) 233 { 234 if (points1[i][0] != points2[j][0]) 235 continue; 236 else 237 { 238 if (points1[i][1] != points2[j][1]) 239 continue; 240 else 241 { 242 points2[j][0]= -1; 243 points2[j][1]= -1; 244 sizeResult--; 245 } 246 } 247 } 248 } 249 if (sizeResult == 0) 250 return points1; 251 252 int ** result= new int *[sizeResult]; 253 for (i= 0; i < sizeResult; i++) 254 result [i]= new int [2]; 255 256 int k= 0; 257 for (i= 0; i < sizePoints1; i++, k++) 258 { 259 result[k][0]= points1[i][0]; 260 result[k][1]= points1[i][1]; 261 } 262 for (i= 0; i < sizePoints2; i++) 263 { 264 if (points2[i][0] < 0) 265 continue; 266 else 267 { 268 result[k][0]= points2[i][0]; 269 result[k][1]= points2[i][1]; 270 k++; 271 } 272 } 273 return result; 274 } 275 224 276 // assumes a bivariate poly as input 225 277 int ** newtonPolygon (const CanonicalForm& F, int& sizeOfNewtonPoly) … … 257 309 delete [] points[i]; 258 310 delete [] points; 311 312 return result; 313 } 314 315 // assumes a bivariate polys as input 316 int ** newtonPolygon (const CanonicalForm& F, const CanonicalForm& G, 317 int& sizeOfNewtonPoly) 318 { 319 int sizeF= size (F); 320 int ** pointsF= new int* [sizeF]; 321 for (int i= 0; i < sizeF; i++) 322 pointsF [i]= new int [2]; 323 int j= 0; 324 int * buf; 325 int bufSize; 326 for (CFIterator i= F; i.hasTerms(); i++) 327 { 328 buf= getDegrees (i.coeff(), bufSize); 329 for (int k= 0; k < bufSize; k++, j++) 330 { 331 pointsF [j] [0]= i.exp(); 332 pointsF [j] [1]= buf [k]; 333 } 334 delete [] buf; 335 } 336 337 int sizeG= size (G); 338 int ** pointsG= new int* [sizeG]; 339 for (int i= 0; i < sizeG; i++) 340 pointsG [i]= new int [2]; 341 j= 0; 342 for (CFIterator i= G; i.hasTerms(); i++) 343 { 344 buf= getDegrees (i.coeff(), bufSize); 345 for (int k= 0; k < bufSize; k++, j++) 346 { 347 pointsG [j] [0]= i.exp(); 348 pointsG [j] [1]= buf [k]; 349 } 350 delete [] buf; 351 } 352 353 int sizePoints; 354 int ** points= merge (pointsF, sizeF, pointsG, sizeG, sizePoints); 355 356 int n= polygon (points, sizePoints); 357 358 int ** result= new int* [n]; 359 for (int i= 0; i < n; i++) 360 { 361 result [i]= new int [2]; 362 result [i] [0]= points [i] [0]; 363 result [i] [1]= points [i] [1]; 364 } 365 366 sizeOfNewtonPoly= n; 367 for (int i= 0; i < sizeF; i++) 368 delete [] pointsF[i]; 369 delete [] pointsF; 370 for (int i= 0; i < sizeG; i++) 371 delete [] pointsG[i]; 372 delete [] pointsG; 259 373 260 374 return result; … … 484 598 485 599 CanonicalForm 486 compress (const CanonicalForm& F, mat_ZZ& M, vec_ZZ& A )600 compress (const CanonicalForm& F, mat_ZZ& M, vec_ZZ& A, bool computeMA) 487 601 { 488 602 int n; 489 int ** newtonPolyg= newtonPolygon (F, n); 490 convexDense (newtonPolyg, n, M, A); 603 int ** newtonPolyg; 604 if (computeMA) 605 { 606 newtonPolyg= newtonPolygon (F, n); 607 convexDense (newtonPolyg, n, M, A); 608 } 491 609 CanonicalForm result= 0; 492 610 ZZ expX, expY; … … 565 683 } 566 684 567 for (int i= 0; i < n; i++) 568 delete [] newtonPolyg [i]; 569 delete [] newtonPolyg; 570 571 M= inv (M); 685 if (computeMA) 686 { 687 for (int i= 0; i < n; i++) 688 delete [] newtonPolyg [i]; 689 delete [] newtonPolyg; 690 M= inv (M); 691 } 692 572 693 return result; 573 694 } -
factory/cfNewtonPolygon.h
ra03496 re7676a 40 40 ); 41 41 42 /// compute the convex hull of the support of two bivariate polynomials 43 /// 44 /// @return an array of points in the plane which are the vertices of the convex 45 /// hull of the support of F and G 46 int ** newtonPolygon (const CanonicalForm& F,///< [in] a bivariate polynomial 47 const CanonicalForm& G,///< [in] a bivariate polynomial 48 int& sizeOfNewtonPoly ///< [in, out] size of the result 49 ); 50 42 51 /// check if @a point is inside a polygon described by points 43 52 /// … … 76 85 compress (const CanonicalForm& F, ///< [in] compressed, i.e. F.level()==2, 77 86 ///< bivariate poly 78 mat_ZZ& inverseM, ///< [in,out] returns the inverse of M 79 vec_ZZ& A ///< [in,out] returns translation 87 mat_ZZ& inverseM, ///< [in,out] returns the inverse of M, 88 ///< if computeMA==true, M otherwise 89 vec_ZZ& A, ///< [in,out] returns translation 90 bool computeMA= true ///< [in] whether to compute M and A 80 91 ); 81 92 -
factory/cf_gcd.cc
ra03496 re7676a 757 757 else if (!fc_and_gc_Univariate) 758 758 { 759 if ( 760 isOn(SW_USE_CHINREM_GCD) 761 && (isPurePoly_m(fc)) && (isPurePoly_m(gc)) 762 ) 763 { 764 #if 0 765 if ( p1 == fc.level() ) 766 fc = chinrem_gcd( fc, gc ); 767 else 768 { 769 fc = replacevar( fc, Variable(p1), Variable(mp) ); 770 gc = replacevar( gc, Variable(p1), Variable(mp) ); 771 fc = replacevar( chinrem_gcd( fc, gc ), Variable(mp), Variable(p1) ); 772 } 773 #else 774 fc = chinrem_gcd( fc, gc); 775 #endif 776 } 777 else if ( isOn( SW_USE_EZGCD ) ) 778 { 779 if ( pe == 1 ) 759 if ( isOn( SW_USE_EZGCD ) ) 760 { 761 fc= ezgcd (fc, gc); 762 /*if ( pe == 1 ) 780 763 fc = ezgcd( fc, gc ); 781 764 else if ( pe > 0 )// no variable at position 1 … … 791 774 gc = swapvar( gc, Variable(pe), Variable(1) ); 792 775 fc = swapvar( ezgcd( fc, gc ), Variable(1), Variable(pe) ); 776 }*/ 777 } 778 else if ( 779 isOn(SW_USE_CHINREM_GCD) 780 && (isPurePoly_m(fc)) && (isPurePoly_m(gc)) 781 ) 782 { 783 #if 0 784 if ( p1 == fc.level() ) 785 fc = chinrem_gcd( fc, gc ); 786 else 787 { 788 fc = replacevar( fc, Variable(p1), Variable(mp) ); 789 gc = replacevar( gc, Variable(p1), Variable(mp) ); 790 fc = replacevar( chinrem_gcd( fc, gc ), Variable(mp), Variable(p1) ); 793 791 } 792 #else 793 fc = chinrem_gcd( fc, gc); 794 #endif 794 795 } 795 796 else … … 1236 1237 1237 1238 CanonicalForm Dn, test= 0; 1239 cl = gcd (f.lc(),g.lc()); 1240 CanonicalForm gcdcfcg= gcd (cf, cg); 1241 CanonicalForm b= 1; 1242 int minCommonDeg= 0; 1243 for (i= tmax (f.level(), g.level()); i > 0; i--) 1244 { 1245 if (degree (f, i) <= 0 || degree (g, i) <= 0) 1246 continue; 1247 else 1248 { 1249 minCommonDeg= tmin (degree (g, i), degree (f, i)); 1250 break; 1251 } 1252 } 1253 if (i == 0) 1254 return gcdcfcg; 1255 for (; i > 0; i--) 1256 { 1257 if (degree (f, i) <= 0 || degree (g, i) <= 0) 1258 continue; 1259 else 1260 minCommonDeg= tmin (minCommonDeg, tmin (degree (g, i), degree (f, i))); 1261 } 1262 b= 2*tmin (maxNorm (f), maxNorm (g))*abs (cl)* 1263 power (CanonicalForm (2), minCommonDeg); 1238 1264 bool equal= false; 1239 1265 i = cf_getNumBigPrimes() - 1; 1240 cl = gcd (f.lc(),g.lc()); 1241 1242 CanonicalForm gcdcfcg= gcd (cf, cg); 1266 1267 CanonicalForm cof, cog, cofp, cogp, newCof, newCog, cofn, cogn; 1243 1268 //Off (SW_RATIONAL); 1244 1269 while ( true ) … … 1246 1271 p = cf_getBigPrime( i ); 1247 1272 i--; 1248 while ( i >= 0 && mod( cl , p ) == 0 )1273 while ( i >= 0 && mod( cl*(lc(f)/cl)*(lc(g)/cl), p ) == 0 ) 1249 1274 { 1250 1275 p = cf_getBigPrime( i ); … … 1253 1278 //printf("try p=%d\n",p); 1254 1279 setCharacteristic( p ); 1255 Dp = gcd_poly( mapinto( f ), mapinto( g ));1280 Dp = GCD_small_p (mapinto (f), mapinto (g), cofp, cogp); 1256 1281 Dp /=Dp.lc(); 1282 cofp /= lc (cofp); 1283 cogp /= lc (cogp); 1257 1284 setCharacteristic( 0 ); 1258 1285 dp_deg=totaldegree(Dp); … … 1265 1292 { 1266 1293 D = mapinto( Dp ); 1294 cof= mapinto (cofp); 1295 cog= mapinto (cogp); 1267 1296 d_deg=dp_deg; 1268 1297 q = p; … … 1273 1302 { 1274 1303 chineseRemainder( D, q, mapinto( Dp ), p, newD, newq ); 1304 chineseRemainder( cof, q, mapinto (cofp), p, newCof, newq); 1305 chineseRemainder( cog, q, mapinto (cogp), p, newCog, newq); 1306 cof= newCof; 1307 cog= newCog; 1275 1308 q = newq; 1276 1309 D = newD; … … 1282 1315 q = p; 1283 1316 D = mapinto( Dp ); 1317 cof= mapinto (cof); 1318 cog= mapinto (cog); 1284 1319 d_deg=dp_deg; 1285 1320 test= 0; … … 1295 1330 { 1296 1331 Dn= Farey(D,q); 1332 cofn= Farey(cof,q); 1333 cogn= Farey(cog,q); 1297 1334 int is_rat= isOn (SW_RATIONAL); 1298 1335 On (SW_RATIONAL); 1299 1336 cd = bCommonDen( Dn ); // we need On(SW_RATIONAL) 1337 cofn *= bCommonDen (cofn); 1338 cogn *= bCommonDen (cogn); 1300 1339 if (!is_rat) 1301 1340 Off (SW_RATIONAL); … … 1306 1345 equal= true; 1307 1346 //Dn /=vcontent(Dn,Variable(1)); 1308 if (equal && fdivides( Dn, f ) && fdivides( Dn, g ) ) 1347 if ((terminationTest (f,g, cofn, cogn, Dn)) || 1348 ((equal || q > b) && fdivides (Dn, f) && fdivides (Dn, g))) 1309 1349 { 1310 1350 //printf(" -> success\n"); … … 1325 1365 } 1326 1366 1367 -
factory/cf_gcd_smallp.cc
ra03496 re7676a 34 34 #include "facHensel.h" 35 35 #include "cf_iter.h" 36 #include "cfNewtonPolygon.h" 36 37 37 38 // iinline helper functions: … … 49 50 TIMING_DEFINE_PRINT(gcd_recursion) 50 51 TIMING_DEFINE_PRINT(newton_interpolation) 52 53 bool 54 terminationTest (const CanonicalForm& F, const CanonicalForm& G, 55 const CanonicalForm& coF, const CanonicalForm& coG, 56 const CanonicalForm& cand) 57 { 58 CanonicalForm LCCand= abs (LC (cand)); 59 if (LCCand*abs (LC (coF)) == abs (LC (F))) 60 { 61 if (LCCand*abs (LC (coG)) == abs (LC (G))) 62 { 63 if (abs (cand)*abs (coF) == abs (F)) 64 { 65 if (abs (cand)*abs (coG) == abs (G)) 66 return true; 67 } 68 return false; 69 } 70 return false; 71 } 72 return false; 73 } 51 74 52 75 static const double log2exp= 1.442695041; … … 216 239 217 240 return 1; 218 }219 220 int221 substituteCheck (const CanonicalForm& F, const CanonicalForm& G)222 {223 if (F.inCoeffDomain() || G.inCoeffDomain())224 return 0;225 Variable x= Variable (1);226 if (degree (F, x) <= 1 || degree (G, x) <= 1)227 return 0;228 CanonicalForm f= swapvar (F, F.mvar(), x); //TODO swapping is pretty expensive229 CanonicalForm g= swapvar (G, G.mvar(), x);230 int sizef= 0;231 int sizeg= 0;232 for (CFIterator i= f; i.hasTerms(); i++, sizef++)233 {234 if (i.exp() == 1)235 return 0;236 }237 for (CFIterator i= g; i.hasTerms(); i++, sizeg++)238 {239 if (i.exp() == 1)240 return 0;241 }242 int * expf= new int [sizef];243 int * expg= new int [sizeg];244 int j= 0;245 for (CFIterator i= f; i.hasTerms(); i++, j++)246 {247 expf [j]= i.exp();248 }249 j= 0;250 for (CFIterator i= g; i.hasTerms(); i++, j++)251 {252 expg [j]= i.exp();253 }254 255 int indf= sizef - 1;256 int indg= sizeg - 1;257 if (expf[indf] == 0)258 indf--;259 if (expg[indg] == 0)260 indg--;261 262 if (expg[indg] != expf [indf] || (expg[indg] == 1 && expf[indf] == 1))263 {264 delete [] expg;265 delete [] expf;266 return 0;267 }268 // expf[indg] == expf[indf] after here269 int result= expg[indg];270 for (int i= indf - 1; i >= 0; i--)271 {272 if (expf [i]%result != 0)273 {274 delete [] expg;275 delete [] expf;276 return 0;277 }278 }279 280 for (int i= indg - 1; i >= 0; i--)281 {282 if (expg [i]%result != 0)283 {284 delete [] expg;285 delete [] expf;286 return 0;287 }288 }289 290 delete [] expg;291 delete [] expf;292 return result;293 }294 295 // substiution296 void297 subst (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& A,298 CanonicalForm& B, const int d299 )300 {301 if (d == 1)302 {303 A= F;304 B= G;305 return;306 }307 308 CanonicalForm C= 0;309 CanonicalForm D= 0;310 Variable x= Variable (1);311 CanonicalForm f= swapvar (F, x, F.mvar());312 CanonicalForm g= swapvar (G, x, G.mvar());313 for (CFIterator i= f; i.hasTerms(); i++)314 C += i.coeff()*power (f.mvar(), i.exp()/ d);315 for (CFIterator i= g; i.hasTerms(); i++)316 D += i.coeff()*power (g.mvar(), i.exp()/ d);317 A= swapvar (C, x, F.mvar());318 B= swapvar (D, x, G.mvar());319 }320 321 CanonicalForm322 reverseSubst (const CanonicalForm& F, const int d)323 {324 if (d == 1)325 return F;326 327 Variable x= Variable (1);328 if (degree (F, x) <= 0)329 return F;330 CanonicalForm f= swapvar (F, x, F.mvar());331 CanonicalForm result= 0;332 for (CFIterator i= f; i.hasTerms(); i++)333 result += i.coeff()*power (f.mvar(), d*i.exp());334 return swapvar (result, x, F.mvar());335 241 } 336 242 … … 541 447 } 542 448 449 CanonicalForm 450 GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G, 451 CanonicalForm& coF, CanonicalForm& coG, 452 Variable & alpha, CFList& l, bool& topLevel); 453 454 CanonicalForm 455 GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G, 456 Variable & alpha, CFList& l, bool& topLevel) 457 { 458 CanonicalForm dummy1, dummy2; 459 CanonicalForm result= GCD_Fp_extension (F, G, dummy1, dummy2, alpha, l, 460 topLevel); 461 return result; 462 } 463 543 464 /// GCD of F and G over \f$ F_{p}(\alpha ) \f$ , 544 465 /// l and topLevel are only used internally, output is monic … … 547 468 CanonicalForm 548 469 GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G, 470 CanonicalForm& coF, CanonicalForm& coG, 549 471 Variable & alpha, CFList& l, bool& topLevel) 550 472 { 551 473 CanonicalForm A= F; 552 474 CanonicalForm B= G; 553 if (F.isZero() && degree(G) > 0) return G/Lc(G); 554 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 555 else if (F.isZero() && G.isZero()) return F.genOne(); 556 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 557 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 558 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 559 if (F == G) return F/Lc(F); 475 if (F.isZero() && degree(G) > 0) 476 { 477 coF= 0; 478 coG= Lc (G); 479 return G/Lc(G); 480 } 481 else if (G.isZero() && degree (F) > 0) 482 { 483 coF= Lc (F); 484 coG= 0; 485 return F/Lc(F); 486 } 487 else if (F.isZero() && G.isZero()) 488 { 489 coF= coG= 0; 490 return F.genOne(); 491 } 492 if (F.inBaseDomain() || G.inBaseDomain()) 493 { 494 coF= F; 495 coG= G; 496 return F.genOne(); 497 } 498 if (F.isUnivariate() && fdivides(F, G, coG)) 499 { 500 coF= Lc (F); 501 return F/Lc(F); 502 } 503 if (G.isUnivariate() && fdivides(G, F, coF)) 504 { 505 coG= Lc (G); 506 return G/Lc(G); 507 } 508 if (F == G) 509 { 510 coF= coG= Lc (F); 511 return F/Lc(F); 512 } 560 513 561 514 CFMap M,N; 562 515 int best_level= myCompress (A, B, M, N, topLevel); 563 516 564 if (best_level == 0) return B.genOne(); 517 if (best_level == 0) 518 { 519 coF= F; 520 coG= G; 521 return B.genOne(); 522 } 565 523 566 524 A= M(A); … … 571 529 //univariate case 572 530 if (A.isUnivariate() && B.isUnivariate()) 573 return N (gcd(A,B));574 575 int substitute= substituteCheck (A, B);576 577 if (substitute > 1)578 subst (A, B, A, B, substitute);531 { 532 CanonicalForm result= gcd (A, B); 533 coF= N (A/result); 534 coG= N (B/result); 535 return N (result); 536 } 579 537 580 538 CanonicalForm cA, cB; // content of A and B … … 598 556 } 599 557 558 int sizeNewtonPolyg; 559 int ** newtonPolyg= NULL; 560 mat_ZZ MM; 561 vec_ZZ V; 562 bool compressConvexDense= (ppA.level() == 2 && ppB.level() == 2); 563 if (compressConvexDense) 564 { 565 CanonicalForm bufcA= cA; 566 CanonicalForm bufcB= cB; 567 cA= content (ppA, 1); 568 cB= content (ppB, 1); 569 ppA /= cA; 570 ppB /= cB; 571 gcdcAcB *= gcd (cA, cB); 572 cA *= bufcA; 573 cB *= bufcB; 574 if (ppA.isUnivariate() || ppB.isUnivariate()) 575 { 576 if (ppA.level() == ppB.level()) 577 { 578 CanonicalForm result= gcd (ppA, ppB); 579 coF= N ((ppA/result)*(cA/gcdcAcB)); 580 coG= N ((ppB/result)*(cB/gcdcAcB)); 581 return N (result*gcdcAcB); 582 } 583 else 584 { 585 coF= N (ppA*(cA/gcdcAcB)); 586 coG= N (ppB*(cB/gcdcAcB)); 587 return N (gcdcAcB); 588 } 589 } 590 591 newtonPolyg= newtonPolygon (ppA,ppB, sizeNewtonPolyg); 592 convexDense (newtonPolyg, sizeNewtonPolyg, MM, V); 593 594 for (int i= 0; i < sizeNewtonPolyg; i++) 595 delete [] newtonPolyg[i]; 596 delete [] newtonPolyg; 597 598 ppA= compress (ppA, MM, V, false); 599 ppB= compress (ppB, MM, V, false); 600 MM= inv (MM); 601 602 if (ppA.isUnivariate() && ppB.isUnivariate()) 603 { 604 if (ppA.level() == ppB.level()) 605 { 606 CanonicalForm result= gcd (ppA, ppB); 607 coF= N (decompress ((ppA/result), MM, V)*(cA/gcdcAcB)); 608 coG= N (decompress ((ppB/result), MM, V)*(cB/gcdcAcB)); 609 return N (decompress (result, MM, V)*gcdcAcB); 610 } 611 else 612 { 613 coF= N (decompress (ppA, MM, V)); 614 coG= N (decompress (ppB, MM, V)); 615 return N (gcdcAcB); 616 } 617 } 618 } 619 600 620 CanonicalForm lcA, lcB; // leading coefficients of A and B 601 621 CanonicalForm gcdlcAlcB; … … 604 624 lcB= uni_lcoeff (ppB); 605 625 606 if (fdivides (lcA, lcB))626 /*if (fdivides (lcA, lcB)) 607 627 { 608 628 if (fdivides (A, B)) … … 613 633 if (fdivides (B, A)) 614 634 return G/Lc(G); 615 } 635 }*/ 616 636 617 637 gcdlcAlcB= gcd (lcA, lcB); … … 621 641 if (d == 0) 622 642 { 623 if (substitute > 1)624 return N (reverseSubst (gcdcAcB, substitute));625 else626 return N(gcdcAcB);627 } 643 coF= N (ppA*(cA/gcdcAcB)); 644 coG= N (ppB*(cB/gcdcAcB)); 645 return N(gcdcAcB); 646 } 647 628 648 int d0= totaldegree (ppB, Variable(2), Variable (ppB.level())); 629 649 if (d0 < d) … … 631 651 if (d == 0) 632 652 { 633 if (substitute > 1) 634 return N (reverseSubst (gcdcAcB, substitute)); 635 else 636 return N(gcdcAcB); 653 coF= N (ppA*(cA/gcdcAcB)); 654 coG= N (ppB*(cB/gcdcAcB)); 655 return N(gcdcAcB); 637 656 } 638 657 639 658 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH; 640 CanonicalForm newtonPoly; 659 CanonicalForm newtonPoly, coF_random_element, coG_random_element, coF_m, 660 coG_m, ppCoF, ppCoG; 641 661 642 662 newtonPoly= 1; 643 663 m= gcdlcAlcB; 644 664 G_m= 0; 665 coF= 0; 666 coG= 0; 645 667 H= 0; 646 668 bool fail= false; … … 650 672 CanonicalForm prim_elem, im_prim_elem; 651 673 CFList source, dest; 674 int bound1= degree (ppA, 1); 675 int bound2= degree (ppB, 1); 652 676 do 653 677 { 654 random_element= randomElement (m , V_buf, l, fail);678 random_element= randomElement (m*lcA*lcB, V_buf, l, fail); 655 679 if (fail) 656 680 { … … 667 691 { 668 692 m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest); 669 G_m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest); 693 G_m= mapDown (G_m, prim_elem, im_prim_elem, alpha, source, dest); 694 coF_m= mapDown (coF_m, prim_elem, im_prim_elem, alpha, source, dest); 695 coG_m= mapDown (coG_m, prim_elem, im_prim_elem, alpha, source, dest); 670 696 newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, alpha, 671 697 source, dest); … … 674 700 gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, alpha, 675 701 source, dest); 702 lcA= mapDown (lcA, prim_elem, im_prim_elem, alpha, source, dest); 703 lcB= mapDown (lcB, prim_elem, im_prim_elem, alpha, source, dest); 676 704 for (CFListIterator i= l; i.hasItem(); i++) 677 705 i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, alpha, … … 693 721 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 694 722 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 723 coF_m= mapUp (coF_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 724 coG_m= mapUp (coG_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 695 725 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 696 726 source, dest); … … 699 729 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 700 730 source, dest); 731 lcA= mapUp (lcA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 732 lcB= mapUp (lcB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 701 733 702 734 fail= false; 703 random_element= randomElement (m , V_buf, l, fail );735 random_element= randomElement (m*lcA*lcB, V_buf, l, fail ); 704 736 DEBOUTLN (cerr, "fail= " << fail); 705 737 CFList list; 706 738 TIMING_START (gcd_recursion); 707 739 G_random_element= 708 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf, 740 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), 741 coF_random_element, coG_random_element, V_buf, 709 742 list, topLevel); 710 743 TIMING_END_AND_PRINT (gcd_recursion, … … 717 750 TIMING_START (gcd_recursion); 718 751 G_random_element= 719 GCD_Fp_extension (ppA(random_element, x), ppB(random_element, x), V_buf, 752 GCD_Fp_extension (ppA(random_element, x), ppB(random_element, x), 753 coF_random_element, coG_random_element, V_buf, 720 754 list, topLevel); 721 755 TIMING_END_AND_PRINT (gcd_recursion, … … 732 766 if (d0 == 0) 733 767 { 734 if (substitute > 1) 735 return N (reverseSubst (gcdcAcB, substitute)); 736 else 737 return N(gcdcAcB); 768 coF= N (ppA*(cA/gcdcAcB)); 769 coG= N (ppB*(cB/gcdcAcB)); 770 return N(gcdcAcB); 738 771 } 739 772 if (d0 > d) … … 747 780 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 748 781 * G_random_element; 782 coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element)) 783 *coF_random_element; 784 coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element)) 785 *coG_random_element; 749 786 750 787 if (!G_random_element.inCoeffDomain()) … … 760 797 G_m= 0; 761 798 d= d0; 799 coF_m= 0; 800 coG_m= 0; 762 801 } 763 802 764 803 TIMING_START (newton_interpolation); 765 804 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 805 coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x); 806 coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x); 766 807 TIMING_END_AND_PRINT (newton_interpolation, 767 808 "time for newton interpolation: "); 768 809 769 810 //termination test 770 if (uni_lcoeff (H) == gcdlcAlcB) 771 { 772 cH= uni_content (H); 811 if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H)) 812 { 813 if (gcdlcAlcB.isOne()) 814 cH= 1; 815 else 816 cH= uni_content (H); 773 817 ppH= H/cH; 818 CanonicalForm lcppH= gcdlcAlcB/cH; 819 CanonicalForm ccoF= lcA/lcppH; 820 ccoF /= Lc (ccoF); 821 CanonicalForm ccoG= lcB/lcppH; 822 ccoG /= Lc (ccoG); 823 ppCoF= coF/ccoF; 824 ppCoG= coG/ccoG; 774 825 if (inextension) 775 826 { 776 CFList u, v; 777 //maybe it's better to test if ppH is an element of F(\alpha) before 778 //mapping down 779 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 780 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 781 ppH /= Lc(ppH); 782 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 783 if (fdivides (ppH, A) && fdivides (ppH, B)) 784 { 785 if (substitute > 1) 827 if (((degree (ppCoF,1)+degree (ppH,1) == bound1) && 828 (degree (ppCoG,1)+degree (ppH,1) == bound2) && 829 terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) || 830 (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG))) 831 { 832 CFList u, v; 833 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 834 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 835 ppCoF= mapDown (ppCoF, prim_elem, im_prim_elem, alpha, u, v); 836 ppCoF= mapDown (ppCoG, prim_elem, im_prim_elem, alpha, u, v); 837 ppH /= Lc(ppH); 838 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 839 if (compressConvexDense) 786 840 { 787 ppH= reverseSubst (ppH, substitute); 788 gcdcAcB= reverseSubst (gcdcAcB, substitute); 841 ppH= decompress (ppH, MM, V); 842 ppCoF= decompress (ppCoF, MM, V); 843 ppCoG= decompress (ppCoG, MM, V); 789 844 } 845 coF= N ((cA/gcdcAcB)*ppCoF); 846 coG= N ((cB/gcdcAcB)*ppCoG); 790 847 return N(gcdcAcB*ppH); 791 848 } 792 849 } 793 else if (fdivides (ppH, A) && fdivides (ppH, B)) 794 { 795 if (substitute > 1) 796 { 797 ppH= reverseSubst (ppH, substitute); 798 gcdcAcB= reverseSubst (gcdcAcB, substitute); 850 else if (((degree (ppCoF,1)+degree (ppH,1) == bound1) && 851 (degree (ppCoG,1)+degree (ppH,1) == bound2) && 852 terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) || 853 (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG))) 854 { 855 if (compressConvexDense) 856 { 857 ppH= decompress (ppH, MM, V); 858 ppCoF= decompress (ppCoF, MM, V); 859 ppCoG= decompress (ppCoG, MM, V); 799 860 } 861 coF= N ((cA/gcdcAcB)*ppCoF); 862 coG= N ((cB/gcdcAcB)*ppCoG);; 800 863 return N(gcdcAcB*ppH); 801 864 } … … 803 866 804 867 G_m= H; 868 coF_m= coF; 869 coG_m= coG; 805 870 newtonPoly= newtonPoly*(x - random_element); 806 871 m= m*(x - random_element); … … 848 913 } 849 914 915 CanonicalForm 916 GCD_GF (const CanonicalForm& F, const CanonicalForm& G, 917 CanonicalForm& coF, CanonicalForm& coG, 918 CFList& l, bool& topLevel); 919 920 CanonicalForm 921 GCD_GF (const CanonicalForm& F, const CanonicalForm& G, CFList& l, 922 bool& topLevel) 923 { 924 CanonicalForm dummy1, dummy2; 925 CanonicalForm result= GCD_GF (F, G, dummy1, dummy2, l, topLevel); 926 return result; 927 } 928 850 929 /// GCD of F and G over GF, based on Alg. 7.2. as described in "Algorithms for 851 930 /// Computer Algebra" by Geddes, Czapor, Labahn … … 853 932 /// faster field arithmetics, however it might fail if the input is large since 854 933 /// the size of the base field is bounded by 2^16, output is monic 855 CanonicalForm GCD_GF (const CanonicalForm& F, const CanonicalForm& G, 934 CanonicalForm 935 GCD_GF (const CanonicalForm& F, const CanonicalForm& G, 936 CanonicalForm& coF, CanonicalForm& coG, 856 937 CFList& l, bool& topLevel) 857 938 { 858 939 CanonicalForm A= F; 859 940 CanonicalForm B= G; 860 if (F.isZero() && degree(G) > 0) return G/Lc(G); 861 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 862 else if (F.isZero() && G.isZero()) return F.genOne(); 863 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 864 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 865 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 866 if (F == G) return F/Lc(F); 941 if (F.isZero() && degree(G) > 0) 942 { 943 coF= 0; 944 coG= Lc (G); 945 return G/Lc(G); 946 } 947 else if (G.isZero() && degree (F) > 0) 948 { 949 coF= Lc (F); 950 coG= 0; 951 return F/Lc(F); 952 } 953 else if (F.isZero() && G.isZero()) 954 { 955 coF= coG= 0; 956 return F.genOne(); 957 } 958 if (F.inBaseDomain() || G.inBaseDomain()) 959 { 960 coF= F; 961 coG= G; 962 return F.genOne(); 963 } 964 if (F.isUnivariate() && fdivides(F, G, coG)) 965 { 966 coF= Lc (F); 967 return F/Lc(F); 968 } 969 if (G.isUnivariate() && fdivides(G, F, coF)) 970 { 971 coG= Lc (G); 972 return G/Lc(G); 973 } 974 if (F == G) 975 { 976 coF= coG= Lc (F); 977 return F/Lc(F); 978 } 867 979 868 980 CFMap M,N; 869 981 int best_level= myCompress (A, B, M, N, topLevel); 870 982 871 if (best_level == 0) return B.genOne(); 983 if (best_level == 0) 984 { 985 coF= F; 986 coG= G; 987 return B.genOne(); 988 } 872 989 873 990 A= M(A); … … 878 995 //univariate case 879 996 if (A.isUnivariate() && B.isUnivariate()) 880 return N (gcd (A, B));881 882 int substitute= substituteCheck (A, B);883 884 if (substitute > 1)885 subst (A, B, A, B, substitute);997 { 998 CanonicalForm result= gcd (A, B); 999 coF= N (A/result); 1000 coG= N (B/result); 1001 return N (result); 1002 } 886 1003 887 1004 CanonicalForm cA, cB; // content of A and B … … 905 1022 } 906 1023 1024 int sizeNewtonPolyg; 1025 int ** newtonPolyg= NULL; 1026 mat_ZZ MM; 1027 vec_ZZ V; 1028 bool compressConvexDense= (ppA.level() == 2 && ppB.level() == 2); 1029 if (compressConvexDense) 1030 { 1031 CanonicalForm bufcA= cA; 1032 CanonicalForm bufcB= cB; 1033 cA= content (ppA, 1); 1034 cB= content (ppB, 1); 1035 ppA /= cA; 1036 ppB /= cB; 1037 gcdcAcB *= gcd (cA, cB); 1038 cA *= bufcA; 1039 cB *= bufcB; 1040 if (ppA.isUnivariate() || ppB.isUnivariate()) 1041 { 1042 if (ppA.level() == ppB.level()) 1043 { 1044 CanonicalForm result= gcd (ppA, ppB); 1045 coF= N ((ppA/result)*(cA/gcdcAcB)); 1046 coG= N ((ppB/result)*(cB/gcdcAcB)); 1047 return N (result*gcdcAcB); 1048 } 1049 else 1050 { 1051 coF= N (ppA*(cA/gcdcAcB)); 1052 coG= N (ppB*(cB/gcdcAcB)); 1053 return N (gcdcAcB); 1054 } 1055 } 1056 1057 newtonPolyg= newtonPolygon (ppA,ppB, sizeNewtonPolyg); 1058 convexDense (newtonPolyg, sizeNewtonPolyg, MM, V); 1059 1060 for (int i= 0; i < sizeNewtonPolyg; i++) 1061 delete [] newtonPolyg[i]; 1062 delete [] newtonPolyg; 1063 1064 ppA= compress (ppA, MM, V, false); 1065 ppB= compress (ppB, MM, V, false); 1066 MM= inv (MM); 1067 1068 if (ppA.isUnivariate() && ppB.isUnivariate()) 1069 { 1070 if (ppA.level() == ppB.level()) 1071 { 1072 CanonicalForm result= gcd (ppA, ppB); 1073 coF= N (decompress ((ppA/result), MM, V)*(cA/gcdcAcB)); 1074 coG= N (decompress ((ppB/result), MM, V)*(cB/gcdcAcB)); 1075 return N (decompress (result, MM, V)*gcdcAcB); 1076 } 1077 else 1078 { 1079 coF= N (decompress (ppA, MM, V)); 1080 coG= N (decompress (ppB, MM, V)); 1081 return N (gcdcAcB); 1082 } 1083 } 1084 } 1085 907 1086 CanonicalForm lcA, lcB; // leading coefficients of A and B 908 1087 CanonicalForm gcdlcAlcB; … … 911 1090 lcB= uni_lcoeff (ppB); 912 1091 913 if (fdivides (lcA, lcB)) 914 { 915 if (fdivides (A, B)) 1092 /*if (fdivides (lcA, lcB)) 1093 { 1094 if (fdivides (ppA, ppB, coG)) 1095 { 1096 coF= 1; 1097 if (compressConvexDense) 1098 coG= decompress (coG, MM, V); 1099 coG= N (coG*(cB/gcdcAcB)); 916 1100 return F; 1101 } 917 1102 } 918 1103 if (fdivides (lcB, lcA)) 919 1104 { 920 if (fdivides (B, A)) 1105 if (fdivides (ppB, ppA, coF)) 1106 { 1107 coG= 1; 1108 if (compressConvexDense) 1109 coF= decompress (coF, MM, V); 1110 coF= N (coF*(cA/gcdcAcB)); 921 1111 return G; 922 } 1112 } 1113 }*/ 923 1114 924 1115 gcdlcAlcB= gcd (lcA, lcB); … … 927 1118 if (d == 0) 928 1119 { 929 if (substitute > 1) 930 return N (reverseSubst (gcdcAcB, substitute)); 931 else 932 return N(gcdcAcB); 1120 coF= N (ppA*(cA/gcdcAcB)); 1121 coG= N (ppB*(cB/gcdcAcB)); 1122 return N(gcdcAcB); 933 1123 } 934 1124 int d0= totaldegree (ppB, Variable(2), Variable (ppB.level())); … … 937 1127 if (d == 0) 938 1128 { 939 if (substitute > 1) 940 return N (reverseSubst (gcdcAcB, substitute)); 941 else 942 return N(gcdcAcB); 1129 coF= N (ppA*(cA/gcdcAcB)); 1130 coG= N (ppB*(cB/gcdcAcB)); 1131 return N(gcdcAcB); 943 1132 } 944 1133 945 1134 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH; 946 CanonicalForm newtonPoly; 1135 CanonicalForm newtonPoly, coF_random_element, coG_random_element, coF_m, 1136 coG_m, ppCoF, ppCoG; 947 1137 948 1138 newtonPoly= 1; 949 1139 m= gcdlcAlcB; 950 1140 G_m= 0; 1141 coF= 0; 1142 coG= 0; 951 1143 H= 0; 952 1144 bool fail= false; 953 topLevel= false;1145 //topLevel= false; 954 1146 bool inextension= false; 955 1147 int p=-1; … … 958 1150 int expon; 959 1151 char gf_name_buf= gf_name; 1152 int bound1= degree (ppA, 1); 1153 int bound2= degree (ppB, 1); 960 1154 do 961 1155 { 962 random_element= GFRandomElement (m , l, fail);1156 random_element= GFRandomElement (m*lcA*lcB, l, fail); 963 1157 if (fail) 964 1158 { … … 981 1175 G_m= GFMapUp (G_m, kk); 982 1176 newtonPoly= GFMapUp (newtonPoly, kk); 1177 coF_m= GFMapUp (coF_m, kk); 1178 coG_m= GFMapUp (coG_m, kk); 983 1179 ppA= GFMapUp (ppA, kk); 984 1180 ppB= GFMapUp (ppB, kk); 985 1181 gcdlcAlcB= GFMapUp (gcdlcAlcB, kk); 986 random_element= GFRandomElement (m, l, fail); 1182 lcA= GFMapUp (lcA, kk); 1183 lcB= GFMapUp (lcB, kk); 1184 random_element= GFRandomElement (m*lcA*lcB, l, fail); 987 1185 DEBOUTLN (cerr, "fail= " << fail); 988 1186 CFList list; 989 1187 TIMING_START (gcd_recursion); 990 1188 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 1189 coF_random_element, coG_random_element, 991 1190 list, topLevel); 992 1191 TIMING_END_AND_PRINT (gcd_recursion, … … 999 1198 TIMING_START (gcd_recursion); 1000 1199 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 1200 coF_random_element, coG_random_element, 1001 1201 list, topLevel); 1002 1202 TIMING_END_AND_PRINT (gcd_recursion, … … 1014 1214 { 1015 1215 if (inextension) 1016 {1017 1216 setCharacteristic (p, k, gf_name_buf); 1018 { 1019 if (substitute > 1) 1020 return N (reverseSubst (gcdcAcB, substitute)); 1021 else 1022 return N(gcdcAcB); 1023 } 1024 } 1025 else 1026 { 1027 if (substitute > 1) 1028 return N (reverseSubst (gcdcAcB, substitute)); 1029 else 1030 return N(gcdcAcB); 1031 } 1217 coF= N (ppA*(cA/gcdcAcB)); 1218 coG= N (ppB*(cB/gcdcAcB)); 1219 return N(gcdcAcB); 1032 1220 } 1033 1221 if (d0 > d) … … 1041 1229 (gcdlcAlcB(random_element, x)/uni_lcoeff(G_random_element)) * 1042 1230 G_random_element; 1231 1232 coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element)) 1233 *coF_random_element; 1234 coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element)) 1235 *coG_random_element; 1236 1043 1237 if (!G_random_element.inCoeffDomain()) 1044 1238 d0= totaldegree (G_random_element, Variable(2), … … 1053 1247 G_m= 0; 1054 1248 d= d0; 1249 coF_m= 0; 1250 coG_m= 0; 1055 1251 } 1056 1252 1057 1253 TIMING_START (newton_interpolation); 1058 1254 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 1059 TIMING_END_AND_PRINT (newton_interpolation, "time for newton interpolation: "); 1255 coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x); 1256 coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x); 1257 TIMING_END_AND_PRINT (newton_interpolation, 1258 "time for newton interpolation: "); 1060 1259 1061 1260 //termination test 1062 if (uni_lcoeff (H) == gcdlcAlcB) 1063 { 1064 cH= uni_content (H); 1261 if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H)) 1262 { 1263 if (gcdlcAlcB.isOne()) 1264 cH= 1; 1265 else 1266 cH= uni_content (H); 1065 1267 ppH= H/cH; 1268 CanonicalForm lcppH= gcdlcAlcB/cH; 1269 CanonicalForm ccoF= lcA/lcppH; 1270 ccoF /= Lc (ccoF); 1271 CanonicalForm ccoG= lcB/lcppH; 1272 ccoG /= Lc (ccoG); 1273 ppCoF= coF/ccoF; 1274 ppCoG= coG/ccoG; 1066 1275 if (inextension) 1067 1276 { 1068 if (fdivides(ppH, GFMapUp(A, k)) && fdivides(ppH, GFMapUp(B,k))) 1277 if (((degree (ppCoF,1)+degree (ppH,1) == bound1) && 1278 (degree (ppCoG,1)+degree (ppH,1) == bound2) && 1279 terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) || 1280 (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG))) 1069 1281 { 1070 1282 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 1071 1283 ppH= GFMapDown (ppH, k); 1284 ppCoF= GFMapDown (ppCoF, k); 1285 ppCoG= GFMapDown (ppCoG, k); 1072 1286 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 1073 if ( substitute > 1)1287 if (compressConvexDense) 1074 1288 { 1075 ppH= reverseSubst (ppH, substitute); 1076 gcdcAcB= reverseSubst (gcdcAcB, substitute); 1289 ppH= decompress (ppH, MM, V); 1290 ppCoF= decompress (ppCoF, MM, V); 1291 ppCoG= decompress (ppCoG, MM, V); 1077 1292 } 1293 coF= N ((cA/gcdcAcB)*ppCoF); 1294 coG= N ((cB/gcdcAcB)*ppCoG); 1078 1295 setCharacteristic (p, k, gf_name_buf); 1079 1296 return N(gcdcAcB*ppH); … … 1082 1299 else 1083 1300 { 1084 if (fdivides (ppH, A) && fdivides (ppH, B)) 1085 { 1086 if (substitute > 1) 1301 if (((degree (ppCoF,1)+degree (ppH,1) == bound1) && 1302 (degree (ppCoG,1)+degree (ppH,1) == bound2) && 1303 terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) || 1304 (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG))) 1305 { 1306 if (compressConvexDense) 1087 1307 { 1088 ppH= reverseSubst (ppH, substitute); 1089 gcdcAcB= reverseSubst (gcdcAcB, substitute); 1308 ppH= decompress (ppH, MM, V); 1309 ppCoF= decompress (ppCoF, MM, V); 1310 ppCoG= decompress (ppCoG, MM, V); 1090 1311 } 1312 coF= N ((cA/gcdcAcB)*ppCoF); 1313 coG= N ((cB/gcdcAcB)*ppCoG); 1091 1314 return N(gcdcAcB*ppH); 1092 1315 } … … 1095 1318 1096 1319 G_m= H; 1320 coF_m= coF; 1321 coG_m= coG; 1097 1322 newtonPoly= newtonPoly*(x - random_element); 1098 1323 m= m*(x - random_element); … … 1152 1377 } 1153 1378 1154 CanonicalForm GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1155 bool& topLevel, CFList& l) 1379 CanonicalForm 1380 GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1381 CanonicalForm& coF, CanonicalForm& coG, 1382 bool& topLevel, CFList& l); 1383 1384 CanonicalForm 1385 GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1386 bool& topLevel, CFList& l) 1387 { 1388 CanonicalForm dummy1, dummy2; 1389 CanonicalForm result= GCD_small_p (F, G, dummy1, dummy2, topLevel, l); 1390 return result; 1391 } 1392 1393 CanonicalForm 1394 GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1395 CanonicalForm& coF, CanonicalForm& coG, 1396 bool& topLevel, CFList& l) 1156 1397 { 1157 1398 CanonicalForm A= F; 1158 1399 CanonicalForm B= G; 1159 if (F.isZero() && degree(G) > 0) return G/Lc(G); 1160 else if (G.isZero() && degree (F) > 0) return F/Lc(F); 1161 else if (F.isZero() && G.isZero()) return F.genOne(); 1162 if (F.inBaseDomain() || G.inBaseDomain()) return F.genOne(); 1163 if (F.isUnivariate() && fdivides(F, G)) return F/Lc(F); 1164 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 1165 if (F == G) return F/Lc(F); 1166 1400 if (F.isZero() && degree(G) > 0) 1401 { 1402 coF= 0; 1403 coG= Lc (G); 1404 return G/Lc(G); 1405 } 1406 else if (G.isZero() && degree (F) > 0) 1407 { 1408 coF= Lc (F); 1409 coG= 0; 1410 return F/Lc(F); 1411 } 1412 else if (F.isZero() && G.isZero()) 1413 { 1414 coF= coG= 0; 1415 return F.genOne(); 1416 } 1417 if (F.inBaseDomain() || G.inBaseDomain()) 1418 { 1419 coF= F; 1420 coG= G; 1421 return F.genOne(); 1422 } 1423 if (F.isUnivariate() && fdivides(F, G, coG)) 1424 { 1425 coF= Lc (F); 1426 return F/Lc(F); 1427 } 1428 if (G.isUnivariate() && fdivides(G, F, coF)) 1429 { 1430 coG= Lc (G); 1431 return G/Lc(G); 1432 } 1433 if (F == G) 1434 { 1435 coF= coG= Lc (F); 1436 return F/Lc(F); 1437 } 1167 1438 CFMap M,N; 1168 1439 int best_level= myCompress (A, B, M, N, topLevel); 1169 1440 1170 if (best_level == 0) return B.genOne(); 1441 if (best_level == 0) 1442 { 1443 coF= F; 1444 coG= G; 1445 return B.genOne(); 1446 } 1171 1447 1172 1448 A= M(A); … … 1177 1453 //univariate case 1178 1454 if (A.isUnivariate() && B.isUnivariate()) 1179 return N (gcd (A, B));1180 1181 int substitute= substituteCheck (A, B);1182 1183 if (substitute > 1)1184 subst (A, B, A, B, substitute);1455 { 1456 CanonicalForm result= gcd (A, B); 1457 coF= N (A/result); 1458 coG= N (B/result); 1459 return N (result); 1460 } 1185 1461 1186 1462 CanonicalForm cA, cB; // content of A and B … … 1204 1480 } 1205 1481 1482 int sizeNewtonPolyg; 1483 int ** newtonPolyg= NULL; 1484 mat_ZZ MM; 1485 vec_ZZ V; 1486 bool compressConvexDense= (ppA.level() == 2 && ppB.level() == 2); 1487 if (compressConvexDense) 1488 { 1489 CanonicalForm bufcA= cA; 1490 CanonicalForm bufcB= cB; 1491 cA= content (ppA, 1); 1492 cB= content (ppB, 1); 1493 ppA /= cA; 1494 ppB /= cB; 1495 gcdcAcB *= gcd (cA, cB); 1496 cA *= bufcA; 1497 cB *= bufcB; 1498 if (ppA.isUnivariate() || ppB.isUnivariate()) 1499 { 1500 if (ppA.level() == ppB.level()) 1501 { 1502 CanonicalForm result= gcd (ppA, ppB); 1503 coF= N ((ppA/result)*(cA/gcdcAcB)); 1504 coG= N ((ppB/result)*(cB/gcdcAcB)); 1505 return N (result*gcdcAcB); 1506 } 1507 else 1508 { 1509 coF= N (ppA*(cA/gcdcAcB)); 1510 coG= N (ppB*(cB/gcdcAcB)); 1511 return N (gcdcAcB); 1512 } 1513 } 1514 1515 newtonPolyg= newtonPolygon (ppA,ppB, sizeNewtonPolyg); 1516 convexDense (newtonPolyg, sizeNewtonPolyg, MM, V); 1517 1518 for (int i= 0; i < sizeNewtonPolyg; i++) 1519 delete [] newtonPolyg[i]; 1520 delete [] newtonPolyg; 1521 1522 ppA= compress (ppA, MM, V, false); 1523 ppB= compress (ppB, MM, V, false); 1524 MM= inv (MM); 1525 1526 if (ppA.isUnivariate() && ppB.isUnivariate()) 1527 { 1528 if (ppA.level() == ppB.level()) 1529 { 1530 CanonicalForm result= gcd (ppA, ppB); 1531 coF= N (decompress ((ppA/result), MM, V)*(cA/gcdcAcB)); 1532 coG= N (decompress ((ppB/result), MM, V)*(cB/gcdcAcB)); 1533 return N (decompress (result, MM, V)*gcdcAcB); 1534 } 1535 else 1536 { 1537 coF= N (decompress (ppA, MM, V)); 1538 coG= N (decompress (ppB, MM, V)); 1539 return N (gcdcAcB); 1540 } 1541 } 1542 } 1543 1206 1544 CanonicalForm lcA, lcB; // leading coefficients of A and B 1207 1545 CanonicalForm gcdlcAlcB; … … 1209 1547 lcB= uni_lcoeff (ppB); 1210 1548 1211 if (fdivides (lcA, lcB))1549 /*if (fdivides (lcA, lcB)) 1212 1550 { 1213 1551 if (fdivides (A, B)) … … 1218 1556 if (fdivides (B, A)) 1219 1557 return G/Lc(G); 1220 } 1558 }*/ 1221 1559 1222 1560 gcdlcAlcB= gcd (lcA, lcB); … … 1227 1565 if (d == 0) 1228 1566 { 1229 if (substitute > 1)1230 return N (reverseSubst (gcdcAcB, substitute));1231 else1232 return N(gcdcAcB);1233 } 1567 coF= N (ppA*(cA/gcdcAcB)); 1568 coG= N (ppB*(cB/gcdcAcB)); 1569 return N(gcdcAcB); 1570 } 1571 1234 1572 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 1235 1573 … … 1239 1577 if (d == 0) 1240 1578 { 1241 if (substitute > 1) 1242 return N (reverseSubst (gcdcAcB, substitute)); 1243 else 1244 return N(gcdcAcB); 1579 coF= N (ppA*(cA/gcdcAcB)); 1580 coG= N (ppB*(cB/gcdcAcB)); 1581 return N(gcdcAcB); 1245 1582 } 1246 1583 1247 1584 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH; 1248 CanonicalForm newtonPoly= 1; 1585 CanonicalForm newtonPoly, coF_random_element, coG_random_element, 1586 coF_m, coG_m, ppCoF, ppCoG; 1587 1588 newtonPoly= 1; 1249 1589 m= gcdlcAlcB; 1250 1590 H= 0; 1591 coF= 0; 1592 coG= 0; 1251 1593 G_m= 0; 1252 1594 Variable alpha, V_buf; … … 1254 1596 bool inextension= false; 1255 1597 bool inextensionextension= false; 1256 topLevel= false;1598 bool topLevel2= false; 1257 1599 CFList source, dest; 1600 int bound1= degree (ppA, 1); 1601 int bound2= degree (ppB, 1); 1258 1602 do 1259 1603 { 1260 1604 if (inextension) 1261 random_element= randomElement (m , V_buf, l, fail);1605 random_element= randomElement (m*lcA*lcB, V_buf, l, fail); 1262 1606 else 1263 random_element= FpRandomElement (m , l, fail);1607 random_element= FpRandomElement (m*lcA*lcB, l, fail); 1264 1608 1265 1609 if (!fail && !inextension) … … 1268 1612 TIMING_START (gcd_recursion); 1269 1613 G_random_element= 1270 GCD_small_p (ppA (random_element,x), ppB (random_element,x), topLevel, 1271 list); 1614 GCD_small_p (ppA (random_element,x), ppB (random_element,x), 1615 coF_random_element, coG_random_element, topLevel2, 1616 list); 1272 1617 TIMING_END_AND_PRINT (gcd_recursion, 1273 1618 "time for recursive call: "); … … 1279 1624 TIMING_START (gcd_recursion); 1280 1625 G_random_element= 1281 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1282 list, topLevel); 1626 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), 1627 coF_random_element, coG_random_element, alpha, 1628 list, topLevel2); 1283 1629 TIMING_END_AND_PRINT (gcd_recursion, 1284 1630 "time for recursive call: "); … … 1297 1643 inextension= true; 1298 1644 fail= false; 1299 random_element= randomElement (m , alpha, l, fail);1645 random_element= randomElement (m*lcA*lcB, alpha, l, fail); 1300 1646 deg++; 1301 1647 } while (fail); … … 1304 1650 TIMING_START (gcd_recursion); 1305 1651 G_random_element= 1306 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1307 list, topLevel); 1652 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), 1653 coF_random_element, coG_random_element, alpha, 1654 list, topLevel2); 1308 1655 TIMING_END_AND_PRINT (gcd_recursion, 1309 1656 "time for recursive call: "); … … 1325 1672 { 1326 1673 m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest); 1327 G_m= mapDown (m, prim_elem, im_prim_elem, alpha, source, dest); 1674 G_m= mapDown (G_m, prim_elem, im_prim_elem, alpha, source, dest); 1675 coF_m= mapDown (coF_m, prim_elem, im_prim_elem, alpha, source, dest); 1676 coG_m= mapDown (coG_m, prim_elem, im_prim_elem, alpha, source, dest); 1328 1677 newtonPoly= mapDown (newtonPoly, prim_elem, im_prim_elem, alpha, 1329 1678 source, dest); … … 1332 1681 gcdlcAlcB= mapDown (gcdlcAlcB, prim_elem, im_prim_elem, alpha, source, 1333 1682 dest); 1683 lcA= mapDown (lcA, prim_elem, im_prim_elem, alpha, source, dest); 1684 lcB= mapDown (lcB, prim_elem, im_prim_elem, alpha, source, dest); 1334 1685 for (CFListIterator i= l; i.hasItem(); i++) 1335 1686 i.getItem()= mapDown (i.getItem(), prim_elem, im_prim_elem, alpha, … … 1352 1703 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1353 1704 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1705 coF_m= mapUp (coF_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1706 coG_m= mapUp (coG_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1354 1707 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 1355 1708 source, dest); … … 1358 1711 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 1359 1712 source, dest); 1713 lcA= mapUp (lcA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1714 lcB= mapUp (lcB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1360 1715 fail= false; 1361 random_element= randomElement (m , V_buf, l, fail );1716 random_element= randomElement (m*lcA*lcB, V_buf, l, fail ); 1362 1717 DEBOUTLN (cerr, "fail= " << fail); 1363 1718 CFList list; 1364 1719 TIMING_START (gcd_recursion); 1365 1720 G_random_element= 1366 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf, 1367 list, topLevel); 1721 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), 1722 coF_random_element, coG_random_element, V_buf, 1723 list, topLevel2); 1368 1724 TIMING_END_AND_PRINT (gcd_recursion, 1369 1725 "time for recursive call: "); … … 1379 1735 if (d0 == 0) 1380 1736 { 1381 if (substitute > 1)1382 return N (reverseSubst (gcdcAcB, substitute));1383 else1384 return N(gcdcAcB);1385 } 1737 coF= N (ppA*(cA/gcdcAcB)); 1738 coG= N (ppB*(cB/gcdcAcB)); 1739 return N(gcdcAcB); 1740 } 1741 1386 1742 if (d0 > d) 1387 1743 { … … 1394 1750 *G_random_element; 1395 1751 1752 coF_random_element= (lcA(random_element,x)/uni_lcoeff(coF_random_element)) 1753 *coF_random_element; 1754 coG_random_element= (lcB(random_element,x)/uni_lcoeff(coG_random_element)) 1755 *coG_random_element; 1396 1756 1397 1757 if (!G_random_element.inCoeffDomain()) … … 1407 1767 G_m= 0; 1408 1768 d= d0; 1769 coF_m= 0; 1770 coG_m= 0; 1409 1771 } 1410 1772 1411 1773 TIMING_START (newton_interpolation); 1412 1774 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 1775 coF= newtonInterp (random_element, coF_random_element, newtonPoly, coF_m,x); 1776 coG= newtonInterp (random_element, coG_random_element, newtonPoly, coG_m,x); 1413 1777 TIMING_END_AND_PRINT (newton_interpolation, 1414 1778 "time for newton_interpolation: "); 1415 1779 1416 1780 //termination test 1417 if (uni_lcoeff (H) == gcdlcAlcB) 1418 { 1419 cH= uni_content (H); 1781 if ((uni_lcoeff (H) == gcdlcAlcB) || (G_m == H)) 1782 { 1783 if (gcdlcAlcB.isOne()) 1784 cH= 1; 1785 else 1786 cH= uni_content (H); 1420 1787 ppH= H/cH; 1421 1788 ppH /= Lc (ppH); 1789 CanonicalForm lcppH= gcdlcAlcB/cH; 1790 CanonicalForm ccoF= lcppH/Lc (lcppH); 1791 CanonicalForm ccoG= lcppH/Lc (lcppH); 1792 ppCoF= coF/ccoF; 1793 ppCoG= coG/ccoG; 1422 1794 DEBOUTLN (cerr, "ppH= " << ppH); 1423 if (fdivides (ppH, A) && fdivides (ppH, B)) 1424 { 1425 if (substitute > 1) 1426 { 1427 ppH= reverseSubst (ppH, substitute); 1428 gcdcAcB= reverseSubst (gcdcAcB, substitute); 1795 if (((degree (ppCoF,1)+degree (ppH,1) == bound1) && 1796 (degree (ppCoG,1)+degree (ppH,1) == bound2) && 1797 terminationTest (ppA, ppB, ppCoF, ppCoG, ppH)) || 1798 (fdivides (ppH, ppA, ppCoF) && fdivides (ppH, ppB, ppCoG))) 1799 { 1800 if (compressConvexDense) 1801 { 1802 ppH= decompress (ppH, MM, V); 1803 ppCoF= decompress (ppCoF, MM, V); 1804 ppCoG= decompress (ppCoG, MM, V); 1429 1805 } 1806 coF= N ((cA/gcdcAcB)*ppCoF); 1807 coG= N ((cB/gcdcAcB)*ppCoG); 1430 1808 return N(gcdcAcB*ppH); 1431 1809 } … … 1433 1811 1434 1812 G_m= H; 1813 coF_m= coF; 1814 coG_m= coG; 1435 1815 newtonPoly= newtonPoly*(x - random_element); 1436 1816 m= m*(x - random_element); … … 2855 3235 return N (gcd (A, B)); 2856 3236 2857 int substitute= substituteCheck (A, B);2858 2859 if (substitute > 1)2860 subst (A, B, A, B, substitute);2861 2862 3237 CanonicalForm cA, cB; // content of A and B 2863 3238 CanonicalForm ppA, ppB; // primitive part of A and B … … 2901 3276 2902 3277 if (d == 0) 2903 { 2904 if (substitute > 1) 2905 return N(reverseSubst (gcdcAcB, substitute)); 2906 else 2907 return N(gcdcAcB); 2908 } 3278 return N(gcdcAcB); 2909 3279 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 2910 3280 … … 2913 3283 2914 3284 if (d == 0) 2915 { 2916 if (substitute > 1) 2917 return N(reverseSubst (gcdcAcB, substitute)); 2918 else 2919 return N(gcdcAcB); 2920 } 3285 return N(gcdcAcB); 2921 3286 2922 3287 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton; … … 3018 3383 3019 3384 if (d0 == 0) 3020 { 3021 if (substitute > 1) 3022 return N(reverseSubst (gcdcAcB, substitute)); 3023 else 3024 return N(gcdcAcB); 3025 } 3385 return N(gcdcAcB); 3026 3386 if (d0 > d) 3027 3387 { … … 3060 3420 //maybe it's better to test if ppH is an element of F(\alpha) before 3061 3421 //mapping down 3062 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 3063 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 3064 ppH /= Lc(ppH); 3065 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 3066 if (fdivides (ppH, A) && fdivides (ppH, B)) 3067 { 3068 if (substitute > 1) 3069 { 3070 ppH= reverseSubst (ppH, substitute); 3071 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3072 } 3422 if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3423 { 3424 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 3425 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 3426 ppH /= Lc(ppH); 3427 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 3073 3428 return N(gcdcAcB*ppH); 3074 3429 } 3075 3430 } 3076 else if (fdivides (ppH, A) && fdivides (ppH, B)) 3077 { 3078 if (substitute > 1) 3079 { 3080 ppH= reverseSubst (ppH, substitute); 3081 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3082 } 3431 else if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3083 3432 return N(gcdcAcB*ppH); 3084 }3085 3433 } 3086 3434 G_m= H; … … 3204 3552 3205 3553 if (d0 == 0) 3206 { 3207 if (substitute > 1) 3208 return N(reverseSubst (gcdcAcB, substitute)); 3209 else 3210 return N(gcdcAcB); 3211 } 3554 return N(gcdcAcB); 3212 3555 if (d0 > d) 3213 3556 { … … 3250 3593 //maybe it's better to test if ppH is an element of F(\alpha) before 3251 3594 //mapping down 3252 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 3253 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 3254 ppH /= Lc(ppH); 3255 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 3256 if (fdivides (ppH, A) && fdivides (ppH, B)) 3595 if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3257 3596 { 3258 if (substitute > 1) 3259 { 3260 ppH= reverseSubst (ppH, substitute); 3261 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3262 } 3597 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 3598 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 3599 ppH /= Lc(ppH); 3600 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 3263 3601 return N(gcdcAcB*ppH); 3264 3602 } 3265 3603 } 3266 else if (fdivides (ppH, A) && fdivides (ppH,B))3604 else if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3267 3605 { 3268 if (substitute > 1)3269 {3270 ppH= reverseSubst (ppH, substitute);3271 gcdcAcB= reverseSubst (gcdcAcB, substitute);3272 }3273 3606 return N(gcdcAcB*ppH); 3274 3607 } … … 3313 3646 return N (gcd (A, B)); 3314 3647 3315 int substitute= substituteCheck (A, B);3316 3317 if (substitute > 1)3318 subst (A, B, A, B, substitute);3319 3320 3648 CanonicalForm cA, cB; // content of A and B 3321 3649 CanonicalForm ppA, ppB; // primitive part of A and B … … 3359 3687 3360 3688 if (d == 0) 3361 { 3362 if (substitute > 1) 3363 return N(reverseSubst (gcdcAcB, substitute)); 3364 else 3365 return N(gcdcAcB); 3366 } 3689 return N(gcdcAcB); 3690 3367 3691 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 3368 3692 … … 3371 3695 3372 3696 if (d == 0) 3373 { 3374 if (substitute > 1) 3375 return N(reverseSubst (gcdcAcB, substitute)); 3376 else 3377 return N(gcdcAcB); 3378 } 3697 return N(gcdcAcB); 3379 3698 3380 3699 CanonicalForm m, random_element, G_m, G_random_element, H, cH, ppH, skeleton; … … 3519 3838 3520 3839 if (d0 == 0) 3521 { 3522 if (substitute > 1) 3523 return N(reverseSubst (gcdcAcB, substitute)); 3524 else 3525 return N(gcdcAcB); 3526 } 3840 return N(gcdcAcB); 3527 3841 if (d0 > d) 3528 3842 { … … 3561 3875 DEBOUTLN (cerr, "ppH= " << ppH); 3562 3876 3563 if (fdivides (ppH, A) && fdivides (ppH, B)) 3564 { 3565 if (substitute > 1) 3566 { 3567 ppH= reverseSubst (ppH, substitute); 3568 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3569 } 3877 if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3570 3878 return N(gcdcAcB*ppH); 3571 }3572 3879 } 3573 3880 G_m= H; … … 3743 4050 3744 4051 if (d0 == 0) 3745 { 3746 if (substitute > 1) 3747 return N(reverseSubst (gcdcAcB, substitute)); 3748 else 3749 return N(gcdcAcB); 3750 } 4052 return N(gcdcAcB); 3751 4053 if (d0 > d) 3752 4054 { … … 3786 4088 ppH /= Lc (ppH); 3787 4089 DEBOUTLN (cerr, "ppH= " << ppH); 3788 if (fdivides (ppH, A) && fdivides (ppH, B)) 3789 { 3790 if (substitute > 1) 3791 { 3792 ppH= reverseSubst (ppH, substitute); 3793 gcdcAcB= reverseSubst (gcdcAcB, substitute); 3794 } 4090 if (fdivides (ppH, ppA) && fdivides (ppH, ppB)) 3795 4091 return N(gcdcAcB*ppH); 3796 }3797 4092 } 3798 4093 … … 4355 4650 } 4356 4651 4357 CanonicalForm cand ;4652 CanonicalForm cand, contcand; 4358 4653 CanonicalForm result; 4359 4654 int o, t; … … 4598 4893 if (gcdfound == 1) 4599 4894 { 4600 cand = DD[2] / content( DD[2], Variable(1) ); 4601 gcdfound = fdivides( cand, G ) && fdivides ( cand, F ); 4895 contcand= content (DD[2], Variable (1)); 4896 cand = DD[2] / contcand; 4897 if (B_is_F) 4898 gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F; 4899 else 4900 gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G; 4602 4901 4603 4902 if (passToGF && gcdfound) -
factory/cf_gcd_smallp.h
ra03496 re7676a 44 44 bool& top_level, CFList& l); 45 45 46 CanonicalForm GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& coF, CanonicalForm& coG, 47 bool& topLevel, CFList& l); 48 46 49 ///GCD of A and B over \f$ F_{p} \f$ 47 50 static inline CanonicalForm GCD_small_p (const CanonicalForm& A, const CanonicalForm& B) … … 50 53 bool top_level= true; 51 54 return GCD_small_p (A, B, top_level, list); 55 } 56 57 static inline CanonicalForm GCD_small_p (const CanonicalForm& A, const CanonicalForm& B, CanonicalForm& coA, CanonicalForm& coB) 58 { 59 CFList list; 60 bool top_level= true; 61 return GCD_small_p (A, B, coA, coB, top_level, list); 52 62 } 53 63 … … 102 112 CFArray 103 113 getMonoms (const CanonicalForm& F); 114 115 bool 116 terminationTest (const CanonicalForm& F, const CanonicalForm& G, 117 const CanonicalForm& coF, const CanonicalForm& coG, 118 const CanonicalForm& cand); 104 119 #endif -
factory/fac_ezgcd.cc
ra03496 re7676a 1 /* emacs edit mode for this file is -*- C++ -*- */ 2 /* $Id$ */ 1 /*****************************************************************************\ 2 * Computer Algebra System SINGULAR 3 \*****************************************************************************/ 4 /** @file fac_ezgcd.cc 5 * 6 * This file implements the GCD of two multivariate polynomials over Q using 7 * EZ-GCD as described in "Algorithms for Computer Algebra" by Geddes, Czapor, 8 * Labahnn 9 * 10 * @author Martin Lee 11 * 12 **/ 13 /*****************************************************************************/ 3 14 4 15 #include "config.h" … … 9 20 #include "cf_defs.h" 10 21 #include "canonicalform.h" 11 #include "fac_util.h" 22 #include "fac_util.h" // HEADER for this file 12 23 #include "cf_algorithm.h" 13 24 #include "cf_reval.h" … … 16 27 #include "fac_distrib.h" 17 28 #include "templates/ftmpl_functions.h" 18 19 static void findeval( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, REvaluation & b, int delta, int degF, int degG ); 20 21 static CanonicalForm ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, REvaluation & b, bool internal ); 22 23 static CanonicalForm ezgcd_specialcase ( const CanonicalForm & F, const CanonicalForm & G, REvaluation & b, const modpk & bound ); 24 25 static modpk findBound ( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & lcF, const CanonicalForm & lcG, int degF, int degG ); 26 27 static modpk enlargeBound ( const CanonicalForm & F, const CanonicalForm & Lb, const CanonicalForm & Db, const modpk & pk ); 29 #include "cf_map.h" 30 #include "facHensel.h" 31 32 static 33 int compress4EZGCD (const CanonicalForm& F, const CanonicalForm& G, CFMap & M, 34 CFMap & N, int& both_non_zero) 35 { 36 int n= tmax (F.level(), G.level()); 37 int * degsf= new int [n + 1]; 38 int * degsg= new int [n + 1]; 39 40 for (int i = 0; i <= n; i++) 41 degsf[i]= degsg[i]= 0; 42 43 degsf= degrees (F, degsf); 44 degsg= degrees (G, degsg); 45 46 both_non_zero= 0; 47 int f_zero= 0; 48 int g_zero= 0; 49 50 for (int i= 1; i <= n; i++) 51 { 52 if (degsf[i] != 0 && degsg[i] != 0) 53 { 54 both_non_zero++; 55 continue; 56 } 57 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 58 { 59 f_zero++; 60 continue; 61 } 62 if (degsg[i] == 0 && degsf[i] && i <= F.level()) 63 { 64 g_zero++; 65 continue; 66 } 67 } 68 69 if (both_non_zero == 0) 70 { 71 delete [] degsf; 72 delete [] degsg; 73 return 0; 74 } 75 76 // map Variables which do not occur in both polynomials to higher levels 77 int k= 1; 78 int l= 1; 79 for (int i= 1; i <= n; i++) 80 { 81 if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level()) 82 { 83 if (k + both_non_zero != i) 84 { 85 M.newpair (Variable (i), Variable (k + both_non_zero)); 86 N.newpair (Variable (k + both_non_zero), Variable (i)); 87 } 88 k++; 89 } 90 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 91 { 92 if (l + g_zero + both_non_zero != i) 93 { 94 M.newpair (Variable (i), Variable (l + g_zero + both_non_zero)); 95 N.newpair (Variable (l + g_zero + both_non_zero), Variable (i)); 96 } 97 l++; 98 } 99 } 100 101 // sort Variables x_{i} in decreasing order of 102 // min(deg_{x_{i}}(f),deg_{x_{i}}(g)) 103 int m= tmin (F.level(), G.level()); 104 int max_min_deg; 105 k= both_non_zero; 106 l= 0; 107 int i= 1; 108 while (k > 0) 109 { 110 max_min_deg= tmin (degsf[i], degsg[i]); 111 while (max_min_deg == 0) 112 { 113 i++; 114 max_min_deg= tmin (degsf[i], degsg[i]); 115 } 116 for (int j= i + 1; j <= m; j++) 117 { 118 if ((tmin (degsf[j],degsg[j]) < max_min_deg) && 119 (tmin (degsf[j], degsg[j]) != 0)) 120 { 121 max_min_deg= tmin (degsf[j], degsg[j]); 122 l= j; 123 } 124 } 125 126 if (l != 0) 127 { 128 if (l != k) 129 { 130 M.newpair (Variable (l), Variable(k)); 131 N.newpair (Variable (k), Variable(l)); 132 degsf[l]= 0; 133 degsg[l]= 0; 134 l= 0; 135 } 136 else 137 { 138 degsf[l]= 0; 139 degsg[l]= 0; 140 l= 0; 141 } 142 } 143 else if (l == 0) 144 { 145 if (i != k) 146 { 147 M.newpair (Variable (i), Variable (k)); 148 N.newpair (Variable (k), Variable (i)); 149 degsf[i]= 0; 150 degsg[i]= 0; 151 } 152 else 153 { 154 degsf[i]= 0; 155 degsg[i]= 0; 156 } 157 i++; 158 } 159 k--; 160 } 161 162 delete [] degsf; 163 delete [] degsg; 164 165 return both_non_zero; 166 } 167 168 static inline 169 CanonicalForm myShift2Zero (const CanonicalForm& F, CFList& Feval, 170 const CFList& evaluation) 171 { 172 CanonicalForm A= F; 173 int k= 2; 174 for (CFListIterator i= evaluation; i.hasItem(); i++, k++) 175 A= A (Variable (k) + i.getItem(), k); 176 177 CanonicalForm buf= A; 178 Feval= CFList(); 179 Feval.append (buf); 180 for (k= evaluation.length() + 1; k > 2; k--) 181 { 182 buf= mod (buf, Variable (k)); 183 Feval.insert (buf); 184 } 185 return A; 186 } 187 188 static inline 189 CanonicalForm myReverseShift (const CanonicalForm& F, const CFList& evaluation) 190 { 191 int l= evaluation.length() + 1; 192 CanonicalForm result= F; 193 CFListIterator j= evaluation; 194 for (int i= 2; i < l + 1; i++, j++) 195 { 196 if (F.level() < i) 197 continue; 198 result= result (Variable (i) - j.getItem(), i); 199 } 200 return result; 201 } 202 203 static inline 204 Evaluation optimize4Lift (const CanonicalForm& F, CFMap & M, 205 CFMap & N, const Evaluation& A) 206 { 207 int n= F.level(); 208 int * degsf= new int [n + 1]; 209 210 for (int i = 0; i <= n; i++) 211 degsf[i]= 0; 212 213 degsf= degrees (F, degsf); 214 215 Evaluation result= Evaluation (A.min(), A.max()); 216 ASSERT (A.min() == 2, "expected A.min() == 2"); 217 ASSERT (A.max() == n, "expected A.max() == n"); 218 int max_deg; 219 int k= n; 220 int l= 1; 221 int i= 2; 222 int pos= 2; 223 while (k > 1) 224 { 225 max_deg= degsf [i]; 226 while (max_deg == 0) 227 { 228 i++; 229 max_deg= degsf [i]; 230 } 231 l= i; 232 for (int j= i + 1; j <= n; j++) 233 { 234 if (degsf[j] > max_deg) 235 { 236 max_deg= degsf[j]; 237 l= j; 238 } 239 } 240 241 if (l <= n) 242 { 243 if (l != pos) 244 { 245 result.setValue (pos, A [l]); 246 M.newpair (Variable (l), Variable (pos)); 247 N.newpair (Variable (pos), Variable (l)); 248 degsf[l]= 0; 249 l= 2; 250 if (k == 2 && n == 3) 251 { 252 result.setValue (l, A [pos]); 253 M.newpair (Variable (pos), Variable (l)); 254 N.newpair (Variable (l), Variable (pos)); 255 degsf[pos]= 0; 256 } 257 } 258 else 259 { 260 result.setValue (l, A [l]); 261 degsf [l]= 0; 262 } 263 } 264 pos++; 265 k--; 266 l= 2; 267 } 268 269 delete [] degsf; 270 271 return result; 272 } 273 274 static inline 275 int Hensel (const CanonicalForm & UU, CFArray & G, const Evaluation & AA, 276 const CFArray& LeadCoeffs ) 277 { 278 CFList factors; 279 factors.append (G[1]); 280 factors.append (G[2]); 281 282 CFMap NN, MM; 283 Evaluation A= optimize4Lift (UU, MM, NN, AA); 284 285 CanonicalForm U= MM (UU); 286 CFArray LCs= CFArray (1,2); 287 LCs [1]= MM (LeadCoeffs [1]); 288 LCs [2]= MM (LeadCoeffs [2]); 289 290 CFList evaluation; 291 for (int i= A.min(); i <= A.max(); i++) 292 evaluation.append (A [i]); 293 CFList UEval; 294 CanonicalForm shiftedU= myShift2Zero (U, UEval, evaluation); 295 296 if (size (shiftedU)/getNumVars (U) > 500) 297 return -1; 298 299 CFArray shiftedLCs= CFArray (2); 300 CFList shiftedLCsEval1, shiftedLCsEval2; 301 shiftedLCs[0]= myShift2Zero (LCs[1], shiftedLCsEval1, evaluation); 302 shiftedLCs[1]= myShift2Zero (LCs[2], shiftedLCsEval2, evaluation); 303 factors.insert (1); 304 int liftBound= degree (UEval.getLast(), 2) + 1; 305 CFArray Pi; 306 CFMatrix M= CFMatrix (liftBound, factors.length() - 1); 307 CFList diophant; 308 CFArray lcs= CFArray (2); 309 lcs [0]= shiftedLCsEval1.getFirst(); 310 lcs [1]= shiftedLCsEval2.getFirst(); 311 nonMonicHenselLift12 (UEval.getFirst(), factors, liftBound, Pi, diophant, M, 312 lcs, false); 313 314 for (CFListIterator i= factors; i.hasItem(); i++) 315 { 316 if (!fdivides (i.getItem(), UEval.getFirst())) 317 return 0; 318 } 319 320 int * liftBounds; 321 bool noOneToOne= false; 322 if (U.level() > 2) 323 { 324 liftBounds= new int [U.level() - 1]; /* index: 0.. U.level()-2 */ 325 liftBounds[0]= liftBound; 326 for (int i= 1; i < U.level() - 1; i++) 327 liftBounds[i]= degree (shiftedU, Variable (i + 2)) + 1; 328 factors= nonMonicHenselLift2 (UEval, factors, liftBounds, U.level() - 1, 329 false, shiftedLCsEval1, shiftedLCsEval2, Pi, 330 diophant, noOneToOne); 331 delete [] liftBounds; 332 if (noOneToOne) 333 return 0; 334 } 335 G[1]= factors.getFirst(); 336 G[2]= factors.getLast(); 337 G[1]= myReverseShift (G[1], evaluation); 338 G[2]= myReverseShift (G[2], evaluation); 339 G[1]= NN (G[1]); 340 G[2]= NN (G[2]); 341 return 1; 342 } 343 344 static 345 bool findeval (const CanonicalForm & F, const CanonicalForm & G, 346 CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, 347 REvaluation & b, int delta, int degF, int degG, int maxeval, 348 int & count, int& k, int bound, int& l) 349 { 350 if( count == 0 && delta != 0) 351 { 352 if( count++ > maxeval ) 353 return false; 354 } 355 if (count > 0) 356 { 357 b.nextpoint(k); 358 if (k == 0) 359 k++; 360 l++; 361 if (l > bound) 362 { 363 l= 1; 364 k++; 365 if (k > tmax (F.level(), G.level()) - 1) 366 return false; 367 b.nextpoint (k); 368 } 369 if (count++ > maxeval) 370 return false; 371 } 372 while( true ) 373 { 374 Fb = b( F ); 375 if( degree( Fb, 1 ) == degF ) 376 { 377 Gb = b( G ); 378 if( degree( Gb, 1 ) == degG ) 379 { 380 Db = gcd( Fb, Gb ); 381 if( delta > 0 ) 382 { 383 if( degree( Db, 1 ) <= delta ) 384 return true; 385 } 386 else 387 { 388 k++; 389 return true; 390 } 391 } 392 } 393 if (k == 0) 394 k++; 395 b.nextpoint(k); 396 l++; 397 if (l > bound) 398 { 399 l= 1; 400 k++; 401 if (k > tmax (F.level(), G.level()) - 1) 402 return false; 403 b.nextpoint (k); 404 } 405 if( count++ > maxeval ) 406 return false; 407 } 408 } 409 410 static CanonicalForm 411 ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, REvaluation & b, 412 bool internal ) 413 { 414 bool isRat= isOn (SW_RATIONAL); 415 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, 416 lcD, cand, contcand, result; 417 CFArray DD( 1, 2 ), lcDD( 1, 2 ); 418 int degF, degG, delta, t, count, maxeval; 419 REvaluation bt; 420 bool gcdfound = false; 421 Variable x = Variable(1); 422 count= 0; 423 maxeval= 200; 424 int o, l; 425 o= 0; 426 l= 1; 427 428 if (!isRat) 429 On (SW_RATIONAL); 430 F= FF*bCommonDen (FF); 431 G= GG*bCommonDen (GG); 432 if (!isRat) 433 Off (SW_RATIONAL); 434 435 CFMap M,N; 436 int smallestDegLev; 437 int best_level= compress4EZGCD (F, G, M, N, smallestDegLev); 438 439 if (best_level == 0) 440 { 441 DEBDECLEVEL( cerr, "ezgcd" ); 442 return G.genOne(); 443 } 444 445 F= M (F); 446 G= M (G); 447 448 DEBINCLEVEL( cerr, "ezgcd" ); 449 DEBOUTLN( cerr, "FF = " << FF ); 450 DEBOUTLN( cerr, "GG = " << GG ); 451 f = content( F, x ); g = content( G, x ); d = gcd( f, g ); 452 d /= icontent (d); 453 DEBOUTLN( cerr, "f = " << f ); 454 DEBOUTLN( cerr, "g = " << g ); 455 F /= f; G /= g; 456 if ( F.isUnivariate() && G.isUnivariate() ) 457 { 458 DEBDECLEVEL( cerr, "ezgcd" ); 459 if(F.mvar()==G.mvar()) 460 d*=gcd(F,G); 461 return N (d); 462 } 463 464 int maxNumVars= tmax (getNumVars (F), getNumVars (G)); 465 int sizeF= size (F); 466 int sizeG= size (G); 467 468 469 if (!isRat) 470 On (SW_RATIONAL); 471 if (sizeF/maxNumVars > 500 && sizeG/maxNumVars > 500) 472 { 473 Off(SW_USE_EZGCD); 474 result=gcd( F, G ); 475 On(SW_USE_EZGCD); 476 if (!isRat) 477 Off (SW_RATIONAL); 478 result /= icontent (result); 479 DEBDECLEVEL( cerr, "ezgcd" ); 480 return N (d*result); 481 } 482 483 if ( gcd_test_one( F, G, false ) ) 484 { 485 DEBDECLEVEL( cerr, "ezgcd" ); 486 if (!isRat) 487 Off (SW_RATIONAL); 488 return N (d); 489 } 490 lcF = LC( F, x ); lcG = LC( G, x ); 491 lcD = gcd( lcF, lcG ); 492 delta = 0; 493 degF = degree( F, x ); degG = degree( G, x ); 494 t = tmax( F.level(), G.level() ); 495 if ( ! internal ) 496 b = REvaluation( 2, t, IntRandom( 25 ) ); 497 while ( ! gcdfound ) 498 { 499 /// ---> A2 500 DEBOUTLN( cerr, "search for evaluation, delta = " << delta ); 501 DEBOUTLN( cerr, "F = " << F ); 502 DEBOUTLN( cerr, "G = " << G ); 503 if (!findeval( F, G, Fb, Gb, Db, b, delta, degF, degG, maxeval, count, 504 o, 25, l)) 505 { 506 Off(SW_USE_EZGCD); 507 result=gcd( F, G ); 508 On(SW_USE_EZGCD); 509 if (!isRat) 510 Off (SW_RATIONAL); 511 DEBDECLEVEL( cerr, "ezgcd" ); 512 result /= icontent (result); 513 return N (d*result); 514 } 515 DEBOUTLN( cerr, "found evaluation b = " << b ); 516 DEBOUTLN( cerr, "F(b) = " << Fb ); 517 DEBOUTLN( cerr, "G(b) = " << Gb ); 518 DEBOUTLN( cerr, "D(b) = " << Db ); 519 delta = degree( Db ); 520 /// ---> A3 521 if ( delta == 0 ) 522 { 523 DEBDECLEVEL( cerr, "ezgcd" ); 524 if (!isRat) 525 Off (SW_RATIONAL); 526 return N (d); 527 } 528 /// ---> A4 529 //deltaold = delta; 530 while ( 1 ) 531 { 532 bt = b; 533 if (!findeval( F, G, Fbt, Gbt, Dbt, bt, delta, degF, degG, maxeval, count, 534 o, 25,l )) 535 { 536 Off(SW_USE_EZGCD); 537 result=gcd( F, G ); 538 On(SW_USE_EZGCD); 539 if (!isRat) 540 Off (SW_RATIONAL); 541 DEBDECLEVEL( cerr, "ezgcd" ); 542 result /= icontent (result); 543 return N (d*result); 544 } 545 int dd=degree( Dbt ); 546 if ( dd /*degree( Dbt )*/ == 0 ) 547 { 548 DEBDECLEVEL( cerr, "ezgcd" ); 549 if (!isRat) 550 Off (SW_RATIONAL); 551 return N (d); 552 } 553 if ( dd /*degree( Dbt )*/ == delta ) 554 break; 555 else if ( dd /*degree( Dbt )*/ < delta ) 556 { 557 delta = dd /*degree( Dbt )*/; 558 b = bt; 559 Db = Dbt; Fb = Fbt; Gb = Gbt; 560 } 561 } 562 DEBOUTLN( cerr, "now after A4, delta = " << delta ); 563 /// ---> A5 564 if (delta == degF) 565 { 566 if (degF <= degG && fdivides (F, G)) 567 { 568 DEBDECLEVEL( cerr, "ezgcd" ); 569 if (!isRat) 570 Off (SW_RATIONAL); 571 return N (d*F); 572 } 573 else 574 delta--; 575 } 576 else if (delta == degG) 577 { 578 if (degG <= degF && fdivides( G, F )) 579 { 580 DEBDECLEVEL( cerr, "ezgcd" ); 581 if (!isRat) 582 Off (SW_RATIONAL); 583 return N (d*G); 584 } 585 else 586 delta--; 587 } 588 if ( delta != degF && delta != degG ) 589 { 590 /// ---> A6 591 bool B_is_F; 592 CanonicalForm xxx1, xxx2; 593 CanonicalForm buf; 594 DD[1] = Fb / Db; 595 buf= Gb/Db; 596 xxx1 = gcd( DD[1], Db ); 597 xxx2 = gcd( buf, Db ); 598 if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 599 (size (F) <= size (G))) 600 || (xxx1.inCoeffDomain() && !xxx2.inCoeffDomain())) 601 { 602 B = F; 603 DD[2] = Db; 604 lcDD[1] = lcF; 605 lcDD[2] = lcD; 606 B_is_F = true; 607 } 608 else if (((xxx1.inCoeffDomain() && xxx2.inCoeffDomain()) && 609 (size (G) < size (F))) 610 || (!xxx1.inCoeffDomain() && xxx2.inCoeffDomain())) 611 { 612 DD[1] = buf; 613 B = G; 614 DD[2] = Db; 615 lcDD[1] = lcG; 616 lcDD[2] = lcD; 617 B_is_F = false; 618 } 619 else 620 { 621 //special case 622 Off(SW_USE_EZGCD); 623 result=gcd( F, G ); 624 On(SW_USE_EZGCD); 625 if (!isRat) 626 Off (SW_RATIONAL); 627 DEBDECLEVEL( cerr, "ezgcd" ); 628 result /= icontent (result); 629 return N (d*result); 630 } 631 /// ---> A7 632 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) ); 633 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) ); 634 DEBOUTLN( cerr, "(hensel) B = " << B ); 635 DEBOUTLN( cerr, "(hensel) lcB = " << LC( B, Variable(1) ) ); 636 DEBOUTLN( cerr, "(hensel) b(B) = " << b(B) ); 637 DEBOUTLN( cerr, "(hensel) DD = " << DD ); 638 DEBOUTLN( cerr, "(hensel) lcDD = " << lcDD ); 639 gcdfound= Hensel (B*lcD, DD, b, lcDD); 640 DEBOUTLN( cerr, "(hensel finished) DD = " << DD ); 641 642 if (gcdfound == -1) 643 { 644 Off (SW_USE_EZGCD); 645 result= gcd (F,G); 646 On (SW_USE_EZGCD); 647 if (!isRat) 648 Off (SW_RATIONAL); 649 DEBDECLEVEL( cerr, "ezgcd" ); 650 result /= icontent (result); 651 return N (d*result); 652 } 653 654 if (gcdfound) 655 { 656 contcand= content (DD[2], Variable (1)); 657 cand = DD[2] / contcand; 658 if (B_is_F) 659 gcdfound = fdivides( cand, G ) && cand*(DD[1]/(lcD/contcand)) == F; 660 else 661 gcdfound = fdivides( cand, F ) && cand*(DD[1]/(lcD/contcand)) == G; 662 } 663 /// ---> A8 (gcdfound) 664 } 665 delta--; 666 } 667 /// ---> A9 668 DEBDECLEVEL( cerr, "ezgcd" ); 669 cand *= bCommonDen (cand); 670 if (!isRat) 671 Off (SW_RATIONAL); 672 cand /= icontent (cand); 673 return N (d*cand); 674 } 28 675 29 676 CanonicalForm 30 677 ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG ) 31 678 { 32 REvaluation b; 33 return ezgcd( FF, GG, b, false ); 34 } 35 36 static CanonicalForm 37 ezgcd ( const CanonicalForm & FF, const CanonicalForm & GG, REvaluation & b, bool internal ) 38 { 39 CanonicalForm F, G, f, g, d, Fb, Gb, Db, Fbt, Gbt, Dbt, B0, B, D0, lcF, lcG, lcD; 40 CFArray DD( 1, 2 ), lcDD( 1, 2 ); 41 int degF, degG, delta, t; 42 REvaluation bt; 43 bool gcdfound = false; 44 Variable x = Variable(1); 45 modpk bound; 46 47 DEBINCLEVEL( cerr, "ezgcd" ); 48 DEBOUTLN( cerr, "FF = " << FF ); 49 DEBOUTLN( cerr, "GG = " << GG ); 50 f = content( FF, x ); g = content( GG, x ); d = gcd( f, g ); 51 DEBOUTLN( cerr, "f = " << f ); 52 DEBOUTLN( cerr, "g = " << g ); 53 F = FF / f; G = GG / g; 54 if ( F.isUnivariate() && G.isUnivariate() ) 55 { 56 DEBDECLEVEL( cerr, "ezgcd" ); 57 if(F.mvar()==G.mvar()) 58 d*=gcd(F,G); 59 return d; 60 } 61 else if ( gcd_test_one( F, G, false ) ) 62 { 63 DEBDECLEVEL( cerr, "ezgcd" ); 64 return d; 65 } 66 lcF = LC( F, x ); lcG = LC( G, x ); 67 lcD = gcd( lcF, lcG ); 68 delta = 0; 69 degF = degree( F, x ); degG = degree( G, x ); 70 t = tmax( F.level(), G.level() ); 71 bound = findBound( F, G, lcF, lcG, degF, degG ); 72 if ( ! internal ) 73 b = REvaluation( 2, t, IntRandom( 25 ) ); 74 while ( ! gcdfound ) { 75 /// ---> A2 76 DEBOUTLN( cerr, "search for evaluation, delta = " << delta ); 77 DEBOUTLN( cerr, "F = " << F ); 78 DEBOUTLN( cerr, "G = " << G ); 79 findeval( F, G, Fb, Gb, Db, b, delta, degF, degG ); 80 DEBOUTLN( cerr, "found evaluation b = " << b ); 81 DEBOUTLN( cerr, "F(b) = " << Fb ); 82 DEBOUTLN( cerr, "G(b) = " << Gb ); 83 DEBOUTLN( cerr, "D(b) = " << Db ); 84 delta = degree( Db ); 85 /// ---> A3 86 if ( delta == 0 ) 87 { 88 DEBDECLEVEL( cerr, "ezgcd" ); 89 return d; 90 } 91 /// ---> A4 92 //deltaold = delta; 93 while ( 1 ) { 94 bt = b; 95 findeval( F, G, Fbt, Gbt, Dbt, bt, delta + 1, degF, degG ); 96 int dd=degree( Dbt ); 97 if ( dd /*degree( Dbt )*/ == 0 ) 98 { 99 DEBDECLEVEL( cerr, "ezgcd" ); 100 return d; 101 } 102 if ( dd /*degree( Dbt )*/ == delta ) 103 break; 104 else if ( dd /*degree( Dbt )*/ < delta ) { 105 delta = dd /*degree( Dbt )*/; 106 b = bt; 107 Db = Dbt; Fb = Fbt; Gb = Gbt; 108 } 109 } 110 DEBOUTLN( cerr, "now after A4, delta = " << delta ); 111 /// ---> A5 112 if ( degF <= degG && delta == degF && fdivides( F, G ) ) 113 { 114 DEBDECLEVEL( cerr, "ezgcd" ); 115 return d*F; 116 } 117 if ( degG < degF && delta == degG && fdivides( G, F ) ) 118 { 119 DEBDECLEVEL( cerr, "ezgcd" ); 120 return d*G; 121 } 122 if ( delta != degF && delta != degG ) { 123 bool B_is_F; 124 /// ---> A6 125 CanonicalForm xxx; 126 //if ( gcd( (DD[1] = Fb / Db), Db ) == 1 ) { 127 DD[1] = Fb / Db; 128 xxx= gcd( DD[1], Db ); 129 DEBOUTLN( cerr, "gcd((Fb/Db),Db) = " << xxx ); 130 DEBOUTLN( cerr, "Fb/Db = " << DD[1] ); 131 DEBOUTLN( cerr, "Db = " << Db ); 132 if (xxx.inCoeffDomain()) { 133 B = F; 134 DD[2] = Db; 135 lcDD[1] = lcF; 136 lcDD[2] = lcF; 137 B *= lcF; 138 B_is_F=true; 139 } 140 //else if ( gcd( (DD[1] = Gb / Db), Db ) == 1 ) { 141 else 142 { 143 DD[1] = Gb / Db; 144 xxx=gcd( DD[1], Db ); 145 DEBOUTLN( cerr, "gcd((Gb/Db),Db) = " << xxx ); 146 DEBOUTLN( cerr, "Gb/Db = " << DD[1] ); 147 DEBOUTLN( cerr, "Db = " << Db ); 148 if (xxx.inCoeffDomain()) 149 { 150 B = G; 151 DD[2] = Db; 152 lcDD[1] = lcG; 153 lcDD[2] = lcG; 154 B *= lcG; 155 B_is_F=false; 156 } 157 else 158 { 159 #ifdef DEBUGOUTPUT 160 CanonicalForm dummyres = d * ezgcd_specialcase( F, G, b, bound ); 161 DEBDECLEVEL( cerr, "ezgcd" ); 162 return dummyres; 163 #else 164 return d * ezgcd_specialcase( F, G, b, bound ); 165 #endif 166 } 167 } 168 /// ---> A7 169 DD[2] = DD[2] * ( b( lcDD[2] ) / lc( DD[2] ) ); 170 DD[1] = DD[1] * ( b( lcDD[1] ) / lc( DD[1] ) ); 171 bound = enlargeBound( B, DD[2], DD[1], bound ); 172 DEBOUTLN( cerr, "(hensel) B = " << B ); 173 DEBOUTLN( cerr, "(hensel) lcB = " << LC( B, Variable(1) ) ); 174 DEBOUTLN( cerr, "(hensel) b(B) = " << b(B) ); 175 DEBOUTLN( cerr, "(hensel) DD = " << DD ); 176 DEBOUTLN( cerr, "(hensel) lcDD = " << lcDD ); 177 gcdfound = Hensel( B, DD, lcDD, b, bound, x ); 178 DEBOUTLN( cerr, "(hensel finished) DD = " << DD ); 179 180 if (gcdfound) 181 { 182 CanonicalForm xxx=content(DD[2],Variable(1)); 183 CanonicalForm cand=DD[2] / xxx; //content(DD[2],Variable(1)); 184 #if 0 185 gcdfound= fdivides(cand,G) && fdivides(cand,F); 186 #else 187 if (B_is_F /*B==F*lcF*/) 188 { 189 DEBOUTLN( cerr, "(test) G: "<<G<<" % gcd:"<<cand<<" -> " << G%cand ); 190 gcdfound= fdivides(cand,G); 191 } 192 else 193 { 194 DEBOUTLN( cerr, "(test) F: "<<F<<" % gcd:"<<cand<<" -> " << F%cand); 195 gcdfound= fdivides(cand,F); 196 } 197 #endif 198 } 199 /// ---> A8 (gcdfound) 200 } 201 delta++; 202 } 203 /// ---> A9 204 DEBDECLEVEL( cerr, "ezgcd" ); 205 return d * DD[2] / content(DD[2],Variable(1)); 206 } 207 208 static CanonicalForm 209 ezgcd_specialcase ( const CanonicalForm & F, const CanonicalForm & G, REvaluation & /*b*/, const modpk & /*bound*/ ) 210 { 211 CanonicalForm d; 212 #if 1 213 Off(SW_USE_EZGCD); 214 //bool ntl0=isOn(SW_USE_NTL_GCD_0); 215 //Off(SW_USE_NTL_GCD_0); 216 //bool ntlp=isOn(SW_USE_NTL_GCD_P); 217 //Off(SW_USE_NTL_GCD_P); 218 d=gcd( F, G ); 219 //if (ntl0) On(SW_USE_NTL_GCD_0); 220 //if (ntlp) On(SW_USE_NTL_GCD_P); 221 On(SW_USE_EZGCD); 222 return d; 223 #else 224 /* 225 * I am not sure, if these lines are much of use. 226 * Remove? 227 */ 228 DEBOUTLN( cerr, "ezgcd: special case" ); 229 CanonicalForm Ft, Gt, L, LL, Fb, Gb, Db, Lb, D, Ds, Dt; 230 CFArray DD( 1, 2 ), lcDD( 1, 2 ); 231 Variable x = Variable( 1 ); 232 bool gcdfound; 233 234 Dt = 1; 235 /// ---> S1 236 DEBOUTLN( cerr, "ezgcdspec: (S1)" ); 237 Ft = ezgcd( F, F.deriv( x ) ); 238 if ( Ft.isOne() ) 239 { 240 // In this case F is squarefree and we came here by bad chance 241 // (means: bad evaluation point). Try again with another 242 // evaluation point. Bug fix (?) by JS. The bad example was 243 // gcd.debug -ocr /+USE_EZGCD/@12/CB 244 // '(16*B^8-208*B^6*C+927*B^4*C^2-1512*B^2*C^3+432*C^4)' 245 // '(4*B^7*C^2-50*B^5*C^3+208*B^3*C^4-288*B*C^5)' 246 b.nextpoint(); 247 return ezgcd( F, G, b, true ); 248 } 249 250 DEBOUTLN( cerr, "ezgcdspec: (S1) done, Ft = " << Ft ); 251 L = F / Ft; 252 /// ---> S2 253 DEBOUTLN( cerr, "ezgcdspec: (S2)" ); 254 255 L = ezgcd( L, G, b, true ); 256 DEBOUTLN( cerr, "ezgcdspec: (S2) done, Ds = " << Ds ); 257 Gt = G / L; 258 Ds = L; Dt = L; 259 Lb = b( L ); Gb = b( Gt ); Fb = b( Ft ); 260 d = gcd( LC( L, x ), gcd( LC( Ft, x ), LC( Gt, x ) ) ); 261 while ( true ) { 262 /// ---> S3 263 DEBOUTLN( cerr, "ezgcdspec: (S3)" ); 264 DEBOUTLN( cerr, "ezgcdspec: Fb = " << Fb ); 265 DEBOUTLN( cerr, "ezgcdspec: Gb = " << Gb ); 266 DD[1] = gcd( Lb, gcd( Fb, Gb ) ); 267 /// ---> S4 268 DEBOUTLN( cerr, "ezgcdspec: (S4)" ); 269 if ( degree( DD[1] ) == 0 ) 270 return Ds; 271 /// ---> S5 272 DEBOUTLN( cerr, "ezgcdspec: (S5)" ); 273 DEBOUTLN( cerr, "ezgcdspec: Lb = " << Lb ); 274 DEBOUTLN( cerr, "ezgcdspec: Db = " << DD[1] ); 275 Db = DD[1]; 276 if ( ! (DD[2] = Lb/DD[1]).isOne() ) { 277 DEBOUTLN( cerr, "ezgcdspec: (S55)" ); 278 lcDD[2] = LC( L, x ); 279 lcDD[1] = d; 280 DD[1] = ( DD[1] * b( d ) ) / lc( DD[1] ); 281 DD[2] = ( DD[2] * b( lcDD[2] ) ) / lc( DD[2] ); 282 LL = L * d; 283 modpk newbound = enlargeBound( LL, DD[2], DD[1], bound ); 284 DEBOUTLN( cerr, "ezgcdspec: begin with lift." ); 285 DEBOUTLN( cerr, "ezgcdspec: B = " << LL ); 286 DEBOUTLN( cerr, "ezgcdspec: DD = " << DD ); 287 DEBOUTLN( cerr, "ezgcdspec: lcDD = " << lcDD ); 288 DEBOUTLN( cerr, "ezgcdspec: b = " << b ); 289 DEBOUTLN( cerr, "ezgcdspec: bound = " << bound.getpk() ); 290 DEBOUTLN( cerr, "ezgcdspec: lc(B) = " << LC( LL, x ) ); 291 DEBOUTLN( cerr, "ezgcdspec: test = " << b( LL ) - DD[1] * DD[2] ); 292 gcdfound = Hensel( LL, DD, lcDD, b, newbound, x ); 293 ASSERT( gcdfound, "fatal error in algorithm" ); 294 Dt = pp( DD[1] ); 295 } 296 DEBOUTLN( cerr, "ezgcdspec: (S7)" ); 297 Ds = Ds * Dt; 298 Fb = Fb / Db; 299 Gb = Gb / Db; 300 } 301 // this point is never reached, but to avoid compiler warnings let's return a value 302 return 0; 303 #endif 304 } 305 306 static void 307 findeval( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & Fb, CanonicalForm & Gb, CanonicalForm & Db, REvaluation & b, int delta, int degF, int degG ) 308 { 309 bool ok; 310 if ( delta != 0 ) 311 b.nextpoint(); 312 DEBOUTLN( cerr, "ezgcd: (findeval) F = " << F <<", G="<< G); 313 DEBOUTLN( cerr, "ezgcd: (findeval) degF = " << degF << ", degG="<<degG ); 314 do { 315 DEBOUTLN( cerr, "ezgcd: (findeval) b = " << b ); 316 Fb = b( F ); 317 ok = degree( Fb ) == degF; 318 if ( ok ) { 319 Gb = b( G ); 320 ok = degree( Gb ) == degG; 321 } 322 323 if ( ok ) 324 { 325 Db = gcd( Fb, Gb ); 326 if ( delta > 0 ) 327 ok = degree( Db ) < delta; 328 } 329 if ( ! ok ) 330 { 331 b.nextpoint(); 332 } 333 } while ( ! ok ); 334 } 335 336 static modpk 337 enlargeBound ( const CanonicalForm & F, const CanonicalForm & Lb, const CanonicalForm & Db, const modpk & pk ) 338 { 339 DEBOUTLN( cerr, "ezgcd: (enlarge bound) F = " << F ); 340 DEBOUTLN( cerr, "ezgcd: (enlarge bound) Lb = " << Lb ); 341 DEBOUTLN( cerr, "ezgcd: (enlarge bound) Db = " << Db ); 342 DEBOUTLN( cerr, "ezgcd: (enlarge bound) Lb % p = " << mod( Lb, pk.getp() ) ); 343 DEBOUTLN( cerr, "ezgcd: (enlarge bound) Db % p = " << mod( Db, pk.getp() ) ); 344 345 CanonicalForm limit = power( CanonicalForm(2), degree( Db ) ) * 346 tmax( maxNorm( Lb ), tmax( maxNorm( Db ), maxNorm( F ) ) ); 347 int p = pk.getp(); 348 int k = pk.getk(); 349 CanonicalForm bound = pk.getpk(); 350 while ( bound < limit ) { 351 k++; 352 bound *= p; 353 } 354 k *= 2; 355 DEBOUTLN( cerr, "ezgcd: (enlarge bound) newbound = " << power( CanonicalForm( p ), k ) ); 356 return modpk( p, k ); 357 } 358 359 static modpk 360 findBound ( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & lcF, const CanonicalForm & lcG, int degF, int degG ) 361 { 362 CanonicalForm limit = power( CanonicalForm(2), tmin( degF, degG ) ) * 363 gcd( icontent( lcF ), icontent( lcG ) ) * tmin( maxNorm( F ), maxNorm( G ) ); 364 int p, i = 0; 365 do { 366 p = cf_getBigPrime( i ); 367 i++; 368 } while ( mod( lcF, p ).isZero() && mod( lcG, p ).isZero() ); 369 CanonicalForm bound = p; 370 i = 1; 371 while ( bound < limit ) { 372 i++; 373 bound *= p; 374 } 375 return modpk( p, i ); 376 } 679 REvaluation b; 680 return ezgcd( FF, GG, b, false ); 681 } 682
Note: See TracChangeset
for help on using the changeset viewer.