Changeset 806c18 in git for factory/cf_gcd_smallp.cc
- Timestamp:
- Nov 15, 2010, 4:34:57 PM (13 years ago)
- Branches:
- (u'spielwiese', '17f1d200f27c5bd38f5dfc6e8a0879242279d1d8')
- Children:
- 7c3bca08c96331a56864c1d35b8c2e8ff2e0be89
- Parents:
- c840d97af622b4e4da8761738b540e21144f716b
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
factory/cf_gcd_smallp.cc
rc840d9 r806c18 6 6 * @date 22.10.2009 7 7 * 8 * This file implements the GCD of two polynomials over \f$ F_{p} \f$ , 9 * \f$ F_{p}(\alpha ) \f$ or GF based on Alg. 7.2. as described in "Algorithms 8 * This file implements the GCD of two polynomials over \f$ F_{p} \f$ , 9 * \f$ F_{p}(\alpha ) \f$ or GF based on Alg. 7.2. as described in "Algorithms 10 10 * for Computer Algebra" by Geddes, Czapor, Labahnn 11 11 * … … 13 13 * (c) by The SINGULAR Team, see LICENSE file 14 14 * 15 * @internal 15 * @internal 16 16 * @version \$Id$ 17 17 * … … 46 46 TIMING_DEFINE_PRINT(newton_interpolation); 47 47 48 /// compressing two polynomials F and G, M is used for compressing, 48 /// compressing two polynomials F and G, M is used for compressing, 49 49 /// N to reverse the compression 50 50 static inline 51 51 int myCompress (const CanonicalForm& F, const CanonicalForm& G, CFMap & M, 52 CFMap & N, bool& topLevel) 53 { 52 CFMap & N, bool& topLevel) 53 { 54 54 int n= tmax (F.level(), G.level()); 55 55 int * degsf= new int [n + 1]; … … 58 58 for (int i = 0; i <= n; i++) 59 59 degsf[i]= degsg[i]= 0; 60 60 61 61 degsf= degrees (F, degsf); 62 62 degsg= degrees (G, degsg); 63 63 64 64 int both_non_zero= 0; 65 65 int f_zero= 0; … … 67 67 int both_zero= 0; 68 68 69 if (topLevel) 70 { 71 for (int i= 1; i <= n; i++) 72 { 73 if (degsf[i] != 0 && degsg[i] != 0) 69 if (topLevel) 70 { 71 for (int i= 1; i <= n; i++) 72 { 73 if (degsf[i] != 0 && degsg[i] != 0) 74 74 { 75 75 both_non_zero++; 76 76 continue; 77 77 } 78 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 78 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 79 79 { 80 80 f_zero++; 81 81 continue; 82 82 } 83 if (degsg[i] == 0 && degsf[i] && i <= F.level()) 83 if (degsg[i] == 0 && degsf[i] && i <= F.level()) 84 84 { 85 85 g_zero++; … … 88 88 } 89 89 90 if (both_non_zero == 0) 90 if (both_non_zero == 0) 91 91 { 92 92 delete [] degsf; … … 98 98 int k= 1; 99 99 int l= 1; 100 for (int i= 1; i <= n; i++) 101 { 102 if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level()) 103 { 104 if (k + both_non_zero != i) 100 for (int i= 1; i <= n; i++) 101 { 102 if (degsf[i] != 0 && degsg[i] == 0 && i <= F.level()) 103 { 104 if (k + both_non_zero != i) 105 105 { 106 106 M.newpair (Variable (i), Variable (k + both_non_zero)); … … 109 109 k++; 110 110 } 111 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 112 { 113 if (l + g_zero + both_non_zero != i) 111 if (degsf[i] == 0 && degsg[i] != 0 && i <= G.level()) 112 { 113 if (l + g_zero + both_non_zero != i) 114 114 { 115 115 M.newpair (Variable (i), Variable (l + g_zero + both_non_zero)); … … 119 119 } 120 120 } 121 121 122 122 // sort Variables x_{i} in increasing order of 123 // min(deg_{x_{i}}(f),deg_{x_{i}}(g)) 123 // min(deg_{x_{i}}(f),deg_{x_{i}}(g)) 124 124 int m= tmin (F.level(), G.level()); 125 125 int max_min_deg; … … 127 127 l= 0; 128 128 int i= 1; 129 while (k > 0) 129 while (k > 0) 130 130 { 131 131 max_min_deg= tmin (degsf[i], degsg[i]); 132 while (max_min_deg == 0) 132 while (max_min_deg == 0) 133 133 { 134 134 i++; 135 135 max_min_deg= tmin (degsf[i], degsg[i]); 136 136 } 137 for (int j= i + 1; j <= m; j++) 138 { 139 if (tmin (degsf[j],degsg[j]) >= max_min_deg) 137 for (int j= i + 1; j <= m; j++) 138 { 139 if (tmin (degsf[j],degsg[j]) >= max_min_deg) 140 140 { 141 141 max_min_deg= tmin (degsf[j], degsg[j]); 142 l= j; 142 l= j; 143 143 } 144 144 } 145 if (l != 0) 146 { 147 if (l != k) 145 if (l != 0) 146 { 147 if (l != k) 148 148 { 149 149 M.newpair (Variable (l), Variable(k)); … … 153 153 l= 0; 154 154 } 155 else 155 else 156 156 { 157 157 degsf[l]= 0; … … 159 159 l= 0; 160 160 } 161 } 162 else if (l == 0) 163 { 164 if (i != k) 161 } 162 else if (l == 0) 163 { 164 if (i != k) 165 165 { 166 166 M.newpair (Variable (i), Variable (k)); … … 169 169 degsg[i]= 0; 170 170 } 171 else 171 else 172 172 { 173 173 degsf[i]= 0; … … 175 175 } 176 176 i++; 177 } 177 } 178 178 k--; 179 179 } 180 180 } 181 else 181 else 182 182 { 183 183 //arrange Variables such that no gaps occur 184 for (int i= 1; i <= n; i++) 185 { 186 if (degsf[i] == 0 && degsg[i] == 0) 184 for (int i= 1; i <= n; i++) 185 { 186 if (degsf[i] == 0 && degsg[i] == 0) 187 187 { 188 188 both_zero++; 189 189 continue; 190 190 } 191 else 192 { 193 if (both_zero != 0) 191 else 192 { 193 if (both_zero != 0) 194 194 { 195 195 M.newpair (Variable (i), Variable (i - both_zero)); … … 207 207 208 208 int 209 substituteCheck (const CanonicalForm& F, const CanonicalForm& G) 209 substituteCheck (const CanonicalForm& F, const CanonicalForm& G) 210 210 { 211 211 if (F.inCoeffDomain() || G.inCoeffDomain()) … … 214 214 if (degree (F, x) <= 1 || degree (G, x) <= 1) 215 215 return 0; 216 CanonicalForm f= swapvar (F, F.mvar(), x); //TODO swapping seems to be pretty expensive 217 CanonicalForm g= swapvar (G, G.mvar(), x); 216 CanonicalForm f= swapvar (F, F.mvar(), x); //TODO swapping seems to be pretty expensive 217 CanonicalForm g= swapvar (G, G.mvar(), x); 218 218 int sizef= 0; 219 int sizeg= 0; 219 int sizeg= 0; 220 220 for (CFIterator i= f; i.hasTerms(); i++, sizef++) 221 221 { … … 240 240 expg [j]= i.exp(); 241 241 } 242 242 243 243 int indf= sizef - 1; 244 244 int indg= sizeg - 1; … … 247 247 if (expg[indg] == 0) 248 248 indg--; 249 249 250 250 if (expg[indg] != expf [indf] || (expg[indg] == 1 && expf[indf] == 1)) 251 251 { … … 265 265 } 266 266 } 267 267 268 268 for (int i= indg - 1; i >= 0; i--) 269 269 { … … 282 282 283 283 // substiution 284 void 285 subst (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& A, 284 void 285 subst (const CanonicalForm& F, const CanonicalForm& G, CanonicalForm& A, 286 286 CanonicalForm& B, const int d 287 287 ) … … 293 293 return; 294 294 } 295 295 296 296 CanonicalForm C= 0; 297 CanonicalForm D= 0; 297 CanonicalForm D= 0; 298 298 Variable x= Variable (1); 299 299 CanonicalForm f= swapvar (F, x, F.mvar()); … … 307 307 } 308 308 309 CanonicalForm 309 CanonicalForm 310 310 reverseSubst (const CanonicalForm& F, const int d) 311 311 { 312 312 if (d == 1) 313 313 return F; 314 314 315 315 Variable x= Variable (1); 316 316 if (degree (F, x) <= 0) … … 320 320 for (CFIterator i= f; i.hasTerms(); i++) 321 321 result += i.coeff()*power (f.mvar(), d*i.exp()); 322 return swapvar (result, x, F.mvar()); 323 } 324 325 static inline CanonicalForm 322 return swapvar (result, x, F.mvar()); 323 } 324 325 static inline CanonicalForm 326 326 uni_content (const CanonicalForm & F); 327 327 … … 335 335 if (F.level() != x.level() && F.isUnivariate()) 336 336 return F.genOne(); 337 337 338 338 if (x.level() != 1) 339 339 { … … 344 344 else 345 345 return uni_content (F); 346 } 347 348 /// compute the content of F, where F is considered as an element of 349 /// \f$ R[x_{1}][x_{2},\ldots ,x_{n}] \f$ 350 static inline CanonicalForm 351 uni_content (const CanonicalForm & F) 352 { 346 } 347 348 /// compute the content of F, where F is considered as an element of 349 /// \f$ R[x_{1}][x_{2},\ldots ,x_{n}] \f$ 350 static inline CanonicalForm 351 uni_content (const CanonicalForm & F) 352 { 353 353 if (F.inBaseDomain()) 354 354 return F.genOne(); … … 360 360 361 361 int l= F.level(); 362 if (l == 2) 362 if (l == 2) 363 363 return content(F); 364 else 364 else 365 365 { 366 366 CanonicalForm pol, c = 0; 367 367 CFIterator i = F; 368 for (; i.hasTerms(); i++) 369 { 370 pol= i.coeff(); 368 for (; i.hasTerms(); i++) 369 { 370 pol= i.coeff(); 371 371 pol= uni_content (pol); 372 372 c= gcd (c, pol); … … 378 378 } 379 379 380 CanonicalForm 381 extractContents (const CanonicalForm& F, const CanonicalForm& G, 382 CanonicalForm& contentF, CanonicalForm& contentG, 380 CanonicalForm 381 extractContents (const CanonicalForm& F, const CanonicalForm& G, 382 CanonicalForm& contentF, CanonicalForm& contentG, 383 383 CanonicalForm& ppF, CanonicalForm& ppG, const int d) 384 384 { … … 407 407 /// is dp. 408 408 static inline 409 CanonicalForm uni_lcoeff (const CanonicalForm& F) 409 CanonicalForm uni_lcoeff (const CanonicalForm& F) 410 410 { 411 411 if (F.level() <= 1) 412 return F; 412 return F; 413 413 else 414 414 { … … 418 418 { 419 419 if (i.exp() + totaldegree (i.coeff(), x, i.coeff().mvar()) == deg) 420 return uni_lcoeff (i.coeff()); 420 return uni_lcoeff (i.coeff()); 421 421 } 422 422 } … … 441 441 } 442 442 443 /// compute a random element a of \f$ F_{p}(\alpha ) \f$ , 443 /// compute a random element a of \f$ F_{p}(\alpha ) \f$ , 444 444 /// s.t. F(a) \f$ \neq 0 \f$ , F is a univariate polynomial, returns 445 /// fail if there are no field elements left which have not been used before 446 static inline CanonicalForm 445 /// fail if there are no field elements left which have not been used before 446 static inline CanonicalForm 447 447 randomElement (const CanonicalForm & F, const Variable & alpha, CFList & list, 448 bool & fail) 448 bool & fail) 449 449 { 450 450 fail= false; … … 457 457 int d= degree (mipo); 458 458 int bound= ipower (p, d); 459 do 459 do 460 460 { 461 461 if (list.length() == bound) … … 464 464 break; 465 465 } 466 if (list.length() < p) 466 if (list.length() < p) 467 467 { 468 468 random= genFF.generate(); … … 470 470 random= genFF.generate(); 471 471 } 472 else 472 else 473 473 { 474 474 random= genAlgExt.generate(); … … 476 476 random= genAlgExt.generate(); 477 477 } 478 if (F (random, x) == 0) 478 if (F (random, x) == 0) 479 479 { 480 480 list.append (random); … … 485 485 } 486 486 487 /// chooses a suitable extension of \f$ F_{p}(\alpha ) \f$ 487 /// chooses a suitable extension of \f$ F_{p}(\alpha ) \f$ 488 488 /// we do not extend \f$ F_{p}(\alpha ) \f$ itself but extend \f$ F_{p} \f$ , 489 /// s.t. \f$ F_{p}(\alpha ) \subset F_{p}(\beta ) \f$ 489 /// s.t. \f$ F_{p}(\alpha ) \subset F_{p}(\beta ) \f$ 490 490 static inline 491 void choose_extension (const int& d, const int& num_vars, Variable& beta) 491 void choose_extension (const int& d, const int& num_vars, Variable& beta) 492 492 { 493 493 int p= getCharacteristic(); … … 496 496 ZZ_pX NTLirredpoly; 497 497 //TODO: replace d by max_{i} (deg_x{i}(f)) 498 int i= (int) (log ((double) ipower (d + 1, num_vars))/log ((double) p)); 498 int i= (int) (log ((double) ipower (d + 1, num_vars))/log ((double) p)); 499 499 int m= degree (getMipo (beta)); 500 500 if (i <= 1) 501 501 i= 2; 502 BuildIrred (NTLirredpoly, i*m); 503 CanonicalForm mipo= convertNTLZZpX2CF (NTLirredpoly, Variable(1)); 504 beta= rootOf (mipo); 505 } 506 507 /// GCD of F and G over \f$ F_{p}(\alpha ) \f$ , 502 BuildIrred (NTLirredpoly, i*m); 503 CanonicalForm mipo= convertNTLZZpX2CF (NTLirredpoly, Variable(1)); 504 beta= rootOf (mipo); 505 } 506 507 /// GCD of F and G over \f$ F_{p}(\alpha ) \f$ , 508 508 /// l and topLevel are only used internally, output is monic 509 509 /// based on Alg. 7.2. as described in "Algorithms for 510 510 /// Computer Algebra" by Geddes, Czapor, Labahn 511 CanonicalForm 512 GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G, 513 Variable & alpha, CFList& l, bool& topLevel) 514 { 511 CanonicalForm 512 GCD_Fp_extension (const CanonicalForm& F, const CanonicalForm& G, 513 Variable & alpha, CFList& l, bool& topLevel) 514 { 515 515 CanonicalForm A= F; 516 516 CanonicalForm B= G; … … 522 522 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 523 523 if (F == G) return F/Lc(F); 524 524 525 525 CFMap M,N; 526 526 int best_level= myCompress (A, B, M, N, topLevel); … … 533 533 Variable x= Variable(1); 534 534 535 //univariate case 536 if (A.isUnivariate() && B.isUnivariate()) 537 return N (gcd(A,B)); 538 535 //univariate case 536 if (A.isUnivariate() && B.isUnivariate()) 537 return N (gcd(A,B)); 538 539 539 int substitute= substituteCheck (A, B); 540 540 541 541 if (substitute > 1) 542 542 subst (A, B, A, B, substitute); … … 550 550 if (best_level <= 2) 551 551 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level); 552 else 553 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 552 else 553 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 554 554 } 555 555 else 556 556 { 557 557 cA = uni_content (A); 558 cB = uni_content (B); 558 cB = uni_content (B); 559 559 gcdcAcB= gcd (cA, cB); 560 560 ppA= A/cA; … … 563 563 564 564 CanonicalForm lcA, lcB; // leading coefficients of A and B 565 CanonicalForm gcdlcAlcB; 565 CanonicalForm gcdlcAlcB; 566 566 567 567 lcA= uni_lcoeff (ppA); 568 568 lcB= uni_lcoeff (ppB); 569 570 if (fdivides (lcA, lcB)) 571 { 569 570 if (fdivides (lcA, lcB)) 571 { 572 572 if (fdivides (A, B)) 573 return F/Lc(F); 573 return F/Lc(F); 574 574 } 575 575 if (fdivides (lcB, lcA)) 576 { 577 if (fdivides (B, A)) 576 { 577 if (fdivides (B, A)) 578 578 return G/Lc(G); 579 579 } … … 587 587 if (substitute > 1) 588 588 return N (reverseSubst (gcdcAcB, substitute)); 589 else 589 else 590 590 return N(gcdcAcB); 591 591 } 592 592 int d0= totaldegree (ppB, Variable(2), Variable (ppB.level())); 593 if (d0 < d) 594 d= d0; 593 if (d0 < d) 594 d= d0; 595 595 if (d == 0) 596 596 { 597 597 if (substitute > 1) 598 598 return N (reverseSubst (gcdcAcB, substitute)); 599 else 599 else 600 600 return N(gcdcAcB); 601 601 } … … 614 614 CanonicalForm prim_elem, im_prim_elem; 615 615 CFList source, dest; 616 do 616 do 617 617 { 618 618 random_element= randomElement (m, V_buf, l, fail); 619 if (fail) 619 if (fail) 620 620 { 621 621 source= CFList(); … … 638 638 DEBOUTLN (cerr, "getMipo (V_buf2)= " << getMipo (V_buf2)); 639 639 inextension= true; 640 for (CFListIterator i= l; i.hasItem(); i++) 641 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 640 for (CFListIterator i= l; i.hasItem(); i++) 641 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 642 642 im_prim_elem, source, dest); 643 643 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 644 644 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 645 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 645 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 646 646 source, dest); 647 647 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 648 648 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 649 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 649 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 650 650 source, dest); 651 651 … … 655 655 CFList list; 656 656 TIMING_START (gcd_recursion); 657 G_random_element= 657 G_random_element= 658 658 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf, 659 659 list, topLevel); 660 TIMING_END_AND_PRINT (gcd_recursion, 660 TIMING_END_AND_PRINT (gcd_recursion, 661 661 "time for recursive call: "); 662 662 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 663 663 } 664 else 664 else 665 665 { 666 666 CFList list; 667 667 TIMING_START (gcd_recursion); 668 G_random_element= 668 G_random_element= 669 669 GCD_Fp_extension (ppA(random_element, x), ppB(random_element, x), V_buf, 670 670 list, topLevel); 671 TIMING_END_AND_PRINT (gcd_recursion, 671 TIMING_END_AND_PRINT (gcd_recursion, 672 672 "time for recursive call: "); 673 673 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 674 674 } 675 675 676 d0= totaldegree (G_random_element, Variable(2), 676 d0= totaldegree (G_random_element, Variable(2), 677 677 Variable (G_random_element.level())); 678 678 if (d0 == 0) … … 680 680 if (substitute > 1) 681 681 return N (reverseSubst (gcdcAcB, substitute)); 682 else 682 else 683 683 return N(gcdcAcB); 684 684 } 685 if (d0 > d) 685 if (d0 > d) 686 686 { 687 687 if (!find (l, random_element)) … … 690 690 } 691 691 692 G_random_element= 692 G_random_element= 693 693 (gcdlcAlcB(random_element, x)/uni_lcoeff (G_random_element)) 694 694 * G_random_element; 695 695 696 d0= totaldegree (G_random_element, Variable(2), 696 d0= totaldegree (G_random_element, Variable(2), 697 697 Variable(G_random_element.level())); 698 if (d0 < d) 698 if (d0 < d) 699 699 { 700 700 m= gcdlcAlcB; … … 706 706 TIMING_START (newton_interpolation); 707 707 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 708 TIMING_END_AND_PRINT (newton_interpolation, 708 TIMING_END_AND_PRINT (newton_interpolation, 709 709 "time for newton interpolation: "); 710 710 711 //termination test 712 if (uni_lcoeff (H) == gcdlcAlcB) 711 //termination test 712 if (uni_lcoeff (H) == gcdlcAlcB) 713 713 { 714 714 cH= uni_content (H); 715 715 ppH= H/cH; 716 if (inextension) 717 { 718 CFList u, v; 716 if (inextension) 717 { 718 CFList u, v; 719 719 //maybe it's better to test if ppH is an element of F(\alpha) before 720 720 //mapping down 721 721 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); 722 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 722 ppH= mapDown (ppH, prim_elem, im_prim_elem, alpha, u, v); 723 723 ppH /= Lc(ppH); 724 724 DEBOUTLN (cerr, "ppH after mapDown= " << ppH); 725 if (fdivides (ppH, A) && fdivides (ppH, B)) 725 if (fdivides (ppH, A) && fdivides (ppH, B)) 726 726 { 727 727 if (substitute > 1) … … 733 733 } 734 734 } 735 else if (fdivides (ppH, A) && fdivides (ppH, B)) 735 else if (fdivides (ppH, A) && fdivides (ppH, B)) 736 736 { 737 737 if (substitute > 1) … … 752 752 } 753 753 754 /// compute a random element a of GF, s.t. F(a) \f$ \neq 0 \f$ , F is a 754 /// compute a random element a of GF, s.t. F(a) \f$ \neq 0 \f$ , F is a 755 755 /// univariate polynomial, returns fail if there are no field elements left 756 756 /// which have not been used before … … 766 766 int d= getGFDegree(); 767 767 int bound= ipower (p, d); 768 do 768 do 769 769 { 770 770 if (list.length() == bound) … … 775 775 if (list.length() < 1) 776 776 random= 0; 777 else 777 else 778 778 { 779 779 random= genGF.generate(); … … 781 781 random= genGF.generate(); 782 782 } 783 if (F (random, x) == 0) 783 if (F (random, x) == 0) 784 784 { 785 785 list.append (random); … … 796 796 /// the size of the base field is bounded by 2^16, output is monic 797 797 CanonicalForm GCD_GF (const CanonicalForm& F, const CanonicalForm& G, 798 CFList& l, bool& topLevel) 799 { 798 CFList& l, bool& topLevel) 799 { 800 800 CanonicalForm A= F; 801 801 CanonicalForm B= G; … … 807 807 if (G.isUnivariate() && fdivides(G, F)) return G/Lc(G); 808 808 if (F == G) return F/Lc(F); 809 809 810 810 CFMap M,N; 811 811 int best_level= myCompress (A, B, M, N, topLevel); … … 818 818 Variable x= Variable(1); 819 819 820 //univariate case 821 if (A.isUnivariate() && B.isUnivariate()) 822 return N (gcd (A, B)); 820 //univariate case 821 if (A.isUnivariate() && B.isUnivariate()) 822 return N (gcd (A, B)); 823 823 824 824 int substitute= substituteCheck (A, B); 825 825 826 826 if (substitute > 1) 827 827 subst (A, B, A, B, substitute); … … 835 835 if (best_level <= 2) 836 836 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level); 837 else 838 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 837 else 838 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 839 839 } 840 840 else 841 841 { 842 842 cA = uni_content (A); 843 cB = uni_content (B); 843 cB = uni_content (B); 844 844 gcdcAcB= gcd (cA, cB); 845 845 ppA= A/cA; … … 848 848 849 849 CanonicalForm lcA, lcB; // leading coefficients of A and B 850 CanonicalForm gcdlcAlcB; 850 CanonicalForm gcdlcAlcB; 851 851 852 852 lcA= uni_lcoeff (ppA); 853 853 lcB= uni_lcoeff (ppB); 854 854 855 if (fdivides (lcA, lcB)) 856 { 855 if (fdivides (lcA, lcB)) 856 { 857 857 if (fdivides (A, B)) 858 return F; 859 } 860 if (fdivides (lcB, lcA)) 861 { 862 if (fdivides (B, A)) 858 return F; 859 } 860 if (fdivides (lcB, lcA)) 861 { 862 if (fdivides (B, A)) 863 863 return G; 864 864 } … … 871 871 if (substitute > 1) 872 872 return N (reverseSubst (gcdcAcB, substitute)); 873 else 873 else 874 874 return N(gcdcAcB); 875 875 } 876 876 int d0= totaldegree (ppB, Variable(2), Variable (ppB.level())); 877 if (d0 < d) 878 d= d0; 877 if (d0 < d) 878 d= d0; 879 879 if (d == 0) 880 880 { 881 881 if (substitute > 1) 882 882 return N (reverseSubst (gcdcAcB, substitute)); 883 else 883 else 884 884 return N(gcdcAcB); 885 885 } … … 900 900 int expon; 901 901 char gf_name_buf= gf_name; 902 do 902 do 903 903 { 904 904 random_element= GFRandomElement (m, l, fail); 905 if (fail) 906 { 905 if (fail) 906 { 907 907 int num_vars= tmin (getNumVars(A), getNumVars(B)); 908 908 num_vars--; … … 911 911 if (expon < 2) 912 912 expon= 2; 913 kk= getGFDegree(); 914 if (ipower (p, kk*expon) < (1 << 16)) 913 kk= getGFDegree(); 914 if (ipower (p, kk*expon) < (1 << 16)) 915 915 setCharacteristic (p, kk*(int)expon, 'b'); 916 else 916 else 917 917 { 918 918 expon= (int) floor((log ((double)((1<<16) - 1)))/(log((double)p)*kk)); … … 922 922 inextension= true; 923 923 fail= false; 924 for (CFListIterator i= l; i.hasItem(); i++) 924 for (CFListIterator i= l; i.hasItem(); i++) 925 925 i.getItem()= GFMapUp (i.getItem(), kk); 926 926 m= GFMapUp (m, kk); … … 934 934 CFList list; 935 935 TIMING_START (gcd_recursion); 936 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 936 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 937 937 list, topLevel); 938 TIMING_END_AND_PRINT (gcd_recursion, 938 TIMING_END_AND_PRINT (gcd_recursion, 939 939 "time for recursive call: "); 940 940 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 941 941 } 942 else 942 else 943 943 { 944 944 CFList list; 945 945 TIMING_START (gcd_recursion); 946 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 946 G_random_element= GCD_GF (ppA(random_element, x), ppB(random_element, x), 947 947 list, topLevel); 948 TIMING_END_AND_PRINT (gcd_recursion, 948 TIMING_END_AND_PRINT (gcd_recursion, 949 949 "time for recursive call: "); 950 950 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 951 951 } 952 952 953 d0= totaldegree (G_random_element, Variable(2), 953 d0= totaldegree (G_random_element, Variable(2), 954 954 Variable (G_random_element.level())); 955 if (d0 == 0) 956 { 957 if (inextension) 955 if (d0 == 0) 956 { 957 if (inextension) 958 958 { 959 959 setCharacteristic (p, k, gf_name_buf); … … 962 962 return N (reverseSubst (gcdcAcB, substitute)); 963 963 else 964 return N(gcdcAcB); 965 } 964 return N(gcdcAcB); 965 } 966 966 } 967 967 else … … 970 970 return N (reverseSubst (gcdcAcB, substitute)); 971 971 else 972 return N(gcdcAcB); 973 } 974 } 975 if (d0 > d) 972 return N(gcdcAcB); 973 } 974 } 975 if (d0 > d) 976 976 { 977 977 if (!find (l, random_element)) … … 980 980 } 981 981 982 G_random_element= 982 G_random_element= 983 983 (gcdlcAlcB(random_element, x)/uni_lcoeff(G_random_element)) * 984 984 G_random_element; 985 d0= totaldegree (G_random_element, Variable(2), 985 d0= totaldegree (G_random_element, Variable(2), 986 986 Variable (G_random_element.level())); 987 987 988 if (d0 < d) 988 if (d0 < d) 989 989 { 990 990 m= gcdlcAlcB; … … 998 998 TIMING_END_AND_PRINT (newton_interpolation, "time for newton interpolation: "); 999 999 1000 //termination test 1001 if (uni_lcoeff (H) == gcdlcAlcB) 1000 //termination test 1001 if (uni_lcoeff (H) == gcdlcAlcB) 1002 1002 { 1003 1003 cH= uni_content (H); 1004 1004 ppH= H/cH; 1005 if (inextension) 1006 { 1007 if (fdivides(ppH, GFMapUp(A, k)) && fdivides(ppH, GFMapUp(B,k))) 1005 if (inextension) 1006 { 1007 if (fdivides(ppH, GFMapUp(A, k)) && fdivides(ppH, GFMapUp(B,k))) 1008 1008 { 1009 1009 DEBOUTLN (cerr, "ppH before mapDown= " << ppH); … … 1019 1019 } 1020 1020 } 1021 else 1022 { 1023 if (fdivides (ppH, A) && fdivides (ppH, B)) 1021 else 1022 { 1023 if (fdivides (ppH, A) && fdivides (ppH, B)) 1024 1024 { 1025 1025 if (substitute > 1) … … 1042 1042 1043 1043 /// F is assumed to be an univariate polynomial in x, 1044 /// computes a random monic irreducible univariate polynomial of random 1044 /// computes a random monic irreducible univariate polynomial of random 1045 1045 /// degree < i in x which does not divide F 1046 CanonicalForm 1047 randomIrredpoly (int i, const Variable & x) 1046 CanonicalForm 1047 randomIrredpoly (int i, const Variable & x) 1048 1048 { 1049 1049 int p= getCharacteristic(); 1050 1050 ZZ NTLp= to_ZZ (p); 1051 1051 ZZ_p::init (NTLp); 1052 ZZ_pX NTLirredpoly; 1052 ZZ_pX NTLirredpoly; 1053 1053 CanonicalForm CFirredpoly; 1054 1054 BuildIrred (NTLirredpoly, i + 1); 1055 1055 CFirredpoly= convertNTLZZpX2CF (NTLirredpoly, x); 1056 1056 return CFirredpoly; 1057 } 1057 } 1058 1058 1059 1059 static inline … … 1067 1067 int p= getCharacteristic(); 1068 1068 int bound= p; 1069 do 1069 do 1070 1070 { 1071 1071 if (list.length() == bound) … … 1076 1076 if (list.length() < 1) 1077 1077 random= 0; 1078 else 1078 else 1079 1079 { 1080 1080 random= genFF.generate(); … … 1082 1082 random= genFF.generate(); 1083 1083 } 1084 if (F (random, x) == 0) 1084 if (F (random, x) == 0) 1085 1085 { 1086 1086 list.append (random); … … 1091 1091 } 1092 1092 1093 CanonicalForm GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1094 bool& topLevel, CFList& l) 1093 CanonicalForm GCD_small_p (const CanonicalForm& F, const CanonicalForm& G, 1094 bool& topLevel, CFList& l) 1095 1095 { 1096 1096 CanonicalForm A= F; … … 1114 1114 Variable x= Variable (1); 1115 1115 1116 //univariate case 1117 if (A.isUnivariate() && B.isUnivariate()) 1116 //univariate case 1117 if (A.isUnivariate() && B.isUnivariate()) 1118 1118 return N (gcd (A, B)); 1119 1119 1120 1120 int substitute= substituteCheck (A, B); 1121 1121 1122 1122 if (substitute > 1) 1123 1123 subst (A, B, A, B, substitute); … … 1131 1131 if (best_level <= 2) 1132 1132 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, best_level); 1133 else 1134 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 1133 else 1134 gcdcAcB= extractContents (A, B, cA, cB, ppA, ppB, 2); 1135 1135 } 1136 1136 else 1137 1137 { 1138 1138 cA = uni_content (A); 1139 cB = uni_content (B); 1139 cB = uni_content (B); 1140 1140 gcdcAcB= gcd (cA, cB); 1141 1141 ppA= A/cA; … … 1144 1144 1145 1145 CanonicalForm lcA, lcB; // leading coefficients of A and B 1146 CanonicalForm gcdlcAlcB; 1146 CanonicalForm gcdlcAlcB; 1147 1147 lcA= uni_lcoeff (ppA); 1148 1148 lcB= uni_lcoeff (ppB); 1149 1149 1150 if (fdivides (lcA, lcB)) 1151 { 1150 if (fdivides (lcA, lcB)) 1151 { 1152 1152 if (fdivides (A, B)) 1153 1153 return F/Lc(F); 1154 } 1154 } 1155 1155 if (fdivides (lcB, lcA)) 1156 { 1157 if (fdivides (B, A)) 1156 { 1157 if (fdivides (B, A)) 1158 1158 return G/Lc(G); 1159 1159 } 1160 1160 1161 gcdlcAlcB= gcd (lcA, lcB); 1162 1161 gcdlcAlcB= gcd (lcA, lcB); 1162 1163 1163 int d= totaldegree (ppA, Variable (2), Variable (ppA.level())); 1164 1164 int d0; … … 1168 1168 if (substitute > 1) 1169 1169 return N (reverseSubst (gcdcAcB, substitute)); 1170 else 1170 else 1171 1171 return N(gcdcAcB); 1172 1172 } 1173 1173 d0= totaldegree (ppB, Variable (2), Variable (ppB.level())); 1174 1174 1175 if (d0 < d) 1175 if (d0 < d) 1176 1176 d= d0; 1177 1177 1178 if (d == 0) 1178 if (d == 0) 1179 1179 { 1180 1180 if (substitute > 1) 1181 1181 return N (reverseSubst (gcdcAcB, substitute)); 1182 else 1182 else 1183 1183 return N(gcdcAcB); 1184 1184 } … … 1195 1195 topLevel= false; 1196 1196 CFList source, dest; 1197 do 1197 do 1198 1198 { 1199 1199 if (inextension) … … 1206 1206 CFList list; 1207 1207 TIMING_START (gcd_recursion); 1208 G_random_element= 1209 GCD_small_p (ppA (random_element,x), ppB (random_element,x), topLevel, 1208 G_random_element= 1209 GCD_small_p (ppA (random_element,x), ppB (random_element,x), topLevel, 1210 1210 list); 1211 TIMING_END_AND_PRINT (gcd_recursion, 1211 TIMING_END_AND_PRINT (gcd_recursion, 1212 1212 "time for recursive call: "); 1213 1213 DEBOUTLN (cerr, "G_random_element= " << G_random_element); … … 1215 1215 else if (!fail && inextension) 1216 1216 { 1217 CFList list; 1217 CFList list; 1218 1218 TIMING_START (gcd_recursion); 1219 G_random_element= 1220 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1219 G_random_element= 1220 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1221 1221 list, topLevel); 1222 TIMING_END_AND_PRINT (gcd_recursion, 1222 TIMING_END_AND_PRINT (gcd_recursion, 1223 1223 "time for recursive call: "); 1224 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 1224 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 1225 1225 } 1226 1226 else if (fail && !inextension) … … 1232 1232 int deg= 2; 1233 1233 do { 1234 mipo= randomIrredpoly (deg, x); 1234 mipo= randomIrredpoly (deg, x); 1235 1235 alpha= rootOf (mipo); 1236 1236 inextension= true; 1237 1237 fail= false; 1238 random_element= randomElement (m, alpha, l, fail); 1238 random_element= randomElement (m, alpha, l, fail); 1239 1239 deg++; 1240 } while (fail); 1240 } while (fail); 1241 1241 list= CFList(); 1242 1242 TIMING_START (gcd_recursion); 1243 G_random_element= 1244 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1243 G_random_element= 1244 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), alpha, 1245 1245 list, topLevel); 1246 TIMING_END_AND_PRINT (gcd_recursion, 1246 TIMING_END_AND_PRINT (gcd_recursion, 1247 1247 "time for recursive call: "); 1248 1248 DEBOUTLN (cerr, "G_random_element= " << G_random_element); … … 1260 1260 CanonicalForm prim_elem, im_prim_elem; 1261 1261 prim_elem= primitiveElement (alpha, V_buf2, prim_fail); 1262 1262 1263 1263 ASSERT (!prim_fail, "failure in integer factorizer"); 1264 1264 if (prim_fail) … … 1271 1271 1272 1272 inextensionextension= true; 1273 for (CFListIterator i= l; i.hasItem(); i++) 1274 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 1273 for (CFListIterator i= l; i.hasItem(); i++) 1274 i.getItem()= mapUp (i.getItem(), alpha, V_buf, prim_elem, 1275 1275 im_prim_elem, source, dest); 1276 1276 m= mapUp (m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1277 1277 G_m= mapUp (G_m, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1278 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 1278 newtonPoly= mapUp (newtonPoly, alpha, V_buf, prim_elem, im_prim_elem, 1279 1279 source, dest); 1280 1280 ppA= mapUp (ppA, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1281 1281 ppB= mapUp (ppB, alpha, V_buf, prim_elem, im_prim_elem, source, dest); 1282 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 1282 gcdlcAlcB= mapUp (gcdlcAlcB, alpha, V_buf, prim_elem, im_prim_elem, 1283 1283 source, dest); 1284 1284 fail= false; … … 1287 1287 CFList list; 1288 1288 TIMING_START (gcd_recursion); 1289 G_random_element= 1289 G_random_element= 1290 1290 GCD_Fp_extension (ppA (random_element, x), ppB (random_element, x), V_buf, 1291 1291 list, topLevel); 1292 TIMING_END_AND_PRINT (gcd_recursion, 1292 TIMING_END_AND_PRINT (gcd_recursion, 1293 1293 "time for recursive call: "); 1294 1294 DEBOUTLN (cerr, "G_random_element= " << G_random_element); 1295 1295 alpha= V_buf; 1296 } 1297 1298 d0= totaldegree (G_random_element, Variable(2), 1296 } 1297 1298 d0= totaldegree (G_random_element, Variable(2), 1299 1299 Variable (G_random_element.level())); 1300 1300 … … 1304 1304 return N (reverseSubst (gcdcAcB, substitute)); 1305 1305 else 1306 return N(gcdcAcB); 1307 } 1308 if (d0 > d) 1309 { 1306 return N(gcdcAcB); 1307 } 1308 if (d0 > d) 1309 { 1310 1310 if (!find (l, random_element)) 1311 1311 l.append (random_element); … … 1314 1314 1315 1315 G_random_element= (gcdlcAlcB(random_element,x)/uni_lcoeff(G_random_element)) 1316 *G_random_element; 1317 1318 1319 d0= totaldegree (G_random_element, Variable(2), 1316 *G_random_element; 1317 1318 1319 d0= totaldegree (G_random_element, Variable(2), 1320 1320 Variable(G_random_element.level())); 1321 1321 1322 if (d0 < d) 1322 if (d0 < d) 1323 1323 { 1324 1324 m= gcdlcAlcB; … … 1327 1327 d= d0; 1328 1328 } 1329 1329 1330 1330 TIMING_START (newton_interpolation); 1331 1331 H= newtonInterp (random_element, G_random_element, newtonPoly, G_m, x); 1332 TIMING_END_AND_PRINT (newton_interpolation, 1332 TIMING_END_AND_PRINT (newton_interpolation, 1333 1333 "time for newton_interpolation: "); 1334 1334 1335 1335 //termination test 1336 if (uni_lcoeff (H) == gcdlcAlcB) 1336 if (uni_lcoeff (H) == gcdlcAlcB) 1337 1337 { 1338 1338 cH= uni_content (H); … … 1340 1340 ppH /= Lc (ppH); 1341 1341 DEBOUTLN (cerr, "ppH= " << ppH); 1342 if (fdivides (ppH, A) && fdivides (ppH, B)) 1342 if (fdivides (ppH, A) && fdivides (ppH, B)) 1343 1343 { 1344 1344 if (substitute > 1)
Note: See TracChangeset
for help on using the changeset viewer.