- Timestamp:
- Oct 29, 2013, 1:54:17 PM (11 years ago)
- Branches:
- (u'fieker-DuVal', '117eb8c30fc9e991c4decca4832b1d19036c4c65')(u'spielwiese', '4bd32dfef92ec9f5ed8dceee82d14318ae147107')
- Children:
- 7395dd26103d1edd6fc4505722010d2bba012d96
- Parents:
- a73fae59ddd878f87c48e12088f6b0046549aaf7
- git-author:
- Yue Ren <ren@mathematik.uni-kl.de>2013-10-29 13:54:17+01:00
- git-committer:
- Yue Ren <ren@mathematik.uni-kl.de>2015-02-06 13:47:01+01:00
- Location:
- Singular/dyn_modules/gfanlib
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
Singular/dyn_modules/gfanlib/bbcone.cc
ra73fae rd770e6 113 113 zv[j]=i[j+1]; 114 114 return zv; 115 } 116 117 int* ZVectorToIntStar(const gfan::ZVector &v, bool &overflow) 118 { 119 int* w = (int*) omAlloc(v.size()*sizeof(int)); 120 for (unsigned i=0; i<v.size(); i++) 121 { 122 if (!v[i].fitsInInt()) 123 { 124 omFree(w); 125 WerrorS("intoverflow converting gfan:ZVector to int*"); 126 overflow = true; 127 return NULL; 128 } 129 w[i]=v[i].toInt(); 130 } 131 return w; 115 132 } 116 133 -
Singular/dyn_modules/gfanlib/bbcone.h
ra73fae rd770e6 27 27 28 28 gfan::ZVector intStar2ZVector(const int d, const int* i); 29 int* ZVectorToIntStar(const gfan::ZVector &v, bool &overflow); 29 30 char* toString(gfan::ZMatrix const &m); 30 31 std::string toString(const gfan::ZCone* const c); -
Singular/dyn_modules/gfanlib/tropical.cc
ra73fae rd770e6 1 1 #include <kernel/polys.h> 2 #include <kernel/kstd1.h> 2 3 #include <libpolys/coeffs/longrat.h> 4 #include <libpolys/polys/clapsing.h> 3 5 #include <bbcone.h> 4 6 … … 154 156 155 157 158 gfan::ZCone* maximalGroebnerCone(const ring &r, const ideal &I) 159 { 160 int n = rVar(r); 161 poly g = NULL; 162 int* leadexpv = (int*) omAlloc((n+1)*sizeof(int)); 163 int* tailexpv = (int*) omAlloc((n+1)*sizeof(int)); 164 gfan::ZVector leadexpw = gfan::ZVector(n); 165 gfan::ZVector tailexpw = gfan::ZVector(n); 166 gfan::ZMatrix inequalities = gfan::ZMatrix(0,n); 167 for (int i=0; i<IDELEMS(I); i++) 168 { 169 g = (poly) I->m[i]; pGetExpV(g,leadexpv); 170 leadexpw = intStar2ZVector(n, leadexpv); 171 pIter(g); 172 while (g != NULL) 173 { 174 pGetExpV(g,tailexpv); 175 tailexpw = intStar2ZVector(n, tailexpv); 176 inequalities.appendRow(leadexpw-tailexpw); 177 pIter(g); 178 } 179 } 180 omFreeSize(leadexpv,(n+1)*sizeof(int)); 181 omFreeSize(tailexpv,(n+1)*sizeof(int)); 182 return new gfan::ZCone(inequalities,gfan::ZMatrix(0, inequalities.getWidth())); 183 } 184 185 156 186 BOOLEAN maximalGroebnerCone(leftv res, leftv args) 157 187 { … … 162 192 if (v == NULL) 163 193 { 164 int n = currRing->N;165 194 ideal I = (ideal) u->Data(); 166 poly g = NULL;167 int* leadexpv = (int*) omAlloc((n+1)*sizeof(int));168 int* tailexpv = (int*) omAlloc((n+1)*sizeof(int));169 gfan::ZVector leadexpw = gfan::ZVector(n);170 gfan::ZVector tailexpw = gfan::ZVector(n);171 gfan::ZMatrix inequalities = gfan::ZMatrix(0,n);172 for (int i=0; i<IDELEMS(I); i++)173 {174 g = (poly) I->m[i]; pGetExpV(g,leadexpv);175 leadexpw = intStar2ZVector(n, leadexpv);176 pIter(g);177 while (g != NULL)178 {179 pGetExpV(g,tailexpv);180 tailexpw = intStar2ZVector(n, tailexpv);181 inequalities.appendRow(leadexpw-tailexpw);182 pIter(g);183 }184 }185 gfan::ZCone* gCone = new gfan::ZCone(inequalities,gfan::ZMatrix(0, inequalities.getWidth()));186 omFreeSize(leadexpv,(n+1)*sizeof(int));187 omFreeSize(tailexpv,(n+1)*sizeof(int));188 189 195 res->rtyp = coneID; 190 res->data = (void*) gCone;196 res->data = (void*) maximalGroebnerCone(currRing, I); 191 197 return FALSE; 192 198 } … … 195 201 return TRUE; 196 202 } 203 204 /*** 205 * If 1, replaces all occuring t with prime p, 206 * where theoretically feasable. 207 * Also computes GCD over integers than 208 * over univariate polynomials 209 **/ 210 #define T_TO_P 0 211 212 /*** 213 * Suppose I=g_0,...,g_{n-1}. 214 * This function uses bubble sort to sorts g_1,...,g_{n-1} 215 * such that lm(g_1)>...>lm(g_{n-1}) 216 **/ 217 static inline void sortingLaterGenerators(ideal I) 218 { 219 poly cache; int i; int n=IDELEMS(I); int newn; 220 do 221 { 222 newn=0; 223 for (i=2; i<n; i++) 224 { 225 if (pLmCmp(I->m[i-1],I->m[i])<0) 226 { 227 cache=I->m[i-1]; 228 I->m[i-1]=I->m[i]; 229 I->m[i]=cache; 230 newn = i; 231 } 232 } 233 n=newn; 234 } while(n); 235 } 236 237 238 /*** 239 * replaces coefficients in g of lowest degree in t 240 * divisible by p with a suitable power of t 241 **/ 242 static bool preduce(poly g, const number p) 243 { 244 // go along g and look for relevant terms. 245 // monomials in x which have been checked are tracked in done. 246 // because we assume the leading coefficient of g is 1, 247 // the leading term does not need to be considered. 248 poly done = p_LmInit(g,currRing); 249 p_SetExp(done,1,0,currRing); p_SetCoeff(done,n_Init(1,currRing->cf),currRing); 250 p_Setm(done,currRing); 251 poly doneEnd = done; 252 poly doneCache; 253 number dnumber; long d; 254 poly subst; number ppower; 255 while(pNext(g)) 256 { 257 // check whether next term needs to be reduced: 258 // first, check whether monomial in x has come up yet 259 for (doneCache=done; doneCache; pIter(doneCache)) 260 { 261 if (p_LmDivisibleBy(doneCache,pNext(g),currRing)) 262 break; 263 } 264 if (!doneCache) // if for loop did not terminate prematurely, 265 // then the monomial in x is new 266 { 267 // second, check whether coefficient is divisible by p 268 if (n_DivBy(p_GetCoeff(pNext(g),currRing->cf),p,currRing->cf)) 269 { 270 // reduce the term with respect to p-t: 271 // divide coefficient by p, remove old term, 272 // add t multiple of old term 273 dnumber = n_Div(p_GetCoeff(pNext(g),currRing->cf),p,currRing->cf); 274 d = n_Int(dnumber,currRing->cf); 275 n_Delete(&dnumber,currRing->cf); 276 if (!d) 277 { 278 p_Delete(&done,currRing); 279 WerrorS("initialReduction: overflow in a t-exponent"); 280 return true; 281 } 282 subst=p_LmInit(pNext(g),currRing); 283 if (d>0) 284 { 285 p_AddExp(subst,1,d,currRing); 286 p_SetCoeff(subst,n_Init(1,currRing->cf),currRing); 287 } 288 else 289 { 290 p_AddExp(subst,1,-d,currRing); 291 p_SetCoeff(subst,n_Init(-1,currRing->cf),currRing); 292 } 293 p_Setm(subst,currRing); pTest(subst); 294 pNext(g)=p_LmDeleteAndNext(pNext(g),currRing); 295 pNext(g)=p_Add_q(pNext(g),subst,currRing); 296 pTest(pNext(g)); 297 } 298 // either way, add monomial in x to done 299 pNext(doneEnd)=p_LmInit(pNext(g),currRing); 300 pIter(doneEnd); 301 p_SetExp(doneEnd,1,0,currRing); 302 p_SetCoeff(doneEnd,n_Init(1,currRing->cf),currRing); 303 p_Setm(doneEnd,currRing); 304 } 305 pIter(g); 306 } 307 p_Delete(&done,currRing); 308 return false; 309 } 310 311 312 #ifndef NDEBUG 313 BOOLEAN preduce(leftv res, leftv args) 314 { 315 leftv u = args; 316 if ((u != NULL) && (u->Typ() == POLY_CMD)) 317 { 318 poly g; bool b; 319 number p = n_Init(3,currRing->cf); 320 omUpdateInfo(); 321 Print("usedBytes=%ld\n",om_Info.UsedBytes); 322 g = (poly) u->CopyD(); 323 b = preduce(g,p); 324 p_Delete(&g,currRing); 325 if (b) return TRUE; 326 omUpdateInfo(); 327 Print("usedBytes=%ld\n",om_Info.UsedBytes); 328 n_Delete(&p,currRing->cf); 329 res->rtyp = NONE; 330 res->data = NULL; 331 return FALSE; 332 } 333 return TRUE; 334 } 335 #endif //NDEBUG 336 337 338 /*** 339 * Returns the highest term in g with the matching x-monomial to m 340 * or, if it does not exist, the NULL pointer 341 **/ 342 static poly highestMatchingX(poly g, const poly m) 343 { 344 pTest(g); pTest(m); 345 poly xalpha=p_LmInit(m,currRing); 346 347 // go along g and find the first term 348 // with the same monomial in x as xalpha 349 while (g) 350 { 351 p_SetExp(xalpha,1,p_GetExp(g,1,currRing),currRing); 352 p_Setm(xalpha,currRing); 353 if (p_LmEqual(g,xalpha,currRing)) 354 break; 355 pIter(g); 356 } 357 358 // gCache now either points at the wanted term 359 // or is NULL 360 p_Delete(&xalpha,currRing); 361 pTest(g); 362 return g; 363 } 364 365 366 /*** 367 * Given g with lm(g)=t^\beta x^\alpha, returns g_\alpha 368 **/ 369 static poly powerSeriesCoeff(poly g) 370 { 371 // the first term obviously is part of our output 372 // so we copy it... 373 poly xalpha=p_LmInit(g,currRing); 374 poly coeff=p_One(currRing); 375 p_SetCoeff(coeff,n_Copy(p_GetCoeff(g,currRing),currRing->cf),currRing); 376 p_SetExp(coeff,1,p_GetExp(g,1,currRing),currRing); 377 p_Setm(coeff,currRing); 378 379 // ..and proceed with the remaining terms, 380 // appending the relevant terms to coeff via coeffCache 381 poly coeffCache=coeff; 382 pIter(g); 383 while (g) 384 { 385 p_SetExp(xalpha,1,p_GetExp(g,1,currRing),currRing); 386 p_Setm(xalpha,currRing); 387 if (p_LmEqual(g,xalpha,currRing)) 388 { 389 pNext(coeffCache)=p_Init(currRing); 390 pIter(coeffCache); 391 p_SetCoeff(coeffCache,n_Copy(p_GetCoeff(g,currRing),currRing->cf),currRing); 392 p_SetExp(coeffCache,1,p_GetExp(g,1,currRing),currRing); 393 p_Setm(coeffCache,currRing); 394 } 395 pIter(g); 396 } 397 398 p_Delete(&xalpha,currRing); 399 return coeff; 400 } 401 402 403 /*** 404 * divides g by t^b knowing that each term of g 405 * is divisible by t^b, i.e. no divisibility checks 406 * needed 407 **/ 408 static void divideByT(poly g, const long b) 409 { 410 while (g) 411 { 412 p_SetExp(g,1,p_GetExp(g,1,currRing)-b,currRing); 413 p_Setm(g,currRing); 414 pIter(g); 415 } 416 } 417 418 419 static void divideByGcd(poly &g) 420 { 421 // first determine all g_\alpha 422 // as alpha runs over all exponent vectors 423 // of monomials in x occuring in g 424 425 // gAlpha will store all g_\alpha, 426 // the first term will, for comparison purposes for now, 427 // also keep their monomial in x. 428 // we assume that the weight on the x are positive 429 // so that the x won't make the monomial smaller 430 ideal gAlphaFront = idInit(pLength(g)); 431 gAlphaFront->m[0] = p_Head(g,currRing); 432 p_SetExp(gAlphaFront->m[0],1,0,currRing); 433 p_Setm(gAlphaFront->m[0],currRing); 434 ideal gAlphaEnd = idInit(pLength(g)); 435 gAlphaEnd->m[0] = gAlphaFront->m[0]; 436 unsigned long gAlpha_sev[pLength(g)]; 437 gAlpha_sev[0] = p_GetShortExpVector(g,currRing); 438 long beta[pLength(g)]; 439 beta[0] = p_GetExp(g,1,currRing); 440 int count=0; 441 442 poly current = pNext(g); unsigned long current_not_sev; 443 int i; 444 while (current) 445 { 446 // see whether the monomial in x of current already came up 447 // since everything is homogeneous in x and the ordering is local in t, 448 // this comes down to a divisibility test in two stages 449 current_not_sev = ~p_GetShortExpVector(current,currRing); 450 for(i=0; i<=count; i++) 451 { 452 // first stage using short exponent vectors 453 // second stage a proper test 454 if (p_LmShortDivisibleBy(gAlphaFront->m[i],gAlpha_sev[i],current,current_not_sev, currRing) 455 && p_LmDivisibleBy(gAlphaFront->m[i],current,currRing)) 456 { 457 // if it already occured, add the term to the respective entry 458 // without the x part 459 pNext(gAlphaEnd->m[i])=p_Init(currRing); 460 pIter(gAlphaEnd->m[i]); 461 p_SetExp(gAlphaEnd->m[i],1,p_GetExp(current,1,currRing)-beta[i],currRing); 462 p_SetCoeff(gAlphaEnd->m[i],n_Copy(p_GetCoeff(current,currRing),currRing->cf),currRing); 463 p_Setm(gAlphaEnd->m[i],currRing); 464 break; 465 } 466 } 467 if (i>count) 468 { 469 // if it is new, create a new entry for the term 470 // including the monomial in x 471 count++; 472 gAlphaFront->m[count] = p_Head(current,currRing); 473 beta[count] = p_GetExp(current,1,currRing); 474 gAlphaEnd->m[count] = gAlphaFront->m[count]; 475 gAlpha_sev[count] = p_GetShortExpVector(current,currRing); 476 } 477 478 pIter(current); 479 } 480 481 if (count) 482 { 483 // now remove all the x in the leading terms 484 // so that gAlpha only contais terms in t 485 int j; long d; 486 for (i=0; i<=count; i++) 487 { 488 for (j=2; j<=currRing->N; j++) 489 p_SetExp(gAlphaFront->m[i],j,0,currRing); 490 p_Setm(gAlphaFront->m[i],currRing); 491 gAlphaEnd->m[i]=NULL; 492 } 493 494 // now compute the gcd over all g_\alpha 495 // and set the input to null as they are deleted in the process 496 poly gcd = singclap_gcd(gAlphaFront->m[0],gAlphaFront->m[1],currRing); 497 gAlphaFront->m[0] = NULL; 498 gAlphaFront->m[1] = NULL; 499 for(i=2; i<=count; i++) 500 { 501 gcd = singclap_gcd(gcd,gAlphaFront->m[i],currRing); 502 gAlphaFront->m[i] = NULL; 503 } 504 // divide g by the gcd 505 poly h = singclap_pdivide(g,gcd,currRing); 506 p_Delete(&gcd,currRing); 507 p_Delete(&g,currRing); 508 g = h; 509 510 id_Delete(&gAlphaFront,currRing); 511 id_Delete(&gAlphaEnd,currRing); 512 } 513 else 514 { 515 // if g contains only one monomial in x, 516 // then we can get rid of all the higher t 517 p_Delete(&g,currRing); 518 g = gAlphaFront->m[0]; 519 pIter(gAlphaFront->m[0]); 520 pNext(g)=NULL; 521 gAlphaEnd->m[0] = NULL; 522 id_Delete(&gAlphaFront,currRing); 523 id_Delete(&gAlphaEnd,currRing); 524 } 525 } 526 527 528 /*** 529 * 1. For each \alpha\in\NN^n, changes (c_\beta t^\beta + c_{\beta+1} t^{\beta+1} + ...) 530 * to (c_\beta + c_{\beta+1}*p + ...) t^\beta 531 * 2. Computes the gcd over all (c_\beta + c_{\beta+1}*p + ...) and divides g by it 532 **/ 533 static void simplify(poly g, const number p) 534 { 535 // go along g and look for relevant terms. 536 // monomials in x which have been checked are tracked in done. 537 poly done = p_LmInit(g,currRing); 538 p_SetCoeff(done,n_Init(1,currRing->cf),currRing); 539 p_Setm(done,currRing); 540 poly doneEnd = done; 541 poly doneCurrent; 542 543 poly subst; number substCoeff, substCoeffCache; 544 unsigned long d; 545 546 poly gCurrent = g; 547 while(pNext(gCurrent)) 548 { 549 // check whether next term needs to be reduced: 550 // first, check whether monomial in x has come up yet 551 for (doneCurrent=done; doneCurrent; pIter(doneCurrent)) 552 { 553 if (p_LmDivisibleBy(doneCurrent,pNext(gCurrent),currRing)) 554 break; 555 } 556 // if the monomial in x already occured, then we want to replace 557 // as many t with p as theoretically feasable 558 if (doneCurrent) 559 { 560 // suppose pNext(gCurrent)=3*t5x and doneCurrent=t3x 561 // then we want to replace pNext(gCurrent) with 3p2*t3x 562 // subst = ?*t3x 563 subst = p_LmInit(doneCurrent,currRing); 564 // substcoeff = p2 565 n_Power(p,p_GetExp(subst,1,currRing)-p_GetExp(doneCurrent,1,currRing),&substCoeff,currRing->cf); 566 // substcoeff = 3p2 567 n_InpMult(substCoeff,p_GetCoeff(pNext(gCurrent),currRing),currRing->cf); 568 // subst = 3p2*t3x 569 p_SetCoeff(subst,substCoeff,currRing); 570 p_Setm(subst,currRing); pTest(subst); 571 572 // g = g - pNext(gCurrent) + subst 573 pNext(gCurrent)=p_LmDeleteAndNext(pNext(gCurrent),currRing); 574 g=p_Add_q(g,subst,currRing); 575 pTest(pNext(gbeginning)); 576 } 577 else 578 { 579 // if the monomial in x is brand new, 580 // then we check whether the coefficient is divisible by p 581 if (n_DivBy(p_GetCoeff(pNext(gCurrent),currRing->cf),p,currRing->cf)) 582 { 583 // reduce the term with respect to p-t: 584 // suppose pNext(gCurrent)=4p3*tx 585 // then we want to replace it with 4*t4x 586 // divide 4p3 repeatedly by p until it is not divisible anymore, 587 // keeping track on the final value 4 588 // and the number of times it has been divided 3 589 substCoeff = n_Div(p_GetCoeff(pNext(gCurrent),currRing->cf),p,currRing->cf); 590 d = 1; 591 while (n_DivBy(substCoeff,p,currRing->cf)) 592 { 593 substCoeffCache = n_Div(p_GetCoeff(pNext(gCurrent),currRing->cf),p,currRing->cf); 594 n_Delete(&substCoeff,currRing->cf); 595 substCoeff = substCoeffCache; 596 d++; 597 assume(d>0); // check for overflow 598 } 599 600 // subst = ?*tx 601 subst=p_LmInit(pNext(gCurrent),currRing); 602 // subst = ?*t4x 603 p_AddExp(subst,1,d,currRing); 604 // subst = 4*t4x 605 p_SetCoeff(subst,substCoeffCache,currRing); 606 p_Setm(subst,currRing); pTest(subst); 607 608 // g = g - pNext(gCurrent) + subst 609 pNext(gCurrent)=p_LmDeleteAndNext(pNext(gCurrent),currRing); 610 pNext(gCurrent)=p_Add_q(pNext(gCurrent),subst,currRing); 611 pTest(pNext(gCurrent)); 612 } 613 614 // either way, add monomial in x with minimal t to done 615 pNext(doneEnd)=p_LmInit(pNext(gCurrent),currRing); 616 pIter(doneEnd); 617 p_SetCoeff(doneEnd,n_Init(1,currRing->cf),currRing); 618 p_Setm(doneEnd,currRing); 619 } 620 pIter(gCurrent); 621 } 622 p_Delete(&done,currRing); 623 } 624 625 626 #ifndef NDEBUG 627 BOOLEAN divideByGcd(leftv res, leftv args) 628 { 629 leftv u = args; 630 if ((u != NULL) && (u->Typ() == POLY_CMD)) 631 { 632 poly g; 633 omUpdateInfo(); 634 Print("usedBytes1=%ld\n",om_Info.UsedBytes); 635 g = (poly) u->CopyD(); 636 divideByGcd(g); 637 p_Delete(&g,currRing); 638 omUpdateInfo(); 639 Print("usedBytes1=%ld\n",om_Info.UsedBytes); 640 res->rtyp = NONE; 641 res->data = NULL; 642 return FALSE; 643 } 644 return TRUE; 645 } 646 #endif //NDEBUG 647 648 649 BOOLEAN initialReduction(leftv res, leftv args) 650 { 651 leftv u = args; 652 if ((u != NULL) && (u->Typ() == IDEAL_CMD)) 653 { 654 leftv v = u->next; 655 if (v == NULL) 656 { 657 ideal I = (ideal) u->Data(); 658 659 /*** 660 * Suppose I=g_0,...,g_n and g_0=p-t. 661 * Step 1: sort elements g_1,...,g_{n-1} such that lm(g_1)>...>lm(g_{n-1}) 662 * (the following algorithm is a bubble sort) 663 **/ 664 sortingLaterGenerators(I); 665 666 /*** 667 * Step 2: replace coefficient of terms of lowest t-degree divisible by p with t 668 **/ 669 number p = p_GetCoeff(I->m[0],currRing); 670 for (int i=1; i<IDELEMS(I); i++) 671 { 672 if (preduce(I->m[i],p)) 673 return TRUE; 674 } 675 676 /*** 677 * Step 3: the first pass. removing terms with the same monomials in x as lt(g_i) 678 * out of g_j for i<j 679 **/ 680 int i,j; 681 poly uniti, unitj; 682 for (i=1; i<IDELEMS(I)-1; i++) 683 { 684 for (j=i+1; j<IDELEMS(I); j++) 685 { 686 unitj = highestMatchingX(I->m[j],I->m[i]); 687 if (unitj) 688 { 689 unitj = powerSeriesCoeff(unitj); 690 divideByT(unitj,p_GetExp(I->m[i],1,currRing)); 691 uniti = powerSeriesCoeff(I->m[i]); 692 divideByT(uniti,p_GetExp(I->m[i],1,currRing)); 693 pTest(unitj); pTest(uniti); pTest(I->m[j]); pTest(I->m[i]); 694 I->m[j]=p_Add_q(p_Mult_q(uniti,I->m[j],currRing), 695 p_Neg(p_Mult_q(unitj,p_Copy(I->m[i],currRing),currRing),currRing), 696 currRing); 697 divideByGcd(I->m[j]); 698 } 699 } 700 } 701 for (int i=1; i<IDELEMS(I); i++) 702 { 703 if (preduce(I->m[i],p)) 704 return TRUE; 705 } 706 707 /*** 708 * Step 4: the second pass. removing terms divisible by lt(g_j) out of g_i for i<j 709 **/ 710 for (i=1; i<IDELEMS(I)-1; i++) 711 { 712 for (j=i+1; j<IDELEMS(I); j++) 713 { 714 uniti = highestMatchingX(I->m[i],I->m[j]); 715 if (uniti && p_GetExp(uniti,1,currRing)>=p_GetExp(I->m[j],1,currRing)) 716 { 717 uniti = powerSeriesCoeff(uniti); 718 divideByT(uniti,p_GetExp(I->m[j],1,currRing)); 719 unitj = powerSeriesCoeff(I->m[j]); 720 divideByT(unitj,p_GetExp(I->m[j],1,currRing)); 721 I->m[i] = p_Add_q(p_Mult_q(unitj,I->m[i],currRing), 722 p_Neg(p_Mult_q(uniti,p_Copy(I->m[j],currRing),currRing),currRing), 723 currRing); 724 divideByGcd(I->m[j]); 725 } 726 } 727 } 728 for (int i=1; i<IDELEMS(I); i++) 729 { 730 if (preduce(I->m[i],p)) 731 return TRUE; 732 } 733 734 res->rtyp = NONE; 735 res->data = NULL; 736 IDDATA((idhdl)u->data) = (char*) I; 737 return FALSE; 738 } 739 } 740 WerrorS("initialReduction: unexpected parameters"); 741 return TRUE; 742 } 743 744 745 #if 0 746 /*** 747 * Given a general ring r with any ordering, 748 * changes the ordering to a(v),ws(-w) 749 **/ 750 bool changetoAWSRing(ring r, gfan::ZVector v, gfan::ZVector w) 751 { 752 omFree(r->order); 753 r->order = (int*) omAlloc0(4*sizeof(int)); 754 omFree(r->block0); 755 r->block0 = (int*) omAlloc0(4*sizeof(int)); 756 omFree(r->block1); 757 r->block1 = (int*) omAlloc0(4*sizeof(int)); 758 for (int i=0; r->wvhdl[i]; i++) 759 { omFree(r->wvhdl[i]); } 760 omFree(r->wvhdl); 761 r->wvhdl = (int**) omAlloc0(4*sizeof(int*)); 762 763 bool ok = false; 764 r->order[0] = ringorder_a; 765 r->block0[0] = 1; 766 r->block1[0] = r->N; 767 r->wvhdl[0] = ZVectorToIntStar(v,ok); 768 r->order[1] = ringorder_ws; 769 r->block0[1] = 1; 770 r->block1[1] = r->N; 771 r->wvhdl[1] = ZVectorToIntStar(w,ok); 772 r->order[2]=ringorder_C; 773 return ok; 774 } 775 776 777 /*** 778 * Given a ring with ordering a(v'),ws(w'), 779 * changes the weights to v,w 780 **/ 781 bool changeAWSWeights(ring r, gfan::ZVector v, gfan::ZVector w) 782 { 783 omFree(r->wvhdl[0]); 784 omFree(r->wvhdl[1]); 785 bool ok = false; 786 r->wvhdl[0] = ZVectorToIntStar(v,ok); 787 r->wvhdl[1] = ZVectorToIntStar(w,ok); 788 return ok; 789 } 790 791 792 // /*** 793 // * Creates an int* representing the transposition of the last two variables 794 // **/ 795 // static inline int* createPermutationVectorForSaturation(static const ring &r) 796 // { 797 // int* w = (int*) omAlloc0((rVar(r)+1)*sizeof(int)); 798 // for (int i=1; i<=rVar(r)-2; i++) 799 // w[i] = i; 800 // w[rVar(r)-1] = rVar(r); 801 // w[rVar(r)] = rVar(r)-1; 802 // } 803 804 805 /*** 806 * Creates an int* representing the permutation 807 * 1 -> 1, ..., i-1 -> i-1, i -> n, i+1 -> n-1, ... , n -> i 808 **/ 809 static inline int* createPermutationVectorForSaturation(const ring &r, const int i) 810 { 811 int* sigma = (int*) omAlloc0((rVar(r)+1)*sizeof(int)); 812 int j; 813 for (j=1; j<i; j++) 814 sigma[j] = j; 815 for (; j<=rVar(r); j++) 816 sigma[j] = rVar(r)-j+i; 817 return(sigma); 818 } 819 820 821 /*** 822 * Changes the int* representing the permutation 823 * 1 -> 1, ..., i -> i, i+1 -> n, i+2 -> n-1, ... , n -> i+1 824 * to an int* representing the permutation 825 * 1 -> 1, ..., i-1 -> i-1, i -> n, i+1 -> n-1, ... , n -> i 826 **/ 827 static void changePermutationVectorForSaturation(int* sigma, const ring &r, const int i) 828 { 829 for (int j=i; j<rVar(r); j++) 830 sigma[j] = rVar(r)-j+i; 831 sigma[rVar(r)] = i; 832 } 833 834 835 /*** 836 * returns a ring in which the weights of the ring variables are permuted 837 * if handed over a poly in which the variables are permuted, this is basically 838 * as good as permuting the variables of the ring itself. 839 **/ 840 static ring permuteWeighstOfRingVariables(const ring &r, const int* const sigma) 841 { 842 ring s = rCopy0(r); 843 for (int j=0; j<rVar(r); j++) 844 { 845 s->wvhdl[0][j] = r->wvhdl[0][sigma[j+1]]; 846 s->wvhdl[1][j] = r->wvhdl[1][sigma[j+1]]; 847 } 848 rComplete(s,1); 849 return s; 850 } 851 852 853 /*** 854 * creates a ring s that is a copy of r except with ordering wp(w) 855 **/ 856 static inline ring createInitialRingForSaturation(const ring &r, const gfan::ZVector &w, bool &ok) 857 { 858 assume(rVar(r) == (int) w.size()); 859 860 ring s = rCopy0(r); int i; 861 for (i=0; s->order[i]; i++) 862 omFreeSize(s->wvhdl[i],rVar(r)*sizeof(int)); 863 i++; 864 omFreeSize(s->order,i*sizeof(int)); 865 s->order = (int*) omAlloc0(3*sizeof(int)); 866 omFreeSize(s->block0,i*sizeof(int)); 867 s->block0 = (int*) omAlloc0(3*sizeof(int)); 868 omFreeSize(s->block1,i*sizeof(int)); 869 s->block1 = (int*) omAlloc0(3*sizeof(int)); 870 omFreeSize(s->wvhdl,i*sizeof(int*)); 871 s->wvhdl = (int**) omAlloc0(3*sizeof(int*)); 872 873 s->order[0] = ringorder_wp; 874 s->block0[0] = 1; 875 s->block1[0] = rVar(r); 876 s->wvhdl[0] = ZVectorToIntStar(w,ok); 877 s->order[1]=ringorder_C; 878 879 rComplete(s,1); 880 return s; 881 } 882 883 884 /*** 885 * Given an weighted homogeneous ideal I with respect to weight w 886 * that in standard basis form with respect to the ordering ws(-w), 887 * derives the standard basis of I:<x_n>^\infty 888 * and returns a long k such that I:<x_n>^\infty=I:<x_n>^k 889 **/ 890 static long deriveStandardBasisOfSaturation(ideal &I, ring &r) 891 { 892 long k=0, l; poly current; 893 for (int i=0; i<IDELEMS(I); i++) 894 { 895 current = I->m[i]; 896 l = p_GetExp(current,rVar(r),r); 897 if (k<l) k=l; 898 while (current) 899 { 900 p_SubExp(current,rVar(r),l,r); p_Setm(current,r); 901 pIter(current); 902 } 903 } 904 return k; 905 } 906 907 908 /*** 909 * Given a weighted homogeneous ideal I with respect to weight w 910 * with constant first element, 911 * returns NULL if I does not contain a monomial 912 * otherwise returns the monomial contained in I 913 **/ 914 poly containsMonomial(const ideal &I, const gfan::ZVector &w) 915 { 916 assume(rField_is_Ring_Z(currRing)); 917 918 // first we switch to the ground field currRing->cf / I->m[0] 919 ring r = rCopy0(currRing); 920 nKillChar(r->cf); 921 r->cf = nInitChar(n_Zp,(void*)(long)n_Int(p_GetCoeff(I->m[0],currRing),currRing->cf)); 922 rComplete(r); 923 924 ideal J = id_Copy(I, currRing); poly cache; number temp; 925 for (int i=0; i<IDELEMS(I); i++) 926 { 927 cache = J->m[i]; 928 while (cache) 929 { 930 // TODO: temp = npMapGMP(p_GetCoeff(cache,currRing),currRing->cf,r->cf); 931 p_SetCoeff(cache,temp,r); pIter(cache); 932 } 933 } 934 935 936 J = kStd(J,NULL,isHomog,NULL); 937 938 bool b = false; 939 ring s = createInitialRingForSaturation(currRing, w, b); 940 if (b) 941 { 942 WerrorS("containsMonomial: overflow in weight vector"); 943 return NULL; 944 } 945 946 return NULL; 947 } 948 949 950 gfan::ZCone* startingCone(ideal I) 951 { 952 I = kStd(I,NULL,isNotHomog,NULL); 953 gfan::ZCone* zc = maximalGroebnerCone(currRing,I); 954 gfan::ZMatrix rays = zc->extremeRays(); 955 gfan::ZVector v; 956 for (int i=0; i<rays.getHeight(); i++) 957 { 958 v = rays[i]; 959 } 960 return zc; 961 } 962 #endif 197 963 198 964 … … 202 968 p->iiAddCproc("","maximalGroebnerCone",FALSE,maximalGroebnerCone); 203 969 p->iiAddCproc("","initial",FALSE,initial); 970 #ifndef NDEBUG 971 p->iiAddCproc("","divideByGcd",FALSE,divideByGcd); 972 p->iiAddCproc("","preduce",FALSE,preduce); 973 #endif //NDEBUG 974 p->iiAddCproc("","initialReduction",FALSE,initialReduction); 204 975 p->iiAddCproc("","homogeneitySpace",FALSE,homogeneitySpace); 205 976 }
Note: See TracChangeset
for help on using the changeset viewer.