source: git/kernel/kspoly.cc @ 51e69e

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