Changeset 359d742 in git
- Timestamp:
- Jun 24, 2008, 2:52:44 PM (15 years ago)
- Branches:
- (u'spielwiese', '828514cf6e480e4bafc26df99217bf2a1ed1ef45')
- Children:
- 18c7a3e40a89b378bb7b4666e1f16148b663f9e8
- Parents:
- 863f53819a571f2381b1eac36056dff30adc1904
- Location:
- factory
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
factory/algext.cc
r863f53 r359d742 9 9 #include "cf_algorithm.h" 10 10 #include "algext.h" 11 11 #include "fieldGCD.h" 12 #include "cf_map.h" 13 #include "cf_generator.h" 12 14 13 15 void tryEuclid( const CanonicalForm & A, const CanonicalForm & B, const CanonicalForm M, CanonicalForm & result, bool & fail ) … … 61 63 Variable x = Variable(1); 62 64 if(!extgcd( replacevar( F, a, x ), replacevar( M, a, x ), inv, b ).isOne()) 65 { 66 printf("failed "); 63 67 fail = true; 68 } 64 69 else 65 70 inv = replacevar( inv, a, x); // change back to alg var … … 84 89 } 85 90 86 87 CanonicalForm QGCD( const CanonicalForm & F, const CanonicalForm & G ) 88 { 91 CanonicalForm univarQGCD( const CanonicalForm & F, const CanonicalForm & G ) 92 { // F,G in Q(a)[x] 89 93 CanonicalForm f, g, tmp, M, q, D, Dp, cl, newD, newq; 90 94 int p, dp_deg, bound, i; … … 133 137 dp_deg = degree(Dp); 134 138 135 if( !dp_deg ) // early termination 139 if( dp_deg == 0 ) // early termination 140 { 141 CanonicalForm inv; 142 tryInvert(Dp, M, inv, fail); 143 if(fail) 144 continue; 136 145 return CanonicalForm(1); 146 } 137 147 138 148 if( dp_deg > bound ) // current prime unlucky … … 171 181 return D; 172 182 } 183 184 185 CanonicalForm QGCD( const CanonicalForm & F, const CanonicalForm & G ) 186 { // F,G in Q(a)[x1,...,xn] 187 if(F.isZero()) 188 { 189 if(G.isZero()) 190 return G; // G is zero 191 if(G.inCoeffDomain()) 192 return CanonicalForm(1); 193 return G/Lc(G); // return monic G 194 } 195 if(G.isZero()) // F is non-zero 196 { 197 if(F.inCoeffDomain()) 198 return CanonicalForm(1); 199 return F/Lc(F); // return monic F 200 } 201 if(F.inCoeffDomain() || G.inCoeffDomain()) 202 return CanonicalForm(1); 203 204 CanonicalForm D; 205 if (getCharacteristic()==0) 206 { 207 CanonicalForm f,g,tmp, M, q, Dp, cl, newD, newq; 208 int p, i; 209 int *bound, *other; // degree vectors 210 bool fail; 211 On(SW_RATIONAL); 212 f = F * bCommonDen(F); 213 g = G * bCommonDen(G); 214 Variable a,b; 215 if( !hasFirstAlgVar( f, a ) && !hasFirstAlgVar( g, b )) 216 { 217 // F and G are in Q[x1,...,xn], call... 218 return gcd_poly_0( f, g ); 219 } 220 if( b.level() > a.level() ) 221 a = b; 222 // here: a is the biggest alg. var in f and g 223 tmp = getMipo(a); 224 M = tmp * bCommonDen(tmp); 225 Off( SW_RATIONAL ); 226 // here: f, g in Z[y][x1,...,xn], M in Z[y] not necessarily monic 227 // calculate upper bound for degree of gcd 228 int mv = f.level(); 229 if(g.level() > mv) 230 mv = g.level(); 231 // here: mv is level of the largest variable in f, g 232 bound = new int[mv+1]; 233 other = new int[mv+1]; 234 for(int i=1; i<=mv; i++) 235 bound[i] = other[i] = 0; 236 bound = leadDeg(f,bound); 237 other = leadDeg(g,other); 238 for(int i=1; i<=mv; i++) // entry at i=0 is not visited 239 if(other[i] < bound[i]) 240 bound[i] = other[i]; 241 // now bound points on the smaller vector 242 cl = lc(M) * lc(f) * lc(g); 243 q = 1; 244 D = 0; 245 for(int i=cf_getNumBigPrimes()-1; i>-1; i--) 246 { 247 p = cf_getBigPrime(i); 248 if( mod( cl, p ).isZero() ) // skip lc-bad primes 249 continue; 250 251 fail = false; 252 setCharacteristic(p); 253 tryBrownGCD( mapinto(f), mapinto(g), mapinto(M), Dp, fail ); 254 setCharacteristic(0); 255 if( fail ) // M splits in char p 256 continue; 257 258 for(int i=1; i<=mv; i++) 259 other[i] = 0; // reset (this is necessary, because some entries may not be updated by call to leadDeg) 260 other = leadDeg(Dp,other); 261 262 if( other==0 ) // early termination 263 { 264 // Dp is in coeff domain 265 CanonicalForm inv; 266 tryInvert(Dp,M,inv,fail); // check if zero-divisor 267 if(fail) 268 continue; 269 return CanonicalForm(1); 270 } 271 272 if( isLess(bound, other, 1, mv) ) // current prime unlucky 273 continue; 274 275 if( isLess(other, bound, 1, mv) ) // all previous primes unlucky 276 { 277 q = p; 278 D = mapinto(Dp); // shortcut CRA 279 for(int i=1; i<=mv; i++) // tighten bound 280 bound[i] = other[i]; 281 continue; 282 } 283 chineseRemainder( D, q, mapinto(Dp), p, newD, newq ); 284 // newD = Dp mod p 285 // newD = D mod q 286 // newq = p*q 287 q = newq; 288 if( D != newD ) 289 { 290 D = newD; 291 continue; 292 } 293 On( SW_RATIONAL ); 294 tmp = Farey( D, q ); 295 if( fdivides( tmp, f ) && fdivides( tmp, g )) // trial division 296 { 297 Off( SW_RATIONAL ); 298 return tmp; 299 } 300 Off( SW_RATIONAL ); 301 } 302 } 303 // hopefully, we never reach this point 304 Off( SW_USE_QGCD ); 305 D = gcd( F, G ); 306 On( SW_USE_QGCD ); 307 return D; 308 } 309 310 void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail ) 311 {// assume F,G are multivariate polys over Z/p(a) for big prime p, M "univariate" polynomial in an algebraic variable 312 printf("Brown "); 313 if(F.isZero()) 314 { 315 if(G.isZero()) 316 { 317 result = G; // G is zero 318 return; 319 } 320 if(G.inCoeffDomain()) 321 { 322 tryInvert(G,M,result,fail); 323 return; 324 } 325 // try to make G monic modulo M 326 CanonicalForm inv; 327 tryInvert(Lc(G),M,inv,fail); 328 if(fail) 329 return; 330 result = inv*G; 331 return; 332 } 333 if(G.isZero()) // F is non-zero 334 { 335 if(F.inCoeffDomain()) 336 { 337 tryInvert(F,M,result,fail); 338 return; 339 } 340 // try to make F monic modulo M 341 CanonicalForm inv; 342 tryInvert(Lc(F),M,inv,fail); 343 if(fail) 344 return; 345 result = inv*F; 346 return; 347 } 348 if(F.inCoeffDomain()) 349 { 350 tryInvert(F,M,result,fail); 351 return; 352 } 353 if(G.inCoeffDomain()) 354 { 355 tryInvert(G,M,result,fail); 356 return; 357 } 358 CFMap MM,NN; 359 CFArray ps(1,2); 360 ps[1] = F; 361 ps[2] = G; 362 compress(ps,MM,NN); // maps MM, NN are created 363 CanonicalForm f=MM(F); 364 CanonicalForm g=MM(G); 365 // here: f, g are compressed 366 // compute largest variable in f or g (least one is Variable(1)) 367 int mv = f.level(); 368 if(g.level() > mv) 369 mv = g.level(); 370 // here: mv is level of the largest variable in f, g 371 if(mv == 1) // f,g univariate 372 { 373 tryEuclid(f,g,M,result,fail); 374 if(fail) 375 return; 376 result = NN(result); // do not forget to map back 377 return; 378 } 379 // here: mv > 1 380 CanonicalForm cf = vcontent(f, Variable(2)); // cf is univariate poly in var(1) 381 CanonicalForm cg = vcontent(g, Variable(2)); 382 CanonicalForm c; 383 tryEuclid(cf,cg,M,c,fail); 384 if(fail) 385 return; 386 f/=cf; 387 g/=cg; 388 if(f.inCoeffDomain()) 389 { 390 tryInvert(f,M,result,fail); 391 if(fail) 392 return; 393 result = NN(result); 394 return; 395 } 396 if(g.inCoeffDomain()) 397 { 398 tryInvert(g,M,result,fail); 399 if(fail) 400 return; 401 result = NN(result); 402 return; 403 } 404 int *L = new int[mv+1]; // L is addressed by i from 2 to mv 405 int *N = new int[mv+1]; 406 for(int i=2; i<=mv; i++) 407 L[i] = N[i] = 0; 408 L = leadDeg(f, L); 409 N = leadDeg(g, N); 410 CanonicalForm gamma; 411 tryEuclid( firstLC(f), firstLC(g), M, gamma, fail ); 412 if(fail) 413 return; 414 for(int i=2; i<=mv; i++) // entry at i=1 is not visited 415 if(N[i] < L[i]) 416 L[i] = N[i]; 417 // L is now upper bound for degrees of gcd 418 int *dg_im = new int[mv+1]; // for the degree vector of the image we don't need any entry at i=1 419 for(int i=2; i<=mv; i++) 420 dg_im[i] = 0; // initialize 421 CanonicalForm gamma_image, m=1; 422 CanonicalForm gm=0; 423 CanonicalForm g_image, alpha, gnew, mnew; 424 FFGenerator gen = FFGenerator(); 425 for(FFGenerator gen = FFGenerator(); gen.hasItems(); gen.next()) 426 { 427 alpha = gen.item(); 428 gamma_image = gamma(alpha, Variable(1)); // plug in alpha for var(1) 429 if(gamma_image.isZero()) // skip lc-bad points var(1)-alpha 430 continue; 431 tryBrownGCD( f(alpha, Variable(1)), g(alpha, Variable(1)), M, g_image, fail ); // recursive call with one var less 432 if(fail) 433 return; 434 if(g_image.inCoeffDomain()) // early termination 435 { 436 tryInvert(g_image,M,result,fail); 437 if(fail) 438 return; 439 result = NN(c); 440 return; 441 } 442 for(int i=2; i<=mv; i++) 443 dg_im[i] = 0; // reset (this is necessary, because some entries may not be updated by call to leadDeg) 444 dg_im = leadDeg(g_image, dg_im); // dg_im cannot be NIL-pointer 445 if(isEqual(dg_im, L, 2, mv)) 446 { 447 g_image /= lc(g_image); // make g_image monic over Z/p 448 g_image *= gamma_image; // multiply by multiple of image lc(gcd) 449 tryCRA( g_image, Variable(1)-alpha, gm, m, gnew, mnew, fail ); 450 // gnew = gm mod m 451 // gnew = g_image mod var(1)-alpha 452 // mnew = m * (var(1)-alpha) 453 if(fail) 454 return; 455 m = mnew; 456 if(gnew == gm) // gnew did not change 457 { 458 g_image = gm / vcontent(gm, Variable(2)); 459 if(fdivides(g_image,f) && fdivides(g_image,g)) // trial division 460 { 461 result = NN(c*g_image); 462 return; 463 } 464 } 465 gm = gnew; 466 continue; 467 } 468 469 if(isLess(L, dg_im, 2, mv)) // dg_im > L --> current point unlucky 470 continue; 471 472 if(isLess(dg_im, L, 2, mv)) // dg_im < L --> all previous points were unlucky 473 { 474 m = CanonicalForm(1); // reset 475 gm = 0; // reset 476 for(int i=2; i<=mv; i++) // tighten bound 477 L[i] = dg_im[i]; 478 } 479 } 480 // we are out of evaluation points 481 fail = true; 482 } 483 484 485 void tryCRA( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew, bool & fail ) 486 { // polys of level <= 1 are considered coefficients. q1,q2 are assumed to be coprime 487 // xnew = x1 mod q1 (coefficientwise in the above sense) 488 // xnew = x2 mod q2 489 // qnew = q1*q2 490 CanonicalForm tmp; 491 if(x1.level() <= 1 && x2.level() <= 1) // base case 492 { 493 tryExtgcd(q1,q2,tmp,xnew,qnew,fail); 494 if(fail) 495 return; 496 xnew = x1 + (x2-x1) * xnew * q1; 497 qnew = q1*q2; 498 xnew = mod(xnew,qnew); 499 return; 500 } 501 CanonicalForm tmp2; 502 xnew = 0; 503 qnew = q1 * q2; 504 // here: x1.level() > 1 || x2.level() > 1 505 if(x1.level() > x2.level()) 506 { 507 for(CFIterator i=x1; i.hasTerms(); i++) 508 { 509 if(i.exp() == 0) // const. term 510 { 511 tryCRA(i.coeff(),q1,x2,q2,tmp,tmp2,fail); 512 if(fail) 513 return; 514 xnew += tmp; 515 } 516 else 517 { 518 tryCRA(i.coeff(),q1,0,q2,tmp,tmp2,fail); 519 if(fail) 520 return; 521 xnew += tmp * power(x1.mvar(),i.exp()); 522 } 523 } 524 return; 525 } 526 // here: x1.level() <= x2.level() && ( x1.level() > 1 || x2.level() > 1 ) 527 if(x2.level() > x1.level()) 528 { 529 for(CFIterator j=x2; j.hasTerms(); j++) 530 { 531 if(j.exp() == 0) // const. term 532 { 533 tryCRA(x1,q1,j.coeff(),q2,tmp,tmp2,fail); 534 if(fail) 535 return; 536 xnew += tmp; 537 } 538 else 539 { 540 tryCRA(0,q1,j.coeff(),q2,tmp,tmp2,fail); 541 if(fail) 542 return; 543 xnew += tmp * power(x2.mvar(),j.exp()); 544 } 545 } 546 return; 547 } 548 // here: x1.level() == x2.level() && x1.level() > 1 && x2.level() > 1 549 CFIterator i = x1; 550 CFIterator j = x2; 551 while(i.hasTerms() || j.hasTerms()) 552 { 553 if(i.hasTerms()) 554 { 555 if(j.hasTerms()) 556 { 557 if(i.exp() == j.exp()) 558 { 559 tryCRA(i.coeff(),q1,j.coeff(),q2,tmp,tmp2,fail); 560 if(fail) 561 return; 562 xnew += tmp * power(x1.mvar(),i.exp()); 563 i++; j++; 564 } 565 else 566 { 567 if(i.exp() < j.exp()) 568 { 569 tryCRA(i.coeff(),q1,0,q2,tmp,tmp2,fail); 570 if(fail) 571 return; 572 xnew += tmp * power(x1.mvar(),i.exp()); 573 i++; 574 } 575 else // i.exp() > j.exp() 576 { 577 tryCRA(0,q1,j.coeff(),q2,tmp,tmp2,fail); 578 if(fail) 579 return; 580 xnew += tmp * power(x1.mvar(),j.exp()); 581 j++; 582 } 583 } 584 } 585 else // j is out of terms 586 { 587 tryCRA(i.coeff(),q1,0,q2,tmp,tmp2,fail); 588 if(fail) 589 return; 590 xnew += tmp * power(x1.mvar(),i.exp()); 591 i++; 592 } 593 } 594 else // i is out of terms 595 { 596 tryCRA(0,q1,j.coeff(),q2,tmp,tmp2,fail); 597 if(fail) 598 return; 599 xnew += tmp * power(x1.mvar(),j.exp()); 600 j++; 601 } 602 } 603 } 604 605 606 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail ) 607 { 608 // F, G are univariate polynomials (i.e. they have exactly one polynomial variable) 609 // F and G must have the same level AND level > 0 610 // we try to calculate gcd(f,g) = s*F + t*G 611 // if a zero divisor is encontered, 'fail' is set to one 612 Variable a, b; 613 if( !hasFirstAlgVar(F,a) && !hasFirstAlgVar(G,b) ) // note lazy evaluation 614 { 615 result = extgcd( F, G, s, t ); // no zero divisors possible 616 return; 617 } 618 if( b.level() > a.level() ) 619 a = b; 620 // here: a is the biggest alg. var in F and G 621 CanonicalForm M = getMipo(a); 622 CanonicalForm P; 623 if( degree(F) > degree(G) ) 624 { 625 P=F; result=G; s=0; t=1; 626 } 627 else 628 { 629 P=G; result=F; s=1; t=0; 630 } 631 CanonicalForm inv, rem, q, u, v; 632 // here: degree(P) >= degree(result) 633 while(true) 634 { 635 tryInvert( Lc(result), M, inv, fail ); 636 if(fail) 637 return; 638 // here: Lc(result) is invertible modulo M 639 q = Lc(P)*inv * power( P.mvar(), degree(P)-degree(result) ); 640 rem = P - q*result; 641 // here: s*F + t*G = result 642 if( rem.isZero() ) 643 { 644 s*=inv; 645 t*=inv; 646 result *= inv; // monify result 647 return; 648 } 649 P=result; 650 result=rem; 651 rem=u-q*s; 652 u=s; 653 s=rem; 654 rem=v-q*t; 655 v=t; 656 t=rem; 657 } 658 } -
factory/algext.h
r863f53 r359d742 5 5 6 6 CanonicalForm QGCD( const CanonicalForm &, const CanonicalForm & ); 7 CanonicalForm univarQGCD( const CanonicalForm & F, const CanonicalForm & G ); 7 8 void tryEuclid( const CanonicalForm &, const CanonicalForm &, const CanonicalForm, CanonicalForm &, bool & ); 8 9 void tryInvert( const CanonicalForm &, const CanonicalForm &, CanonicalForm &, bool & ); 9 10 bool hasFirstAlgVar( const CanonicalForm &, Variable & ); 11 void tryBrownGCD( const CanonicalForm & F, const CanonicalForm & G, const CanonicalForm & M, CanonicalForm & result, bool & fail ); 12 void tryCRA( const CanonicalForm & x1, const CanonicalForm & q1, const CanonicalForm & x2, const CanonicalForm & q2, CanonicalForm & xnew, CanonicalForm & qnew, bool & fail ); 13 void tryExtgcd( const CanonicalForm & F, const CanonicalForm & G, CanonicalForm & result, CanonicalForm & s, CanonicalForm & t, bool & fail ); 14 15 16 -
factory/cf_defs.h
r863f53 r359d742 1 1 /* emacs edit mode for this file is -*- C++ -*- */ 2 /* $Id: cf_defs.h,v 1.1 4 2008-06-16 12:55:08Singular Exp $ */2 /* $Id: cf_defs.h,v 1.15 2008-06-24 12:52:44 Singular Exp $ */ 3 3 4 4 #ifndef INCL_CF_DEFS_H … … 43 43 const int SW_USE_GCD_P=14; 44 44 const int SW_USE_QGCD=15; 45 const int SW_USE_fieldGCD=16; 45 46 //}}} 46 47 -
factory/cf_switches.cc
r863f53 r359d742 1 1 /* emacs edit mode for this file is -*- C++ -*- */ 2 /* $Id: cf_switches.cc,v 1.1 0 2008-06-16 12:54:25Singular Exp $ */2 /* $Id: cf_switches.cc,v 1.11 2008-06-24 12:52:44 Singular Exp $ */ 3 3 4 4 //{{{ docu … … 37 37 On(SW_USE_EZGCD); 38 38 //On(SW_USE_EZGCD_P); // still testing 39 //On(SW_USE_QGCD); 39 On(SW_USE_QGCD); 40 On(SW_USE_fieldGCD); 40 41 } 41 42 //}}} -
factory/cf_switches.h
r863f53 r359d742 1 1 /* emacs edit mode for this file is -*- C++ -*- */ 2 /* $Id: cf_switches.h,v 1.1 3 2008-06-16 12:54:05Singular Exp $ */2 /* $Id: cf_switches.h,v 1.14 2008-06-24 12:52:44 Singular Exp $ */ 3 3 4 4 #ifndef INCL_CF_SWITCHES_H … … 19 19 // 20 20 //}}} 21 const int CFSwitchesMax = 1 6;21 const int CFSwitchesMax = 17; 22 22 //}}} 23 23
Note: See TracChangeset
for help on using the changeset viewer.