source: git/kernel/kspoly.cc @ f92547

spielwiese
Last change on this file since f92547 was f92547, checked in by Oliver Wienand <wienand@…>, 18 years ago
*oliver kspoly.cc: --> kscheckcoef * modified for zero divisors --> ksCreateShortSPoly * create correct short s poly for rings * in case of rings, also calculate coeff kstd2.cc: --> bba * use different enterpairs method in case of rings * small changes (replaced p_ISet by p_NSet) kutil.cc, kutil.h: --> new enterpairs derivate, also downstreams are new derivates of functions --> function to create extended s poly for rings --> nComp fct, will be nGreater later, maybe --> stub for chainCritRing polys.cc: --> chainCrit correct for rings, but not optimized numbers.cc, rmodulo2m.cc, rmodulo2m.h: --> gcd, ncd for zero divisor (att, not really a gcd or ncd) --> IntDiv (att, just takes a machine div, allows to divide by zero div) --> Greater (att, compares zero divisor exponent) git-svn-id: file:///usr/local/Singular/svn/trunk@9026 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 12.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kspoly.cc,v 1.4 2006-03-20 20:33:56 wienand Exp $ */
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"
16#ifdef HAVE_RING2TOM
17#include "polys.h"
18#endif
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
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
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
68  if (rIsPluralRing(currRing))
69  {
70    // for the time being: we know currRing==strat->tailRing
71    // no exp-bound checking needed
72    // (only needed if exp-bound(tailring)<exp-b(currRing))
73    number c;
74    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,&c);
75    else 
76    {
77      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
78      assume(_p != NULL);
79      nc_PolyPolyRed(_p, p2,&c);
80      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
81      PR->pLength=pLength(_p);
82    }
83    if (coef!=NULL) *coef=c;
84    else nDelete(&c);
85    return 0;
86  }
87
88  if (t2==NULL)           // Divisor is just one term, therefore it will
89  {                       // just cancel the leading term
90    PR->LmDeleteAndIter();
91    if (coef != NULL) *coef = n_Init(1, tailRing);
92    return 0;
93  }
94
95  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
96
97  if (tailRing != currRing)
98  {
99    // check that reduction does not violate exp bound
100    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
101    {
102      // undo changes of lm
103      p_ExpVectorAdd(lm, p2, tailRing);
104      if (strat == NULL) return 2;
105      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
106      tailRing = strat->tailRing;
107      p1 = PR->GetLmTailRing();
108      p2 = PW->GetLmTailRing();
109      t2 = pNext(p2);
110      lm = p1;
111      p_ExpVectorSub(lm, p2, tailRing);
112      ret = 1;
113    }
114  }
115
116  // take care of coef buisness
117  if (! n_IsOne(pGetCoeff(p2), tailRing))
118  {
119    number bn = pGetCoeff(lm);
120    number an = pGetCoeff(p2);
121    int ct = ksCheckCoeff(&an, &bn);    // Calculate special LC
122    p_SetCoeff(lm, bn, tailRing);
123    if ((ct == 0) || (ct == 2))
124      PR->Tail_Mult_nn(an);
125    if (coef != NULL) *coef = an;
126    else n_Delete(&an, tailRing);
127  }
128  else
129  {
130    if (coef != NULL) *coef = n_Init(1, tailRing);
131  }
132
133
134  // and finally,
135  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
136  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
137  PR->LmDeleteAndIter();
138#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
139  if (TEST_OPT_DEBUG)
140  {
141    Print(" to: "); PR->wrp(); Print("\n");
142  }
143#endif
144  return ret;
145}
146
147/***************************************************************
148 *
149 * Creates S-Poly of p1 and p2
150 *
151 *
152 ***************************************************************/
153void ksCreateSpoly(LObject* Pair,   poly spNoether,
154                   int use_buckets, ring tailRing,
155                   poly m1, poly m2, TObject** R)
156{
157#ifdef KDEBUG
158  create_count++;
159#endif
160  kTest_L(Pair);
161  poly p1 = Pair->p1;
162  poly p2 = Pair->p2;
163  poly last;
164  Pair->tailRing = tailRing;
165
166  assume(p1 != NULL);
167  assume(p2 != NULL);
168  assume(tailRing != NULL);
169
170  poly a1 = pNext(p1), a2 = pNext(p2);
171  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
172  int co=0, ct = ksCheckCoeff(&lc1, &lc2); // gcd and zero divisors
173
174  int l1=0, l2=0;
175
176  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
177  {
178    if (p_GetComp(p1, currRing)==0)
179    {
180      co=1;
181      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
182    }
183    else
184    {
185      co=2;
186      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
187    }
188  }
189
190  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
191  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
192  if (m1 == NULL)
193    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
194
195  pSetCoeff0(m1, lc2);
196  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
197
198  if (R != NULL)
199  {
200    l1 = (R[Pair->i_r1])->GetpLength() - 1;
201    l2 = (R[Pair->i_r2])->GetpLength() - 1;
202  }
203
204  // get m2 * a2
205  if (spNoether != NULL)
206  {
207    l2 = -1;
208    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
209    assume(l2 == pLength(a2));
210  }
211  else
212    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
213#ifdef HAVE_RING2TOM
214  if (currRing->cring == 1) l2 = pLength(a2);
215#endif
216
217  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
218
219  // get m2*a2 - m1*a1
220  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
221
222  // Clean-up time
223  Pair->LmDeleteAndIter();
224  p_LmDelete(m1, tailRing);
225
226  if (co != 0)
227  {
228    if (co==1)
229    {
230      p_SetCompP(p1,0, currRing, tailRing);
231    }
232    else
233    {
234      p_SetCompP(p2,0, currRing, tailRing);
235    }
236  }
237}
238
239int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
240{
241  BOOLEAN ret;
242  number coef;
243  poly Lp =     PR->GetLmCurrRing();
244  poly Save =   PW->GetLmCurrRing();
245
246  kTest_L(PR);
247  kTest_T(PW);
248  pAssume(pIsMonomOf(Lp, Current));
249
250  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
251  assume(PR->bucket == NULL);
252
253  LObject Red(pNext(Current), PR->tailRing);
254  TObject With(PW, Lp == Save);
255
256  pAssume(!pHaveCommonMonoms(Red.p, With.p));
257  ret = ksReducePoly(&Red, &With, spNoether, &coef);
258
259  if (!ret)
260  {
261    if (! n_IsOne(coef, currRing))
262    {
263      pNext(Current) = NULL;
264      if (Current == PR->p && PR->t_p != NULL)
265        pNext(PR->t_p) = NULL;
266      PR->Mult_nn(coef);
267    }
268
269    n_Delete(&coef, currRing);
270    pNext(Current) = Red.GetLmTailRing();
271    if (Current == PR->p && PR->t_p != NULL)
272      pNext(PR->t_p) = pNext(Current);
273  }
274
275  if (Lp == Save)
276    With.Delete();
277  return ret;
278}
279
280/***************************************************************
281 *
282 * Auxillary Routines
283 *
284 *
285 ***************************************************************/
286
287/*
288* input - output: a, b
289* returns:
290*   a := a/gcd(a,b), b := b/gcd(a,b)
291*   and return value
292*       0  ->  a != 1,  b != 1
293*       1  ->  a == 1,  b != 1
294*       2  ->  a != 1,  b == 1
295*       3  ->  a == 1,  b == 1
296*   this value is used to control the spolys
297*/
298int ksCheckCoeff(number *a, number *b)
299{
300  int c = 0;
301  number an = *a, bn = *b;
302  nTest(an);
303  nTest(bn);
304
305  number cn = nGcd(an, bn, currRing);
306
307  if(nIsOne(cn))
308  {
309    an = nCopy(an);
310    bn = nCopy(bn);
311  }
312  else
313  {
314    an = nIntDiv(an, cn);
315    bn = nIntDiv(bn, cn);
316  }
317  nDelete(&cn);
318  if (nIsOne(an))
319  {
320    c = 1;
321  }
322  if (nIsOne(bn))
323  {
324    c += 2;
325  }
326  *a = an;
327  *b = bn;
328  return c;
329}
330
331/*2
332* creates the leading term of the S-polynomial of p1 and p2
333* do not destroy p1 and p2
334* remarks:
335*   1. the coefficient is 0 (nNew)
336*   1. a) in the case of coefficient ring, the coefficient is calculated
337*   2. pNext is undefined
338*/
339//static void bbb() { int i=0; }
340poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
341{
342  poly a1 = pNext(p1), a2 = pNext(p2);
343  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
344  Exponent_t c;
345  poly m1,m2;
346  number t1,t2;
347  int cm,i;
348  BOOLEAN equal;
349
350#ifdef HAVE_RING2TOM
351  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
352  int ct = ksCheckCoeff(&lc1, &lc2); // gcd and zero divisors
353  if (currRing->cring == 1)
354  {
355    if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
356    if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
357    while (a1 != NULL && nIsZero(t2))
358    {
359      pIter(a1);
360      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
361    }
362    while (a2 != NULL && nIsZero(t1))
363    {
364      pIter(a2);
365      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
366    }
367  }
368#endif
369
370  if (a1==NULL)
371  {
372    if(a2!=NULL)
373    {
374      m2=p_Init(currRing);
375x2:
376      for (i = pVariables; i; i--)
377      {
378        c = p_GetExpDiff(p1, p2,i, currRing);
379        if (c>0)
380        {
381          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
382        }
383        else
384        {
385          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
386        }
387      }
388      if ((c1==c2)||(c2!=0))
389      {
390        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
391      }
392      else
393      {
394        p_SetComp(m2,c1,currRing);
395      }
396      p_Setm(m2, currRing);
397#ifdef HAVE_RING2TOM
398      if (currRing->cring == 1)
399          pSetCoeff(m2, t1);
400      else
401#endif
402        nNew(&(pGetCoeff(m2)));
403      return m2;
404    }
405    else
406      return NULL;
407  }
408  if (a2==NULL)
409  {
410    m1=p_Init(currRing);
411x1:
412    for (i = pVariables; i; i--)
413    {
414      c = p_GetExpDiff(p2, p1,i,currRing);
415      if (c>0)
416      {
417        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
418      }
419      else
420      {
421        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
422      }
423    }
424    if ((c1==c2)||(c1!=0))
425    {
426      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
427    }
428    else
429    {
430      p_SetComp(m1,c2,currRing);
431    }
432    p_Setm(m1, currRing);
433#ifdef HAVE_RING2TOM
434    if (currRing->cring == 1)
435        pSetCoeff(m1, t2);
436    else
437#endif
438      nNew(&(pGetCoeff(m1)));
439    return m1;
440  }
441  m1 = p_Init(currRing);
442  m2 = p_Init(currRing);
443  for(;;)
444  {
445    for (i = pVariables; i; i--)
446    {
447      c = p_GetExpDiff(p1, p2,i,currRing);
448      if (c > 0)
449      {
450        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
451        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
452      }
453      else
454      {
455        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
456        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
457      }
458    }
459    if(c1==c2)
460    {
461      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
462      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
463    }
464    else
465    {
466      if(c1!=0)
467      {
468        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
469        p_SetComp(m2,c1, currRing);
470      }
471      else
472      {
473        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
474        p_SetComp(m1,c2, currRing);
475      }
476    }
477    p_Setm(m1,currRing);
478    p_Setm(m2,currRing);
479    cm = p_LmCmp(m1, m2,currRing);
480    if (cm!=0)
481    {
482      if(cm==1)
483      {
484        p_LmFree(m2,currRing);
485        nNew(&(pGetCoeff(m1)));
486        return m1;
487      }
488      else
489      {
490        p_LmFree(m1,currRing);
491        nNew(&(pGetCoeff(m2)));
492        return m2;
493      }
494    }
495#ifdef HAVE_RING2TOM
496    if (currRing->cring == 1)
497    {
498      t1 = nAdd(t1, t2);
499      equal = nIsZero(t1);
500      nDelete(&t2);
501    }
502    else
503#endif
504    {
505      t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
506      t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
507      equal = nEqual(t1,t2);
508      nDelete(&t2);
509      nDelete(&t1);
510    }
511    if (!equal)
512    {
513      p_LmFree(m2,currRing);
514#ifdef HAVE_RING2TOM
515      if (currRing->cring == 1)
516          pSetCoeff(m1, t1);
517      else
518#endif
519        nNew(&(pGetCoeff(m1)));
520      return m1;
521    }
522    pIter(a1);
523    pIter(a2);
524#ifdef HAVE_RING2TOM
525    if (currRing->cring == 1)
526    {
527      nDelete(&t1);
528      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
529      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
530      while (a1 != NULL && nIsZero(t2))
531      {
532        pIter(a1);
533        if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
534      }
535      while (a2 != NULL && nIsZero(t1))
536      {
537        pIter(a2);
538        if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
539      }
540    }
541#endif
542    if (a2==NULL)
543    {
544      p_LmFree(m2,currRing);
545      if (a1==NULL)
546      {
547        p_LmFree(m1,currRing);
548        return NULL;
549      }
550      goto x1;
551    }
552    if (a1==NULL)
553    {
554      p_LmFree(m1,currRing);
555      goto x2;
556    }
557  }
558}
Note: See TracBrowser for help on using the repository browser.