Changeset 50cbdc in git for Singular/walk.cc
- Timestamp:
- Aug 27, 2001, 4:48:02 PM (23 years ago)
- Branches:
- (u'spielwiese', 'fe61d9c35bf7c61f2b6cbf1b56e25e2f08d536cc')
- Children:
- 2567b5a6cb7109be5a83e53eb94abb1c38fb9945
- Parents:
- 3de58c9ca0aeaafdf5cb29f986967bffa405b542
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/walk.cc
r3de58c r50cbdc 2 2 * Computer Algebra System SINGULAR * 3 3 *****************************************/ 4 /* $Id: walk.cc,v 1. 4 2000-09-07 13:39:45 sulandraExp $ */4 /* $Id: walk.cc,v 1.5 2001-08-27 14:47:45 Singular Exp $ */ 5 5 /* 6 6 * ABSTRACT: Implementation of the Groebner walk 7 7 */ 8 8 9 /* includes */ 9 10 #include "mod2.h" 10 11 #include "walk.h" … … 13 14 #include "intvec.h" 14 15 #include "ipid.h" 15 16 // add two intvecs: 17 intvec* walkAddIntVec(intvec* v1, intvec* v2) 18 { 19 int n = v1->length(); 16 #include "tok.h" 17 #include <omalloc.h> 18 #include "febase.h" 19 #include "numbers.h" 20 #include "ipid.h" 21 #include "ring.h" 22 #include "kstd1.h" 23 #include "matpol.h" 24 #include "weight.h" 25 #include "intvec.h" 26 #include "syz.h" 27 #include "lists.h" 28 #include "prCopy.h" 29 #include <string.h> 30 #include "structs.h" 31 #include "longalg.h" 32 #ifdef HAVE_FACTORY 33 #include "clapsing.h" 34 #endif 35 36 static void* idString(ideal L) 37 { 20 38 int i; 21 intvec *result = new intvec(n); 22 if (v2->length() > n) n = v2->length(); 23 24 for (i=0; i<n; i++) 25 { 26 (*result)[i] = (*v1)[i] + (*v2)[i]; 27 } 28 29 return result; 30 } 31 32 33 34 35 // scalar product of weights and exponent vector of p 36 // assumes that weights and exponent vector have length n 37 inline long walkWeightDegree(const poly p, const int* weights, 38 const long n) 39 { 40 assume(p != NULL && weights != NULL); 41 42 long i, res = 0; 43 44 for (i=0; i<n; i++) res += pGetExp(p, i+1) * weights[i]; 45 46 return res; 39 printf("//ideal Itmp: "); 40 for(i=0; i<IDELEMS(L); i++) 41 printf(" %s, ", pString(L->m[i])); 42 printf("\n"); 47 43 } 48 44 49 45 50 46 // returns gcd of integers a and b 51 inline long gcd(const long a, const long b)47 static inline long gcd(const long a, const long b) 52 48 { 53 49 long r, p0 = a, p1 = b; 54 assume(p0 >= 0 && p1 >= 0); 55 50 //assume(p0 >= 0 && p1 >= 0); 51 if(p0 < 0) 52 p0 = -p0; 53 54 if(p1 < 0) 55 p1 = -p1; 56 56 while(p1 != 0) 57 57 { … … 64 64 65 65 // cancel gcd of integers zaehler and nenner 66 inline void cancel(long &zaehler, long &nenner)66 static inline void cancel(long &zaehler, long &nenner) 67 67 { 68 68 assume(zaehler >= 0 && nenner > 0); … … 75 75 } 76 76 77 // Returns the next Weight vector for the Groebner walk 78 // Assumes monoms of polys of G are ordered decreasingly w.r.t. curr_weight 79 int* walkNextWeight(const int* curr_weight, 80 const int* target_weight, 81 const ideal G) 82 { 83 assume(currRing != NULL && target_weight != NULL && curr_weight != NULL && 84 G != NULL); 85 86 int* diff_weight = 87 (int*)omAlloc(currRing->N*sizeof(int)); 88 long j, t_zaehler = 0, t_nenner = 0; 89 90 for (j=0; j<currRing->N; j++) 91 diff_weight[j] = target_weight[j] - curr_weight[j]; 92 93 for (j=0; j<IDELEMS(G); j++) 94 { 95 poly g = G->m[j]; 96 if (g != 0) 97 { 98 long deg_w0_p1 = pGetOrder(g); 99 long deg_d0_p1 = walkWeightDegree(g, diff_weight, currRing->N); 100 77 /******************************************************************** 78 * compute a weight degree of a monomial p w.r.t. a weight_vector * 79 ********************************************************************/ 80 static inline int MLmWeightedDegree(const poly p, intvec* weight) 81 { 82 int i, d = 0; 83 84 for (i=1; i<=pVariables; i++) 85 d += pGetExp(p, i) * (*weight)[i-1]; 86 87 return d; 88 } 89 90 /******************************************************************** 91 * compute a weight degree of a polynomial p w.r.t. a weight_vector * 92 ********************************************************************/ 93 static inline int MwalkWeightDegree(poly p, intvec* weight_vector) 94 { 95 assume(weight_vector->length() >= pVariables); 96 int max = 0, maxtemp; 97 poly hp; 98 99 while(p != NULL) 100 { 101 hp = pHead(p); 102 pIter(p); 103 maxtemp = MLmWeightedDegree(hp, weight_vector); 104 105 if (maxtemp > max) 106 max = maxtemp; 107 } 108 return max; 109 } 110 111 /***************************************************************************** 112 * return an initial form of the polynom g w.r.t. a weight vector curr_weight * 113 *****************************************************************************/ 114 static poly MpolyInitialForm(poly g, intvec* curr_weight) 115 { 116 if(g == NULL) 117 return g; 118 119 int maxtmp, max = 0; 120 poly in_w_g = NULL, hg; 121 122 while(g != NULL) 123 { 124 hg = pHead(g); 125 pIter(g); 126 maxtmp = MwalkWeightDegree(hg, curr_weight); 127 128 if(maxtmp > max) 129 { 130 max = maxtmp; 131 in_w_g = hg; 132 } else { 133 if(maxtmp == max) 134 in_w_g = pAdd(in_w_g, hg); 135 } 136 } 137 return in_w_g; 138 } 139 140 141 /***************************************************************************** 142 * compute the initial form of an ideal "G" w.r.t. weight vector curr_weight * 143 ****************************************************************************/ 144 ideal MwalkInitialForm(ideal G, intvec* curr_weight) 145 { 146 int i; 147 int nG = IDELEMS(G); 148 ideal Gomega = idInit(nG, G->rank); 149 150 for(i=0; i<nG; i++) 151 Gomega->m[i] = MpolyInitialForm(G->m[i], curr_weight); 152 153 //return Gomega; 154 ideal result = idCopy(Gomega); 155 idDelete(&Gomega); 156 return result; 157 } 158 159 /************************************************************************ 160 * test that does the weight vector iv exist in the cone of the ideal G * 161 * i.e. does in(in_w(g)) =? in(g), for all g in G * 162 ************************************************************************/ 163 void* test_w_in_Cone(ideal G, intvec* iv) 164 { 165 int nG = IDELEMS(G); 166 int i; 167 BOOLEAN ok = TRUE; 168 poly mi, in_mi, gi; 169 for(i=0; i<nG; i++) 170 { 171 mi = MpolyInitialForm(G->m[i], iv); 172 in_mi = pHead(mi); 173 gi = pHead(G->m[i]); 174 if(pEqualPolys(in_mi, gi) != ok) 175 { 176 printf("//ring Test_W_in_Cone = %s ;\n", rString(currRing)); 177 printf("//the computed next weight vector doesn't exist in the cone\n"); 178 break; 179 } 180 } 181 } 182 183 //compute a least common multiple of two integers 184 static inline long Mlcm(long &i1, long &i2) 185 { 186 long temp = gcd(i1, i2); 187 return ((i1*i2) / temp); 188 } 189 190 191 /*************************************************** 192 * return the dot product of two intvecs a and b * 193 ***************************************************/ 194 static inline long MivDotProduct(intvec* a, intvec* b) 195 { 196 assume( a->length() == b->length()); 197 int i, n = a->length(); 198 long result = 0; 199 200 for(i=0; i<n; i++) 201 result += (*a)[i] * (*b)[i]; 202 203 return result; 204 } 205 206 207 /**21.10.00******************************************* 208 * return the "intvec" lead exponent of a polynomial * 209 *****************************************************/ 210 static intvec* MExpPol(poly f) 211 { 212 int nR = currRing->N; 213 214 intvec* result = new intvec(nR); 215 int i; 216 217 for(i=0; i<nR; i++) 218 (*result)[i] = pGetExp(f,i+1); 219 220 intvec *res = ivCopy(result); 221 omFree((ADDRESS) result); 222 return res; 223 } 224 225 226 /***23-24.10.00****************************************** 227 * compute a division of two monoms, "a" by a monom "b" * 228 * i.e. leading term of two polynoms a and b * 229 ********************************************************/ 230 static poly MpDiv(poly a, poly b) 231 { 232 assume (b != NULL); 233 BOOLEAN ok = TRUE; 234 235 if(a == NULL) 236 return a; 237 238 int nR = currRing->N; 239 240 number nn = (number) omAllocBin(rnumber_bin); 241 242 poly ptmp, ppotenz; 243 poly result = pISet(1); 244 245 intvec* iva = MExpPol(a); //head exponent of a 246 intvec* ivb = MExpPol(b); //head exponent of a 247 248 int nab; 249 for(int i=0; i<nR; i++) 250 { 251 nab = (*iva)[i] - (*ivb)[i]; 252 // b does not divide a 253 if(nab < 0) 254 { 255 result = NULL; 256 return result; 257 } 258 //define a polynomial which is a variable of the basering 259 ptmp = (poly) pmInit(currRing->names[i], ok); //p:=xi 260 ppotenz = pPower(ptmp, nab); 261 result = pMult(result, ppotenz); 262 } 263 nn = nDiv(pGetCoeff(a), pGetCoeff(b)); 264 result = pMult_nn(result, nn); 265 nDelete(&nn); 266 267 return result; 268 } 269 270 271 /***24.10.00 ***************************************** 272 * compute a product of two monoms a and b * 273 * i.e. leading term of two polynoms a and b * 274 *****************************************************/ 275 static poly MpMult(poly a, poly b) 276 { 277 if(a == NULL || b == NULL) 278 return a; 279 280 int nR = currRing->N; 281 BOOLEAN ok = TRUE; 282 283 poly ptmp, ppotenz; 284 poly result = pISet(1); // result := 1 285 intvec* ivab = ivAdd(MExpPol(a), MExpPol(b)); 286 287 for(int i=0; i<nR; i++) 288 { 289 //define a polynomial which is a variable of the basering 290 ptmp = pmInit(currRing->names[i], ok); 291 ppotenz = pPower(ptmp, (*ivab)[i]); 292 result = pMult(result, ppotenz); 293 } 294 number nn = nMult(pGetCoeff(a), pGetCoeff(b)); 295 result = pMult_nn(result, nn); 296 297 return result; 298 } 299 300 301 poly MivSame(intvec* u , intvec* v) 302 { 303 assume(u->length() == v->length()); 304 305 int i, niv = u->length(); 306 307 for (i=0; i<niv; i++) 308 if ((*u)[i] != (*v)[i]) 309 return pISet(1); 310 311 return (poly) NULL; 312 } 313 314 poly M3ivSame(intvec* temp, intvec* u , intvec* v) 315 { 316 assume(temp->length() == u->length() && u->length() == v->length()); 317 318 if(MivSame(temp, u) == NULL) 319 return (poly) NULL; 320 if(MivSame(temp, v) == NULL) 321 return pISet(1); 322 return pISet(2); 323 } 324 325 326 /************************ 327 * Define a monom x^iv * 328 ************************/ 329 poly MPolVar(intvec* iv) 330 { 331 int i, niv = pVariables; 332 333 poly ptemp = pOne(); 334 poly pvar, ppotenz; 335 BOOLEAN ok = TRUE; 336 337 for(i=0; i<niv; i++) 338 { 339 pvar = (poly) pmInit(currRing->names[i], ok); //p:=x_i 340 ppotenz = pPower(pvar, (*iv)[i]); 341 ptemp = pMult(ptemp, ppotenz); 342 } 343 return ptemp; 344 } 345 346 347 /* compute a Groebner basis of an ideal */ 348 ideal Mstd(ideal G) 349 { 350 G = kStd(G, NULL, testHomog, NULL); 351 G = kInterRed(G, NULL);//5.02 352 idSkipZeroes(G); 353 return G; 354 } 355 356 /* compute a Groebner basis of a homogenoues ideal */ 357 ideal Mstdhom(ideal G) 358 { 359 G = kStd(G, NULL, isHomog, NULL); 360 G = kInterRed(G, NULL);//21.02 361 idSkipZeroes(G); 362 return G; 363 } 364 365 /* compute a reduced Groebner basis of a Groebner basis */ 366 ideal MkInterRed(ideal G) 367 { 368 if(G == NULL) 369 return G; 370 371 G = kInterRed(G, NULL); 372 idSkipZeroes(G); 373 return G; 374 } 375 376 377 /***************************************************** 378 * PERTURBATION WALK * 379 *****************************************************/ 380 381 /*************************************** 382 * create an ordering matrix as intvec * 383 ****************************************/ 384 intvec* MivMatrixOrder(intvec* iv) 385 { 386 int i,j; 387 int nR = currRing->N; 388 intvec* ivm = new intvec(nR*nR); 389 390 for(i=0; i<nR; i++) 391 (*ivm)[i] = (*iv)[i]; 392 393 for(i=1; i<nR; i++) 394 (*ivm)[i*nR+i-1] = (int) 1; 395 396 return ivm; 397 } 398 399 static intvec* MivMatUnit(void) 400 { 401 int nR = currRing->N; 402 intvec* ivm = new intvec(nR); 403 404 (*ivm)[0] = 1; 405 406 return ivm; 407 } 408 409 /* return iv = (1, ..., 1) */ 410 intvec* Mivdp(int nR) 411 { 412 int i; 413 intvec* ivm = new intvec(nR); 414 415 for(i=0; i<nR; i++) 416 (*ivm)[i] = 1; 417 418 return ivm; 419 } 420 421 /* return iv = (1,0, ..., 0) */ 422 intvec* Mivlp(int nR) 423 { 424 int i; 425 intvec* ivm = new intvec(nR); 426 (*ivm)[0] = 1; 427 428 return ivm; 429 } 430 431 intvec* Mivdp0(int nR) 432 { 433 int i; 434 intvec* ivm = new intvec(nR); 435 (*ivm)[nR-1] = 0; 436 for(i=0; i<nR-1; i++) 437 (*ivm)[i] = 1; 438 439 return ivm; 440 } 441 442 /***************************************************************************** 443 * If target_ord = intmat(A1, ..., An) then calculate the perturbation * 444 * vectors * 445 * tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg * 446 * where * 447 * inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg)) * 448 * intmat target_ord is an integer order matrix of the monomial ordering of * 449 * basering. * 450 * This programm computes a perturbated vector with a p_deg perturbation * 451 * degree which smaller than the numbers of varibles * 452 ******************************************************************************/ 453 /* ivtarget is a matrix of a degree reverse lex. order */ 454 intvec* MPertVectors(ideal G, intvec* ivtarget, int pdeg) 455 { 456 int nV = currRing->N; 457 //assume(pdeg <= nV && pdeg >= 0); 458 459 int i, j; 460 intvec* pert_vector = new intvec(nV); 461 462 //Checking that the perturbated degree is valid 463 if(pdeg > nV || pdeg <= 0) 464 { 465 WerrorS("The perturbed degree is wrong!!"); 466 return pert_vector; 467 } 468 for(i=0; i<nV; i++) 469 (*pert_vector)[i]=(*ivtarget)[i]; 470 471 if(pdeg == 1) 472 return pert_vector; 473 474 // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg), 475 // where the Ai are the i-te rows of the matrix target_ord. 476 477 int ntemp, maxAi, maxA=0; 478 //for(i=1; i<pdeg; i++) 479 for(i=0; i<pdeg; i++) //for "dp" 480 { 481 maxAi = (*ivtarget)[i*nV]; 482 for(j=i*nV+1; j<(i+1)*nV; j++) 483 { 484 ntemp = (*ivtarget)[j]; 485 if(ntemp > maxAi) 486 maxAi = ntemp; 487 } 488 maxA += maxAi; 489 } 490 491 // Calculate inveps = 1/eps, where 1/eps > totaldeg(p)*max1 for all p in G. 492 int inveps, tot_deg = 0, maxdeg; 493 494 intvec* ivUnit = Mivdp(nV);//19.02 495 for(i=0; i<IDELEMS(G); i++) 496 { 497 //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose 498 maxdeg = MwalkWeightDegree(G->m[i], ivUnit); 499 if (maxdeg > tot_deg ) 500 tot_deg = maxdeg; 501 } 502 inveps = (tot_deg * maxA) + 1; 503 504 // pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg, 505 // pert_vector := A1 506 for ( i=1; i < pdeg; i++ ) 507 for(j=0; j<nV; j++) 508 (*pert_vector)[j] = inveps*(*pert_vector)[j] + (*ivtarget)[i*nV+j]; 509 510 511 int temp = (*pert_vector)[0]; 512 for(i=1; i<nV; i++) 513 { 514 temp = gcd(temp, (*pert_vector)[i]); 515 if(temp == 1) 516 break; 517 } 518 if(temp != 1) 519 for(i=0; i<nV; i++) 520 (*pert_vector)[i] = (*pert_vector)[i] / temp; 521 522 //test_w_in_Cone(G, pert_vector); 523 return pert_vector; 524 } 525 526 /* ivtarget is a matrix of the lex. order */ 527 intvec* MPertVectorslp(ideal G, intvec* ivtarget, int pdeg) 528 { 529 int nV = currRing->N; 530 //assume(pdeg <= nV && pdeg >= 0); 531 532 int i, j; 533 intvec* pert_vector = new intvec(nV); 534 535 //Checking that the perturbated degree is valid 536 if(pdeg > nV || pdeg <= 0) 537 { 538 WerrorS("The perturbed degree is wrong!!"); 539 return pert_vector; 540 } 541 for(i=0; i<nV; i++) 542 (*pert_vector)[i]=(*ivtarget)[i]; 543 544 if(pdeg == 1) 545 return pert_vector; 546 547 // Calculate max1 = Max(A2)+Max(A3)+...+Max(Apdeg), 548 // where the Ai are the i-te rows of the matrix target_ord. 549 int ntemp, maxAi, maxA=0; 550 for(i=1; i<pdeg; i++) 551 //for(i=0; i<pdeg; i++) //for "dp" 552 { 553 maxAi = (*ivtarget)[i*nV]; 554 for(j=i*nV+1; j<(i+1)*nV; j++) 555 { 556 ntemp = (*ivtarget)[j]; 557 if(ntemp > maxAi) 558 maxAi = ntemp; 559 } 560 maxA += maxAi; 561 } 562 563 // Calculate inveps := 1/eps, where 1/eps > deg(p)*max1 for all p in G. 564 int inveps, tot_deg = 0, maxdeg; 565 566 intvec* ivUnit = Mivdp(nV);//19.02 567 for(i=0; i<IDELEMS(G); i++) 568 { 569 //maxdeg = pTotaldegree(G->m[i], currRing); //it's wrong for ex1,2,rose 570 maxdeg = MwalkWeightDegree(G->m[i], ivUnit); 571 if (maxdeg > tot_deg ) 572 tot_deg = maxdeg; 573 } 574 inveps = (tot_deg * maxA) + 1; 575 576 // Pert(A1) = inveps^(pdeg-1)*A1 + inveps^(pdeg-2)*A2+...+A_pdeg, 577 578 for ( i=1; i < pdeg; i++ ) 579 for(j=0; j<nV; j++) 580 (*pert_vector)[j] = inveps*((*pert_vector)[j]) + (*ivtarget)[i*nV+j]; 581 582 int temp = (*pert_vector)[0]; 583 for(i=1; i<nV; i++) 584 { 585 temp = gcd(temp, (*pert_vector)[i]); 586 if(temp == 1) 587 break; 588 } 589 if(temp != 1) 590 for(i=0; i<nV; i++) 591 (*pert_vector)[i] = (*pert_vector)[i] / temp; 592 593 //test_w_in_Cone(G, pert_vector); 594 return pert_vector; 595 } 596 597 598 /*************************************************************** 599 * FRACTAL WALK * 600 ***************************************************************/ 601 602 /***** define a lexicographic order matrix as intvec ********/ 603 intvec* MivMatrixOrderlp(int nV) 604 { 605 int i; 606 intvec* ivM = new intvec(nV*nV); 607 608 for(i=0; i<nV; i++) 609 (*ivM)[i*nV + i] = 1; 610 611 return(ivM); 612 } 613 614 intvec* MivMatrixOrderdp(int nV) 615 { 616 int i; 617 intvec* ivM = new intvec(nV*nV); 618 619 for(i=0; i<nV; i++) 620 (*ivM)[i] = 1; 621 622 for(i=1; i<nV; i++) 623 (*ivM)[(i+1)*nV - i] = -1; 624 625 return(ivM); 626 } 627 628 //creates an intvec of the monomial order Wp(ivstart) 629 intvec* MivWeightOrderlp(intvec* ivstart) 630 { 631 int i; 632 int nV = ivstart->length(); 633 intvec* ivM = new intvec(nV*nV); 634 635 for(i=0; i<nV; i++) 636 (*ivM)[i] = (*ivstart)[i]; 637 638 for(i=1; i<nV; i++) 639 (*ivM)[i*nV + i-1] = 1; 640 641 return(ivM); 642 } 643 644 intvec* MivWeightOrderdp(intvec* ivstart) 645 { 646 int i; 647 int nV = ivstart->length(); 648 intvec* ivM = new intvec(nV*nV); 649 650 for(i=0; i<nV; i++) 651 (*ivM)[i] = (*ivstart)[i]; 652 653 for(i=0; i<nV; i++) 654 (*ivM)[nV+i] = 1; 655 656 for(i=2; i<nV; i++) 657 (*ivM)[(i+1)*nV - i] = -1; 658 659 return(ivM); 660 } 661 662 intvec* MivUnit(int nV) 663 { 664 int i; 665 intvec* ivM = new intvec(nV); 666 667 for(i=0; i<nV; i++) 668 (*ivM)[i] = 1; 669 670 return(ivM); 671 } 672 673 /************************************************************************ 674 * compute a perturbed weight vector of a matrix order w.r.t. an ideal * 675 *************************************************************************/ 676 intvec* Mfpertvector(ideal G, intvec* ivtarget) 677 //intvec* Mfpertvector(ideal G) 678 { 679 int i, j; 680 int nV = currRing->N; 681 int niv = nV*nV; 682 683 // Calculate max1 = Max(A2) + Max(A3) + ... + Max(AnV), 684 // where the Ai are the i-te rows of the matrix 'targer_ord'. 685 int ntemp, maxAi, maxA=0; 686 for(i=1; i<nV; i++) //30.03 687 //for(i=0; i<nV; i++) //for "dp" 688 { 689 maxAi = (*ivtarget)[i*nV]; 690 for(j=i*nV+1; j<(i+1)*nV; j++) 691 { 692 ntemp = (*ivtarget)[j]; 693 if(ntemp > maxAi) 694 maxAi = ntemp; 695 } 696 maxA = maxA + maxAi; 697 } 698 intvec* ivUnit = Mivdp(nV); 699 700 // Calculate inveps = 1/eps, where 1/eps > deg(p)*max1 for all p in G. 701 int inveps, tot_deg = 0, maxdeg; 702 for(i=0; i<IDELEMS(G); i++) 703 { 704 maxdeg = MwalkWeightDegree(G->m[i], ivUnit); 705 //maxdeg = pTotaldegree(G->m[i]); 706 if (maxdeg > tot_deg ) 707 tot_deg = maxdeg; 708 } 709 inveps = (tot_deg * maxA) + 1; 710 711 // Calculate the perturbed target orders: 712 intvec* ivtemp = new intvec(nV); 713 intvec* pert_vector = new intvec(niv); 714 for(i=0; i<nV; i++) 715 { 716 ntemp = (*ivtarget)[i]; 717 (* ivtemp)[i] = ntemp; 718 (* pert_vector)[i] = ntemp; 719 } 720 for(i=1; i<nV; i++) 721 { 722 for(j=0; j<nV; j++) 723 (* ivtemp)[j] = inveps*(*ivtemp)[j] + (*ivtarget)[i*nV+j]; 724 for(j=0; j<nV; j++) 725 (* pert_vector)[i*nV+j] = (* ivtemp)[j]; 726 } 727 omFree((ADDRESS)ivtemp); 728 return pert_vector; 729 } 730 731 732 /********************************************************************** 733 * computes a transformation matrix as an ideal L 734 an i-th element of L is a representasion of an i-th element M w.r.t. 735 the generators of Gomega 736 ********************************************************************/ 737 738 ideal MidLift(ideal Gomega, ideal M) 739 { 740 //M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL); 741 //return M; 742 //17.04.01 743 ideal Mtmp = idInit(IDELEMS(M),1); 744 Mtmp = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL); 745 idSkipZeroes(Mtmp); 746 M = idCopy(Mtmp); 747 748 omFree((ADDRESS)Mtmp); 749 return M; 750 } 751 752 /**************************************************************** 753 * Multiplikation of two ideals by elementwise * 754 * i.e. Let be A := (a_i) and B := (b_i), return C := (a_i*b_i) * 755 ****************************************************************/ 756 ideal MidMultLift(ideal A, ideal B) 757 { 758 int mA = IDELEMS(A), mB = IDELEMS(B); 759 ideal result; 760 761 if(A==NULL || B==NULL) 762 return result; 763 764 if(mB < mA) 765 { 766 mA = mB; 767 result = idInit(mA, 1); 768 } 769 else 770 result = idInit(mA, 1); 771 772 int i, k=0; 773 for(i=0; i<mA; i++) 774 if(A->m[i] != NULL) 775 { 776 result->m[k] = pMult(pCopy(A->m[i]), pCopy(B->m[i])); 777 k++; 778 } 779 780 //idSkipZeroes(result); //walkalp_CON 781 ideal res = idCopy(result); 782 idDelete(&result); 783 return res; 784 } 785 786 //computes a multiplication of two ideals L and G, ie. L[i]*G[i] 787 ideal MLiftLmalG(ideal L, ideal G) 788 { 789 int i, j; 790 ideal Gtemp = idInit(IDELEMS(L),1); 791 ideal mG = idInit(IDELEMS(G),1); 792 poly pGtmp = NULL, pmG; 793 ideal T; 794 795 for(i=0; i<IDELEMS(L); i++) 796 { 797 T = idVec2Ideal(L->m[i]); 798 mG = MidMultLift(T,G); 799 idSkipZeroes(mG); 800 801 for(j=0; j<IDELEMS(mG); j++) 802 { 803 pGtmp = pAdd(pGtmp, mG->m[j]); 804 } 805 Gtemp->m[i] = pCopy(pGtmp); 806 } 807 idSkipZeroes(Gtemp); 808 809 //compute a reduced Groebner basis of GF 810 //Gtemp = kInterRed(Gtemp, NULL); 811 L = idCopy(Gtemp); 812 813 omFree((ADDRESS)mG); 814 omFree((ADDRESS)Gtemp); 815 return L; 816 } 817 818 /********************************************************************* 819 * G is a red. Groebner basis w.r.t. <_1 * 820 * Gomega is an initial form ideal of <G> w.r.t. a weight vector w * 821 * M is a subideal of <Gomega> and M selft is a red. Groebner basis * 822 * of the ideal <Gomega> w.r.t. <_w * 823 * Let m_i = h1.gw1 + ... + hs.gws for each m_i in M; gwi in Gomega * 824 * return F with n(F) = n(M) and f_i = h1.g1 + ... + hs.gs for each i* 825 ********************************************************************/ 826 /* MidLift + MLiftLmalG */ 827 ideal MLiftLmalGNew(ideal Gomega, ideal M, ideal G) 828 { 829 int i, j; 830 M = idLift(Gomega, M, NULL, FALSE, FALSE, TRUE, NULL); 831 int nM = IDELEMS(M); 832 ideal Gtemp = idInit(IDELEMS(M),1); 833 ideal mG = idInit(IDELEMS(G),1); 834 poly pmG, pGtmp = NULL; 835 ideal T; 836 837 for(i=0; i<nM; i++) 838 { 839 T = idVec2Ideal(M->m[i]); 840 mG = MidMultLift(T, G); 841 842 for(j=0; j<IDELEMS(mG); j++) 843 pGtmp = pAdd(pGtmp, mG->m[j]); 844 845 Gtemp->m[i] = pCopy(pGtmp); 846 } 847 idSkipZeroes(Gtemp); 848 849 M = idCopy(Gtemp); 850 851 omFree((ADDRESS)mG); 852 omFree((ADDRESS)Gtemp); 853 return M; 854 } 855 856 /****************************************************************************** 857 * compute a next weight vector on the line from curr_weight to target_weight * 858 * and it still stays in the cone of the ideal G where the curr_weight too * 859 *****************************************************************************/ 860 intvec* MwalkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G) 861 { 862 assume(currRing != NULL && curr_weight != NULL && 863 target_weight != NULL && G != NULL); 864 865 int nRing = currRing->N; 866 int nG = IDELEMS(G); 867 intvec* ivtemp; 868 869 long t_zaehler = 0, t_nenner = 0; 870 long s_zaehler, s_nenner, temp, MwWd; 871 long deg_w0_p1, deg_d0_p1; 872 int j; 873 874 intvec* diff_weight = ivSub(target_weight, curr_weight); 875 poly g; 876 for (j=0; j<nG; j++) 877 { 878 g = G->m[j]; 879 if (g != NULL) 880 { 881 ivtemp = MExpPol(g); 882 deg_w0_p1 = MivDotProduct(ivtemp, curr_weight); 883 deg_d0_p1 = MivDotProduct(ivtemp, diff_weight); 884 101 885 pIter(g); 102 886 103 887 while (g != NULL) 104 888 { 105 // compute s = s_zahler / s_nenner 106 long s_zaehler = deg_w0_p1 - pGetOrder(g); 889 //s_zaehler = deg_w0_p1 - pGetOrder(g); 890 ivtemp = MExpPol(g); 891 MwWd = MivDotProduct(ivtemp, curr_weight); 892 s_zaehler = deg_w0_p1 - MwWd; 107 893 108 894 if (s_zaehler != 0) 109 { 110 long s_nenner = 111 walkWeightDegree(g, diff_weight, currRing->N) - deg_d0_p1; 895 { 896 //s_nenner = MwalkWeightDegree(g, diff_weight) - deg_d0_p1; 897 MwWd = MivDotProduct(ivtemp, diff_weight); 898 s_nenner = MwWd - deg_d0_p1; 899 112 900 // check for 0 < s <= 1 113 901 if ( (s_zaehler > 0 && s_nenner >= s_zaehler) || … … 121 909 } 122 910 123 // look whether s < t 124 if (t_nenner == 0 || 125 s_zaehler*t_nenner < t_zaehler * s_nenner) 911 // compute a simply fraction of s 912 cancel(s_zaehler, s_nenner); 913 914 if(t_nenner != 0) 126 915 { 127 cancel(s_zaehler, s_nenner); 128 t_zaehler = s_zaehler; 916 if(s_zaehler * t_nenner < s_nenner * t_zaehler) 917 { 918 t_nenner = s_nenner; 919 t_zaehler = s_zaehler; 920 } 921 } 922 else 923 { 129 924 t_nenner = s_nenner; 925 t_zaehler = s_zaehler; 130 926 } 131 927 } 132 928 } 133 pIter(g); 929 pIter(g); //g = g - pHead(g); 134 930 } 135 931 } 136 932 } 137 138 // return if no t or if t == 1 139 if (t_nenner == 0 || t_nenner == 1) 140 { 141 omFreeSize(diff_weight, currRing->N*sizeof(int)); 142 return (int*) t_nenner; 143 } 144 145 // construct new weight vector 146 for (j=0; j<currRing->N; j++) 147 diff_weight[j] = t_nenner*curr_weight[j] + t_zaehler*diff_weight[j]; 933 if(t_nenner == 0) 934 { 935 diff_weight = ivCopy(curr_weight); 936 return diff_weight; 937 } 938 939 if(t_nenner == 1 && t_zaehler == 1) 940 { 941 diff_weight = ivCopy(target_weight); 942 return diff_weight; 943 } 944 945 // construct a new weight vector 946 for (j=0; j<nRing; j++) 947 { 948 (*diff_weight)[j] = t_nenner*(*curr_weight)[j] + 949 t_zaehler*(*diff_weight)[j]; 950 } 951 148 952 // and take out the content 149 long temp = diff_weight[0];150 151 for (j=1; j<currRing->N && temp != 1; j++)152 {153 temp = gcd(temp, diff_weight[j]);154 if (temp == 1) goto Finish;155 } 156 157 for (j=0; j<currRing->N; j++) 158 diff_weight[j] = diff_weight[j] / temp;159 160 Finish: 953 temp = (*diff_weight)[0]; 954 if(temp != 1) 955 for (j=1; j<nRing; j++) 956 { 957 temp = gcd(temp, (*diff_weight)[j]); 958 if (temp == 1) 959 return diff_weight; 960 } 961 962 for (j=0; j<nRing; j++) 963 (*diff_weight)[j] = (*diff_weight)[j] / temp; 964 161 965 return diff_weight; 162 966 } 163 967 164 165 // next weight vector given weights as intvecs 166 intvec* walkNextWeight(intvec* curr_weight, intvec* target_weight, ideal G) 167 { 168 assume(curr_weight->length() == currRing->N); 169 assume(target_weight->length() == currRing->N); 170 171 int* nw = walkNextWeight(curr_weight->ivGetVec(), 172 target_weight->ivGetVec(), 173 G); 174 intvec* next_weight; 175 176 if (nw != NULL && nw != (int*) 1) 177 { 178 next_weight = new intvec(currRing->N); 179 int *nw_i = next_weight->ivGetVec(); 180 int i; 181 182 for (i=0; i<currRing->N; i++) 183 nw_i[i] = nw[i]; 184 omFreeSize(nw, (currRing->N)*sizeof(int)); 185 } 186 else 187 { 188 next_weight = (intvec*) nw; 189 } 190 191 return next_weight; 192 } 193 194 195 // returns ideals of initials (w.r.t. curr_weight) of ideal G 196 // assumes that monoms are ordered by descending W-degree (w.r.t curr_weight) 197 198 poly walkInitials(poly p) 199 { 200 assume(p != NULL); 201 202 poly pi = pHead(p); 203 poly pr = pi; 204 long d_lm = pGetOrder(p); 205 206 pIter(p); 207 208 while (p != NULL && pGetOrder(p) == d_lm) 209 { 210 pNext(pi) = pHead(p); 211 pIter(pi); 212 pIter(p); 213 } 214 215 assume(p == NULL || pGetOrder(p) < d_lm); 216 217 pNext(pi) = NULL; 218 pTest(pr); 219 return pr; 220 } 221 222 ideal walkInitials(ideal G) 223 { 224 ideal GI = idInit(IDELEMS(G),1); 968 /* Condition: poly f must be divided by the ideal G */ 969 /* Let f = h1g1+...+hsgs, then the result is (h1, ... ,hs) */ 970 static ideal MNormalForm(poly f, ideal G) 971 { 972 int nG = IDELEMS(G); 973 ideal lmG = idInit(nG, 1); 974 ideal result = idInit(nG, 1); 975 int i, ind=0, ncheck=0; 976 977 for(i=0; i<nG; i++) 978 { 979 lmG->m[i] = pHead(G->m[i]); 980 result->m[i] = NULL; 981 } 982 983 poly h = f; 984 poly lmh, q, pmax = pISet(1), quot, qtmp=NULL; 985 int ntest = 0; 986 while(h != NULL) 987 { 988 lmh = pHead(h); 989 for(i=0; i<nG; i++) 990 { 991 q = MpDiv(lmh, lmG->m[i]); 992 993 if(q != NULL) 994 { 995 if(ncheck == 0) 996 { 997 result->m[i] = pCopy(pAdd(result->m[i], q)); 998 h = pSub(h, pMult(q, pCopy(G->m[i]))); 999 break; 1000 } 1001 else { 1002 h = pSub(f, pMult(q, pCopy(G->m[i]))); 1003 if(quot != NULL) 1004 { 1005 ntest = 1; 1006 qtmp = q; 1007 ind = i; 1008 ncheck = 0; 1009 } 1010 } 1011 } 1012 } 1013 if(i==nG) 1014 { 1015 f = h; 1016 pIter(h); 1017 ncheck = 1; 1018 } 1019 1020 if(ntest == 1) 1021 { 1022 result->m[ind] = pCopy(pAdd(result->m[ind], qtmp)); 1023 ntest = 0; 1024 } 1025 } 1026 ideal rest = idCopy(result); 1027 idDelete(&result); 1028 idDelete(&lmG); 1029 return rest; 1030 } 1031 1032 /* GW is an initial form of the ideal G w.r.t. a weight vector */ 1033 /* polynom f is divided by the ideal GW */ 1034 /* Let f := h_1.gw_1 + ... + h_s.gw_s, then the result is */ 1035 /* h_1.g_1 + ... + h_s.g_s */ 1036 static poly MpolyConversion(poly f, ideal GW, ideal G) 1037 { 1038 ideal H = MNormalForm(f, GW); 1039 ideal HG = MidMultLift(H, G); 1040 1041 poly result = NULL; 225 1042 int i; 226 227 for (i=0; i<IDELEMS(G); i++) 228 GI->m[i] = walkInitials(G->m[i]); 229 230 return GI; 231 } 1043 int nG = IDELEMS(G); 1044 1045 for(i=0; i<nG; i++) 1046 result = pCopy(pAdd(result, HG->m[i])); 1047 1048 return result; 1049 } 1050 1051 /* GW is an initial form of the ideal G w.r.t. a weight vector */ 1052 /* Each polynom f of the ideal M is divided by the ideal GW */ 1053 /* Let m_i := h_1.gw_1 + ... + h_s.gw_s, then the i-th polynom */ 1054 /* of result is f_i := h_1.g_1 + ... + h_s.g_s */ 1055 ideal MidealConversion(ideal M, ideal GW, ideal G) 1056 { 1057 int nM = IDELEMS(M); 1058 int i; 1059 1060 for(i=0; i<nM; i++) 1061 { 1062 M->m[i] = MpolyConversion(M->m[i], GW, G); 1063 } 1064 ideal result = idCopy(M); 1065 return result; 1066 } 1067 1068 /* check that the monomial f is reduced by a monomial ideal G */ 1069 static inline int MCheckpRedId(poly f, ideal G) 1070 { 1071 int nG = IDELEMS(G); 1072 int i; 1073 poly q; 1074 1075 for(i=0; i<nG; i++) 1076 { 1077 q = MpDiv(f, G->m[i]); 1078 if(q != NULL) 1079 return 0; 1080 } 1081 return 1; 1082 } 1083 1084 poly MpReduceId(poly f, ideal GO) 1085 { 1086 ideal G = idCopy(GO); 1087 int nG = IDELEMS(G); 1088 int i, pcheck; 1089 ideal HG = idInit(nG, 1); 1090 1091 for(i=0; i<nG; i++) 1092 HG->m[i] = pHead(G->m[i]); 1093 1094 poly h = f; 1095 poly lmh, q,qg, result = NULL; 1096 1097 while(h!=NULL) 1098 { 1099 f = pCopy( h); 1100 lmh = pHead(h); 1101 1102 if(MCheckpRedId(lmh, HG) != 0) 1103 { 1104 result = pCopy(pAdd(result, lmh)); 1105 pIter(h); 1106 } 1107 else 1108 for(i=0; i<nG; i++) 1109 { 1110 q = MpDiv(lmh, HG->m[i]); 1111 if(q != NULL) 1112 { 1113 f = pAdd(result, f); 1114 qg = pMult(q, G->m[i]); 1115 h = pSub(f, qg); 1116 result = NULL; 1117 1118 lmh = pHead(h); 1119 pcheck = MCheckpRedId(lmh, HG); 1120 if(pcheck != 0) 1121 { 1122 break; 1123 } 1124 } 1125 } 1126 } 1127 idDelete(&HG); 1128 return result; 1129 } 1130 1131 /* return f, if a head term of f is not divided by a head ideal M */ 1132 static poly MpMinimId(poly f, ideal M) 1133 { 1134 int nM = IDELEMS(M); 1135 ideal HM = idInit(nM, 1); 1136 int i, pcheck; 1137 1138 for(i=0; i<nM; i++) 1139 HM->m[i] = pCopy(M->m[i]); 1140 1141 poly result = pCopy(f); 1142 poly hf=pHead(f), q, qtmp, h=f; 1143 1144 if(MCheckpRedId(pHead(f), HM) != 0) 1145 goto FINISH; 1146 1147 while(1) 1148 { 1149 for(i=0; i<nM; i++) 1150 { 1151 q = MpDiv(hf, HM->m[i]); 1152 if(q != NULL) 1153 { 1154 qtmp = pMult(q, M->m[i]); 1155 h = pSub(h, qtmp); 1156 1157 hf = pHead(h); 1158 pcheck = MCheckpRedId(hf, HM); 1159 if(pcheck != 0) 1160 { 1161 result = pCopy(h); 1162 goto FINISH; 1163 } 1164 break; 1165 } 1166 } 1167 } 1168 1169 FINISH: 1170 idDelete(&HM); 1171 return result; 1172 } 1173 1174 /* return a minimal ideal of an ideal M */ 1175 ideal MidMinimId(ideal M) 1176 { 1177 int i,j=0; 1178 ideal result = idInit(IDELEMS(M),1); 1179 poly pmin; 1180 for(i=0; i<IDELEMS(M); i++) 1181 { 1182 ideal Mtmp = idCopy(M); 1183 Mtmp->m[j] = NULL; 1184 idSkipZeroes(Mtmp); 1185 pmin = MpMinimId(pCopy(M->m[i]), Mtmp); 1186 M->m[i] = pCopy(pmin); 1187 result->m[j] = pmin; 1188 if(pmin == NULL) 1189 { 1190 i--; 1191 j--; 1192 idSkipZeroes(M); 1193 } 1194 j++; 1195 idDelete(&Mtmp); 1196 } 1197 idSkipZeroes(result); 1198 ideal res = idCopy(result); 1199 idDelete(&result); 1200 return res; 1201 } 1202 1203 1204 ideal MidMinBase(ideal G) 1205 { 1206 if(G == NULL) 1207 return G; 1208 1209 intvec * wth; 1210 lists re = min_std(G,currQuotient,(tHomog)TRUE,&wth,NULL,0,3); 1211 G = (ideal)re->m[1].data; 1212 re->m[1].data = NULL; 1213 re->m[1].rtyp = NONE; 1214 re->Clean(); 1215 1216 return G; 1217 } 1218 1219 1220 /* compute a Groebner basis of a homogenoues ideal */ 1221 ideal MNWstdhomRed(ideal G, intvec* iv) 1222 { 1223 1224 ideal Gomega = MwalkInitialForm(G, iv); 1225 G = kStd(Gomega, NULL, isHomog, NULL); 1226 Gomega = MkInterRed(G); 1227 1228 return Gomega; 1229 } 1230 1231 /***************************************************************************** 1232 * If target_ord = intmat(A1,..., An) then calculate the perturbation vectors * 1233 * tau_p_dep = inveps^(p_deg-1)*A1 + inveps^(p_deg-2)*A2 +... + A_p_deg * 1234 * where * 1235 * inveps > totaldegree(G)*(max(A2)+...+max(A_p_deg)) * 1236 * and * 1237 * p_deg <= the number of variables of a basering * 1238 ******************************************************************************/ 1239 intvec* Mfivpert(ideal G, intvec* target, int p_deg) 1240 { 1241 int i, j; 1242 int nV = currRing->N; 1243 1244 //Checking that the perturbation degree is valid 1245 if(p_deg > nV || p_deg <= 0) 1246 { 1247 WerrorS("The perturbed degree is wrong!!"); 1248 return NULL; 1249 } 1250 1251 // Calculate max_el_rows = Max(A2)+Max(A3)+...+Max(Ap_deg), 1252 // where the Ai are the rows of the target-order matrix. 1253 int nmax = 0, maxAi, ntemp; 1254 1255 for(i=1; i < p_deg; i++) 1256 { 1257 maxAi = (*target)[i*nV]; 1258 for(j=1; j < nV; j++) 1259 { 1260 ntemp = (*target)[i*nV + j]; 1261 if(ntemp > maxAi) 1262 maxAi = ntemp; 1263 } 1264 nmax += maxAi; 1265 } 1266 1267 // Calculate inv_eps := 1/eps, where 1/eps > deg(p)*max_el_rows 1268 // for all p in G. 1269 int inv_eps, degG, max_deg=0; 1270 intvec* ivUnit = Mivdp(nV); 1271 1272 for (i=0; i<IDELEMS(G); i++) 1273 { 1274 degG = MwalkWeightDegree(G->m[i], ivUnit); 1275 if(degG > max_deg) 1276 max_deg = degG; 1277 } 1278 inv_eps = (max_deg * nmax) + 1; 1279 1280 1281 // Calculate the perturbed target order: 1282 // Since a weight vector in Singular has to be in integral, we compute 1283 // tau_p_deg = inv_eps^(p_deg-1)*A1 - inv_eps^(p_deg-2)*A2+...+A_p_deg, 1284 1285 intvec* ivtemp = new intvec(nV); 1286 intvec* pert_vector = new intvec(nV); 1287 1288 for(i=0; i<nV; i++) 1289 { 1290 ntemp = (*target)[i]; 1291 (* ivtemp)[i] = ntemp; 1292 (* pert_vector)[i] = ntemp; 1293 } 1294 1295 for(i=1; i<p_deg; i++) 1296 { 1297 for(j=0; j<nV; j++) 1298 (* ivtemp)[j] = inv_eps*(*ivtemp)[j] + (*target)[i*nV+j]; 1299 1300 pert_vector = ivtemp; 1301 } 1302 omFree((ADDRESS) ivtemp); 1303 return pert_vector; 1304 } 1305 1306 ideal MpHeadIdeal(ideal G) 1307 { 1308 int i, nG = IDELEMS(G); 1309 ideal result = idInit(nG,1); 1310 1311 for(i=0; i<nG; i++) 1312 { 1313 result->m[i] = pHead(G->m[i]); 1314 } 1315 1316 ideal res = idCopy(result); 1317 idDelete(&result); 1318 return res; 1319 } 1320 1321 void* checkideal(ideal G) 1322 { 1323 int i; 1324 printf("//** Size(G)= %d, and ", IDELEMS(G)); 1325 1326 for(i=0; i<IDELEMS(G); i++) 1327 { 1328 printf("G[%d] = %d, ", i, pLength(G->m[i])); 1329 } 1330 printf("\n"); 1331 } 1332
Note: See TracChangeset
for help on using the changeset viewer.