source: git/kernel/kspoly.cc @ 725ef18

spielwiese
Last change on this file since 725ef18 was 725ef18, checked in by Hans Schönemann <hannes@…>, 14 years ago
reactivate TEST_OPT_DEBUG_RED git-svn-id: file:///usr/local/Singular/svn/trunk@12359 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 14.8 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[341696]4/* $Id$ */
[35aab3]5/*
6*  ABSTRACT -  Routines for Spoly creation and reductions
7*/
8
9// #define PDEBUG 2
10#include "mod2.h"
11#include "kutil.h"
12#include "numbers.h"
13#include "p_polys.h"
14#include "p_Procs.h"
15#include "gring.h"
[725ef18]16#ifdef KDEBUG
17#include "febase.h"
18#endif
[206e158]19#ifdef HAVE_RINGS
[f92547]20#include "polys.h"
21#endif
[35aab3]22
23#ifdef KDEBUG
24int red_count = 0;
25int create_count = 0;
26// define this if reductions are reported on TEST_OPT_DEBUG
[725ef18]27//#define TEST_OPT_DEBUG_RED
[35aab3]28#endif
29
30/***************************************************************
31 *
32 * Reduces PR with PW
33 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
34 *
35 ***************************************************************/
36int ksReducePoly(LObject* PR,
37                 TObject* PW,
38                 poly spNoether,
39                 number *coef,
40                 kStrategy strat)
41{
42#ifdef KDEBUG
43  red_count++;
44#ifdef TEST_OPT_DEBUG_RED
45  if (TEST_OPT_DEBUG)
46  {
47    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
48    PW->wrp();
49  }
50#endif
51#endif
52  int ret = 0;
53  ring tailRing = PR->tailRing;
54  kTest_L(PR);
55  kTest_T(PW);
56
[cea6f3]57  poly p1 = PR->GetLmTailRing();   // p2 | p1
58  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
59  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
60  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
[35aab3]61  p_CheckPolyRing(p1, tailRing);
62  p_CheckPolyRing(p2, tailRing);
63
64  pAssume1(p2 != NULL && p1 != NULL &&
65           p_DivisibleBy(p2,  p1, tailRing));
66
67  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
68           (p_GetComp(p2, tailRing) == 0 &&
69            p_MaxComp(pNext(p2),tailRing) == 0));
70
[d60626]71#ifdef HAVE_PLURAL
[35aab3]72  if (rIsPluralRing(currRing))
73  {
74    // for the time being: we know currRing==strat->tailRing
75    // no exp-bound checking needed
76    // (only needed if exp-bound(tailring)<exp-b(currRing))
77    number c;
[19370c]78    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,&c);
[35aab3]79    else 
80    {
81      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
82      assume(_p != NULL);
83      nc_PolyPolyRed(_p, p2,&c);
84      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
85      PR->pLength=pLength(_p);
86    }
87    if (coef!=NULL) *coef=c;
88    else nDelete(&c);
89    return 0;
90  }
[d60626]91#endif
[35aab3]92
[cea6f3]93  if (t2==NULL)           // Divisor is just one term, therefore it will
94  {                       // just cancel the leading term
[585bbcb]95    PR->LmDeleteAndIter();
96    if (coef != NULL) *coef = n_Init(1, tailRing);
97    return 0;
98  }
99
[cea6f3]100  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
[585bbcb]101
102  if (tailRing != currRing)
103  {
104    // check that reduction does not violate exp bound
105    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
106    {
107      // undo changes of lm
108      p_ExpVectorAdd(lm, p2, tailRing);
109      if (strat == NULL) return 2;
110      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
111      tailRing = strat->tailRing;
112      p1 = PR->GetLmTailRing();
113      p2 = PW->GetLmTailRing();
114      t2 = pNext(p2);
115      lm = p1;
116      p_ExpVectorSub(lm, p2, tailRing);
117      ret = 1;
118    }
119  }
120
121  // take care of coef buisness
122  if (! n_IsOne(pGetCoeff(p2), tailRing))
123  {
124    number bn = pGetCoeff(lm);
125    number an = pGetCoeff(p2);
[cea6f3]126    int ct = ksCheckCoeff(&an, &bn);    // Calculate special LC
127    p_SetCoeff(lm, bn, tailRing);
[585bbcb]128    if ((ct == 0) || (ct == 2))
129      PR->Tail_Mult_nn(an);
130    if (coef != NULL) *coef = an;
131    else n_Delete(&an, tailRing);
132  }
133  else
134  {
135    if (coef != NULL) *coef = n_Init(1, tailRing);
136  }
137
138
139  // and finally,
140  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
[cea6f3]141  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
[585bbcb]142  PR->LmDeleteAndIter();
[9f5fca]143
144  // the following is commented out: shrinking
145#ifdef HAVE_SHIFTBBA_NONEXISTENT
146  if ( (currRing->isLPring) && (!strat->homog) )
147  {
148    // assume? h->p in currRing
149    PR->GetP();
150    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
151    PR->Clear(); // does the right things
152    PR->p = qq; 
153    PR->t_p = NULL;
154    PR->SetShortExpVector();
155  }
156#endif
157 
[585bbcb]158#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
159  if (TEST_OPT_DEBUG)
160  {
161    Print(" to: "); PR->wrp(); Print("\n");
162  }
163#endif
164  return ret;
165}
166
[35aab3]167/***************************************************************
168 *
169 * Creates S-Poly of p1 and p2
170 *
171 *
172 ***************************************************************/
173void ksCreateSpoly(LObject* Pair,   poly spNoether,
174                   int use_buckets, ring tailRing,
175                   poly m1, poly m2, TObject** R)
176{
177#ifdef KDEBUG
178  create_count++;
179#endif
180  kTest_L(Pair);
181  poly p1 = Pair->p1;
182  poly p2 = Pair->p2;
183  poly last;
184  Pair->tailRing = tailRing;
185
186  assume(p1 != NULL);
187  assume(p2 != NULL);
188  assume(tailRing != NULL);
189
190  poly a1 = pNext(p1), a2 = pNext(p2);
191  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
[cea6f3]192  int co=0, ct = ksCheckCoeff(&lc1, &lc2); // gcd and zero divisors
[35aab3]193
194  int l1=0, l2=0;
195
196  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
197  {
198    if (p_GetComp(p1, currRing)==0)
199    {
200      co=1;
201      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
202    }
203    else
204    {
205      co=2;
206      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
207    }
208  }
209
210  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
211  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
212  if (m1 == NULL)
213    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
214
215  pSetCoeff0(m1, lc2);
216  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
217
218  if (R != NULL)
219  {
[51e69e]220    if (Pair->i_r1 == -1)
221    {
222      l1 = pLength(p1) - 1;
223    }
224    else
225    {
226      l1 = (R[Pair->i_r1])->GetpLength() - 1;
227    }
228    if (Pair->i_r2 == -1)
229    {
230      l2 = pLength(p2) - 1;
231    }
232    else
233    {
234      l2 = (R[Pair->i_r2])->GetpLength() - 1;
235    }
[35aab3]236  }
237
238  // get m2 * a2
239  if (spNoether != NULL)
240  {
241    l2 = -1;
242    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
243    assume(l2 == pLength(a2));
244  }
245  else
246    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
[009d80]247#ifdef HAVE_RINGS
[93ebe1]248  if (!(rField_is_Domain(currRing))) l2 = pLength(a2);
[cea6f3]249#endif
250
[35aab3]251  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
252
253  // get m2*a2 - m1*a1
254  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
255
256  // Clean-up time
257  Pair->LmDeleteAndIter();
258  p_LmDelete(m1, tailRing);
259
260  if (co != 0)
261  {
262    if (co==1)
263    {
264      p_SetCompP(p1,0, currRing, tailRing);
265    }
266    else
267    {
268      p_SetCompP(p2,0, currRing, tailRing);
269    }
270  }
[9f5fca]271
272  // the following is commented out: shrinking
273#ifdef HAVE_SHIFTBBA_NONEXISTENT
274  if (currRing->isLPring)
275  {
276    // assume? h->p in currRing
277    Pair->GetP();
278    poly qq = p_Shrink(Pair->p, currRing->isLPring, currRing);
279    Pair->Clear(); // does the right things
280    Pair->p = qq; 
281    Pair->t_p = NULL;
282    Pair->SetShortExpVector();
283  }
284#endif
285
[35aab3]286}
287
288int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
289{
290  BOOLEAN ret;
291  number coef;
292  poly Lp =     PR->GetLmCurrRing();
293  poly Save =   PW->GetLmCurrRing();
294
295  kTest_L(PR);
296  kTest_T(PW);
297  pAssume(pIsMonomOf(Lp, Current));
298
299  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
300  assume(PR->bucket == NULL);
301
302  LObject Red(pNext(Current), PR->tailRing);
303  TObject With(PW, Lp == Save);
304
305  pAssume(!pHaveCommonMonoms(Red.p, With.p));
306  ret = ksReducePoly(&Red, &With, spNoether, &coef);
307
308  if (!ret)
309  {
310    if (! n_IsOne(coef, currRing))
311    {
312      pNext(Current) = NULL;
313      if (Current == PR->p && PR->t_p != NULL)
314        pNext(PR->t_p) = NULL;
315      PR->Mult_nn(coef);
316    }
317
318    n_Delete(&coef, currRing);
319    pNext(Current) = Red.GetLmTailRing();
320    if (Current == PR->p && PR->t_p != NULL)
321      pNext(PR->t_p) = pNext(Current);
322  }
323
324  if (Lp == Save)
325    With.Delete();
[9f5fca]326
327  // the following is commented out: shrinking
328#ifdef HAVE_SHIFTBBA_NONEXISTENT
329  if (currRing->isLPring)
330  {
331    // assume? h->p in currRing
332    PR->GetP();
333    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
334    PR->Clear(); // does the right things
335    PR->p = qq; 
336    PR->t_p = NULL;
337    PR->SetShortExpVector();
338  }
339#endif
340
[35aab3]341  return ret;
342}
343
344/***************************************************************
345 *
346 * Auxillary Routines
347 *
348 *
349 ***************************************************************/
350
351/*
352* input - output: a, b
353* returns:
354*   a := a/gcd(a,b), b := b/gcd(a,b)
355*   and return value
356*       0  ->  a != 1,  b != 1
357*       1  ->  a == 1,  b != 1
358*       2  ->  a != 1,  b == 1
359*       3  ->  a == 1,  b == 1
360*   this value is used to control the spolys
361*/
362int ksCheckCoeff(number *a, number *b)
363{
364  int c = 0;
365  number an = *a, bn = *b;
366  nTest(an);
367  nTest(bn);
368
369  number cn = nGcd(an, bn, currRing);
370
371  if(nIsOne(cn))
372  {
373    an = nCopy(an);
374    bn = nCopy(bn);
375  }
376  else
377  {
378    an = nIntDiv(an, cn);
379    bn = nIntDiv(bn, cn);
380  }
381  nDelete(&cn);
382  if (nIsOne(an))
383  {
384    c = 1;
385  }
386  if (nIsOne(bn))
387  {
388    c += 2;
389  }
390  *a = an;
391  *b = bn;
392  return c;
393}
394
395/*2
396* creates the leading term of the S-polynomial of p1 and p2
397* do not destroy p1 and p2
398* remarks:
399*   1. the coefficient is 0 (nNew)
[f92547]400*   1. a) in the case of coefficient ring, the coefficient is calculated
[35aab3]401*   2. pNext is undefined
402*/
403//static void bbb() { int i=0; }
404poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
405{
406  poly a1 = pNext(p1), a2 = pNext(p2);
407  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
408  Exponent_t c;
409  poly m1,m2;
[a539ad]410  number t1 = NULL,t2 = NULL;
[35aab3]411  int cm,i;
412  BOOLEAN equal;
413
[009d80]414#ifdef HAVE_RINGS
[93ebe1]415  BOOLEAN is_Ring=rField_is_Ring(currRing);
[f92547]416  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
[93ebe1]417  if (is_Ring)
[f92547]418  {
[a539ad]419    ksCheckCoeff(&lc1, &lc2); // gcd and zero divisors
[f92547]420    if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
421    if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
422    while (a1 != NULL && nIsZero(t2))
423    {
424      pIter(a1);
[a539ad]425      nDelete(&t2);
[f92547]426      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
427    }
428    while (a2 != NULL && nIsZero(t1))
429    {
430      pIter(a2);
[a539ad]431      nDelete(&t1);
[f92547]432      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
433    }
434  }
435#endif
436
[35aab3]437  if (a1==NULL)
438  {
439    if(a2!=NULL)
440    {
441      m2=p_Init(currRing);
442x2:
443      for (i = pVariables; i; i--)
444      {
445        c = p_GetExpDiff(p1, p2,i, currRing);
446        if (c>0)
447        {
448          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
449        }
450        else
451        {
452          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
453        }
454      }
455      if ((c1==c2)||(c2!=0))
456      {
457        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
458      }
459      else
460      {
461        p_SetComp(m2,c1,currRing);
462      }
463      p_Setm(m2, currRing);
[009d80]464#ifdef HAVE_RINGS
[93ebe1]465      if (is_Ring)
[a539ad]466      {
467          nDelete(&lc1);
468          nDelete(&lc2);
469          nDelete(&t2);
[bac8611]470          pSetCoeff0(m2, t1);
[a539ad]471      }
[f92547]472      else
473#endif
474        nNew(&(pGetCoeff(m2)));
[35aab3]475      return m2;
476    }
477    else
[a539ad]478    {
479#ifdef HAVE_RINGS
[725ef18]480      if (is_Ring)
481      {
482        nDelete(&lc1);
483        nDelete(&lc2);
484        nDelete(&t1);
485        nDelete(&t2);
486      }
[a539ad]487#endif
[35aab3]488      return NULL;
[a539ad]489    }
[35aab3]490  }
491  if (a2==NULL)
492  {
493    m1=p_Init(currRing);
494x1:
495    for (i = pVariables; i; i--)
496    {
497      c = p_GetExpDiff(p2, p1,i,currRing);
498      if (c>0)
499      {
500        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
501      }
502      else
503      {
504        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
505      }
506    }
507    if ((c1==c2)||(c1!=0))
508    {
509      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
510    }
511    else
512    {
513      p_SetComp(m1,c2,currRing);
514    }
515    p_Setm(m1, currRing);
[009d80]516#ifdef HAVE_RINGS
[93ebe1]517    if (is_Ring)
[a539ad]518    {
519      pSetCoeff0(m1, t2);
520      nDelete(&lc1);
521      nDelete(&lc2);
522      nDelete(&t1);
523    }
[f92547]524    else
525#endif
526      nNew(&(pGetCoeff(m1)));
[35aab3]527    return m1;
528  }
529  m1 = p_Init(currRing);
530  m2 = p_Init(currRing);
[725ef18]531  loop
[35aab3]532  {
533    for (i = pVariables; i; i--)
534    {
535      c = p_GetExpDiff(p1, p2,i,currRing);
536      if (c > 0)
537      {
538        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
539        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
540      }
541      else
542      {
543        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
544        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
545      }
546    }
547    if(c1==c2)
548    {
549      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
550      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
551    }
552    else
553    {
554      if(c1!=0)
555      {
556        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
557        p_SetComp(m2,c1, currRing);
558      }
559      else
560      {
561        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
562        p_SetComp(m1,c2, currRing);
563      }
564    }
565    p_Setm(m1,currRing);
566    p_Setm(m2,currRing);
567    cm = p_LmCmp(m1, m2,currRing);
568    if (cm!=0)
569    {
570      if(cm==1)
571      {
572        p_LmFree(m2,currRing);
[009d80]573#ifdef HAVE_RINGS
[93ebe1]574        if (is_Ring)
[a539ad]575        {
[bac8611]576          pSetCoeff0(m1, t2);
[a539ad]577          nDelete(&lc1);
578          nDelete(&lc2);
579          nDelete(&t1);
580        }
[e6cbed]581        else
582#endif
583          nNew(&(pGetCoeff(m1)));
[35aab3]584        return m1;
585      }
586      else
587      {
588        p_LmFree(m1,currRing);
[009d80]589#ifdef HAVE_RINGS
[93ebe1]590        if (is_Ring)
[a539ad]591        {
592          pSetCoeff0(m2, t1);
593          nDelete(&lc1);
594          nDelete(&lc2);
595          nDelete(&t2);
596        }
[e6cbed]597        else
598#endif
599          nNew(&(pGetCoeff(m2)));
[35aab3]600        return m2;
601      }
602    }
[009d80]603#ifdef HAVE_RINGS
[93ebe1]604    if (is_Ring)
[f92547]605    {
[a539ad]606      equal = nEqual(t1,t2);
[f92547]607    }
608    else
609#endif
610    {
611      t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
612      t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
613      equal = nEqual(t1,t2);
614      nDelete(&t2);
615      nDelete(&t1);
616    }
[35aab3]617    if (!equal)
618    {
619      p_LmFree(m2,currRing);
[009d80]620#ifdef HAVE_RINGS
[93ebe1]621      if (is_Ring)
[a539ad]622      {
623          pSetCoeff0(m1, nSub(t1, t2));
624          nDelete(&lc1);
625          nDelete(&lc2);
626          nDelete(&t1);
627          nDelete(&t2);
628      }
[f92547]629      else
630#endif
631        nNew(&(pGetCoeff(m1)));
[35aab3]632      return m1;
633    }
634    pIter(a1);
635    pIter(a2);
[009d80]636#ifdef HAVE_RINGS
[93ebe1]637    if (is_Ring)
[f92547]638    {
[a539ad]639      if (a2 != NULL)
640      {
641        nDelete(&t1);
642        t1 = nMult(pGetCoeff(a2),lc1);
643      }
644      if (a1 != NULL)
645      {
646        nDelete(&t2);
647        t2 = nMult(pGetCoeff(a1),lc2);
648      }
[93ebe1]649      while ((a1 != NULL) && nIsZero(t2))
[f92547]650      {
651        pIter(a1);
[a539ad]652        if (a1 != NULL)
653        {
654          nDelete(&t2);
655          t2 = nMult(pGetCoeff(a1),lc2);
656        }
[f92547]657      }
[93ebe1]658      while ((a2 != NULL) && nIsZero(t1))
[f92547]659      {
660        pIter(a2);
[a539ad]661        if (a2 != NULL)
662        {
663          nDelete(&t1);
664          t1 = nMult(pGetCoeff(a2),lc1);
665        }
[f92547]666      }
667    }
668#endif
[35aab3]669    if (a2==NULL)
670    {
671      p_LmFree(m2,currRing);
672      if (a1==NULL)
673      {
[a539ad]674#ifdef HAVE_RINGS
[93ebe1]675        if (is_Ring)
[a539ad]676        {
677          nDelete(&lc1);
678          nDelete(&lc2);
679          nDelete(&t1);
680          nDelete(&t2);
681        }
682#endif
[35aab3]683        p_LmFree(m1,currRing);
684        return NULL;
685      }
686      goto x1;
687    }
688    if (a1==NULL)
689    {
690      p_LmFree(m1,currRing);
691      goto x2;
692    }
693  }
694}
Note: See TracBrowser for help on using the repository browser.