source: git/kernel/kspoly.cc @ 762407

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