source: git/Singular/kspoly.cc @ 110345

fieker-DuValspielwiese
Last change on this file since 110345 was 3b1a83c, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: dagstuhl improvements git-svn-id: file:///usr/local/Singular/svn/trunk@5653 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.8 KB
RevLine 
[d14712]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[3b1a83c]4/* $Id: kspoly.cc,v 1.26 2001-10-23 14:04:23 Singular Exp $ */
[d14712]5/*
6*  ABSTRACT -  Routines for Spoly creation and reductions
7*/
[0f98876]8
9// #define PDEBUG 2
[d14712]10#include "mod2.h"
11#include "kutil.h"
12#include "numbers.h"
[0f98876]13#include "p_polys.h"
[512a2b]14#include "p_Procs.h"
[d14712]15
16
[a29995]17#ifdef KDEBUG
18int red_count = 0;
19int create_count = 0;
20// define this if reductions are reported on TEST_OPT_DEBUG
21// #define TEST_OPT_DEBUG_RED
[d14712]22#endif
23
24/***************************************************************
25 *
26 * Reduces PR with PW
27 * Assumes PR != NULL, PW != NULL, Lm(PR) divides Lm(PW)
[a3bc95e]28 *
[d14712]29 ***************************************************************/
[dd01bf0]30int ksReducePoly(LObject* PR,
31                 TObject* PW,
32                 poly spNoether,
33                 number *coef,
34                 kStrategy strat)
[d14712]35{
[a29995]36#ifdef KDEBUG
37  red_count++;
38#ifdef TEST_OPT_DEBUG_RED
39  if (TEST_OPT_DEBUG)
40  {
41    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
42    PW->wrp();
43  }
44#endif
45#endif
[dd01bf0]46  int ret = 0;
[c5f4b9]47  ring tailRing = PR->tailRing;
[bd4fa1]48  kTest_L(PR);
[c5f4b9]49  kTest_T(PW);
[a3bc95e]50
[0f98876]51  poly p1 = PR->GetLmTailRing();
52  poly p2 = PW->GetLmTailRing();
[bd4fa1]53  poly t2 = pNext(p2), lm = p1;
[233e4c]54  assume(p1 != NULL && p2 != NULL);
[c5f4b9]55  p_CheckPolyRing(p1, tailRing);
56  p_CheckPolyRing(p2, tailRing);
[bd4fa1]57
[a3bc95e]58  pAssume1(p2 != NULL && p1 != NULL &&
[c5f4b9]59           p_DivisibleBy(p2,  p1, tailRing));
[bd4fa1]60
[c5f4b9]61  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
[a3bc95e]62           (p_GetComp(p2, tailRing) == 0 &&
[bd4fa1]63            p_MaxComp(pNext(p2),tailRing) == 0));
64
65  if (t2==NULL)
66  {
[c5f4b9]67    PR->LmDeleteAndIter();
68    if (coef != NULL) *coef = n_Init(1, tailRing);
[dd01bf0]69    return 0;
[0f98876]70  }
71
72  p_ExpVectorSub(lm, p2, tailRing);
[a3bc95e]73
[0f98876]74  if (tailRing != currRing)
75  {
76    // check that reduction does not violate exp bound
[fc83e4]77    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
[0f98876]78    {
79      // undo changes of lm
80      p_ExpVectorAdd(lm, p2, tailRing);
[dd01bf0]81      if (strat == NULL) return 2;
82      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
[0f98876]83      tailRing = strat->tailRing;
84      p1 = PR->GetLmTailRing();
85      p2 = PW->GetLmTailRing();
86      t2 = pNext(p2);
87      lm = p1;
[ab9672]88      p_ExpVectorSub(lm, p2, tailRing);
[dd01bf0]89      ret = 1;
[0f98876]90    }
[bd4fa1]91  }
92
[0f98876]93  // take care of coef buisness
[c5f4b9]94  if (! n_IsOne(pGetCoeff(p2), tailRing))
[bd4fa1]95  {
96    number bn = pGetCoeff(lm);
97    number an = pGetCoeff(p2);
98    int ct = ksCheckCoeff(&an, &bn);
[0f98876]99    p_SetCoeff(lm, bn,tailRing);
[a3bc95e]100    if ((ct == 0) || (ct == 2))
[bd4fa1]101      PR->Tail_Mult_nn(an);
102    if (coef != NULL) *coef = an;
[c5f4b9]103    else n_Delete(&an, tailRing);
[bd4fa1]104  }
105  else
106  {
[c5f4b9]107    if (coef != NULL) *coef = n_Init(1, tailRing);
[bd4fa1]108  }
[a3bc95e]109
110
111  // and finally,
[5038cd]112  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
[c5f4b9]113  PR->LmDeleteAndIter();
[a29995]114#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
115  if (TEST_OPT_DEBUG)
116  {
117    Print(" to: "); PR->wrp(); Print("\n");
118  }
119#endif
[dd01bf0]120  return ret;
[bd4fa1]121}
122
123/***************************************************************
124 *
125 * Creates S-Poly of p1 and p2
[a3bc95e]126 *
[bd4fa1]127 *
128 ***************************************************************/
[a3bc95e]129void ksCreateSpoly(LObject* Pair,   poly spNoether,
130                   int use_buckets, ring tailRing,
[fc83e4]131                   poly m1, poly m2, TObject** R)
[bd4fa1]132{
[a29995]133#ifdef KDEBUG
134  create_count++;
135#endif
[ff4e34f]136  kTest_L(Pair);
[bd4fa1]137  poly p1 = Pair->p1;
138  poly p2 = Pair->p2;
[5038cd]139  poly last;
[bd4fa1]140  Pair->tailRing = tailRing;
[a3bc95e]141
[bd4fa1]142  assume(p1 != NULL);
143  assume(p2 != NULL);
144  assume(tailRing != NULL);
145
146  poly a1 = pNext(p1), a2 = pNext(p2);
147  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
148  int co=0, ct = ksCheckCoeff(&lc1, &lc2);
149
[a29995]150  int l1=0, l2=0;
[a3bc95e]151
[0f98876]152  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
[bd4fa1]153  {
[0f98876]154    if (p_GetComp(p1, currRing)==0)
[bd4fa1]155    {
156      co=1;
[0f98876]157      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
[bd4fa1]158    }
159    else
160    {
161      co=2;
[0f98876]162      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
[bd4fa1]163    }
164  }
[d14712]165
[bd4fa1]166  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
167  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
[0f98876]168  if (m1 == NULL)
169    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
[a3bc95e]170
[bd4fa1]171  pSetCoeff0(m1, lc2);
[0f98876]172  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
[bd4fa1]173
[5038cd]174  if (R != NULL)
[fc83e4]175  {
[5038cd]176    l1 = (R[Pair->i_r1])->GetpLength() - 1;
177    l2 = (R[Pair->i_r2])->GetpLength() - 1;
[fc83e4]178  }
[a3bc95e]179
[bd4fa1]180  // get m2 * a2
[a77e2c]181  if (spNoether != NULL)
[a29995]182  {
183    l2 = -1;
[a77e2c]184    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
[a29995]185    assume(l2 == pLength(a2));
186  }
[a77e2c]187  else
188    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
[a29995]189  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
[bd4fa1]190
191  // get m2*a2 - m1*a1
[fc83e4]192  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
[a3bc95e]193
[bd4fa1]194  // Clean-up time
[c5f4b9]195  Pair->LmDeleteAndIter();
[bd4fa1]196  p_LmDelete(m1, tailRing);
[a3bc95e]197
[bd4fa1]198  if (co != 0)
199  {
200    if (co==1)
201    {
202      p_SetCompP(p1,0, currRing, tailRing);
203    }
204    else
205    {
206      p_SetCompP(p2,0, currRing, tailRing);
207    }
208  }
209}
210
[dd01bf0]211int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
[bd4fa1]212{
[0f98876]213  BOOLEAN ret;
[48aa42]214  number coef;
[4e6cf2]215  poly Lp =     PR->GetLmCurrRing();
216  poly Save =   PW->GetLmCurrRing();
[a3bc95e]217
[0f98876]218  kTest_L(PR);
219  kTest_T(PW);
220  pAssume(pIsMonomOf(Lp, Current));
[a3bc95e]221
[bd4fa1]222  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
223  assume(PR->bucket == NULL);
224
[c5f4b9]225  LObject Red(pNext(Current), PR->tailRing);
226  TObject With(PW, Lp == Save);
[bd4fa1]227
[5038cd]228  pAssume(!pHaveCommonMonoms(Red.p, With.p));
[0f98876]229  ret = ksReducePoly(&Red, &With, spNoether, &coef);
[a3bc95e]230
[dd01bf0]231  if (!ret)
[bd4fa1]232  {
[0f98876]233    if (! n_IsOne(coef, currRing))
234    {
235      pNext(Current) = NULL;
[fc83e4]236      if (Current == PR->p && PR->t_p != NULL)
237        pNext(PR->t_p) = NULL;
[0f98876]238      PR->Mult_nn(coef);
239    }
[c5f4b9]240
[0f98876]241    n_Delete(&coef, currRing);
242    pNext(Current) = Red.GetLmTailRing();
[fc83e4]243    if (Current == PR->p && PR->t_p != NULL)
244      pNext(PR->t_p) = pNext(Current);
[0f98876]245  }
[c5f4b9]246
[a3bc95e]247  if (Lp == Save)
[a29995]248    With.Delete();
[0f98876]249  return ret;
[bd4fa1]250}
251
[d14712]252/***************************************************************
253 *
254 * Auxillary Routines
[a3bc95e]255 *
256 *
[d14712]257 ***************************************************************/
258
259/*
260* input - output: a, b
261* returns:
262*   a := a/gcd(a,b), b := b/gcd(a,b)
263*   and return value
264*       0  ->  a != 1,  b != 1
265*       1  ->  a == 1,  b != 1
266*       2  ->  a != 1,  b == 1
267*       3  ->  a == 1,  b == 1
268*   this value is used to control the spolys
269*/
270int ksCheckCoeff(number *a, number *b)
271{
272  int c = 0;
273  number an = *a, bn = *b;
274  nTest(an);
275  nTest(bn);
[dd01bf0]276
[958e16]277  number cn = nGcd(an, bn, currRing);
[d14712]278
279  if(nIsOne(cn))
280  {
281    an = nCopy(an);
282    bn = nCopy(bn);
283  }
284  else
285  {
286    an = nIntDiv(an, cn);
287    bn = nIntDiv(bn, cn);
288  }
289  nDelete(&cn);
290  if (nIsOne(an))
291  {
292    c = 1;
293  }
294  if (nIsOne(bn))
295  {
296    c += 2;
297  }
298  *a = an;
299  *b = bn;
300  return c;
301}
302
303/*2
304* creates the leading term of the S-polynomial of p1 and p2
305* do not destroy p1 and p2
306* remarks:
307*   1. the coefficient is 0 (nNew)
308*   2. pNext is undefined
309*/
310//static void bbb() { int i=0; }
[0f98876]311poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
[d14712]312{
313  poly a1 = pNext(p1), a2 = pNext(p2);
[0f98876]314  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
[d14712]315  Exponent_t c;
316  poly m1,m2;
317  number t1,t2;
318  int cm,i;
319  BOOLEAN equal;
320
321  if (a1==NULL)
322  {
323    if(a2!=NULL)
324    {
[0f98876]325      m2=p_Init(currRing);
[d14712]326x2:
327      for (i = pVariables; i; i--)
328      {
[0f98876]329        c = p_GetExpDiff(p1, p2,i, currRing);
[d14712]330        if (c>0)
331        {
[0f98876]332          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
[d14712]333        }
334        else
335        {
[0f98876]336          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
[d14712]337        }
338      }
339      if ((c1==c2)||(c2!=0))
340      {
[0f98876]341        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
[d14712]342      }
343      else
344      {
[0f98876]345        p_SetComp(m2,c1,currRing);
[d14712]346      }
[0f98876]347      p_Setm(m2, currRing);
[d14712]348      nNew(&(pGetCoeff(m2)));
349      return m2;
350    }
351    else
352      return NULL;
353  }
354  if (a2==NULL)
355  {
[0f98876]356    m1=p_Init(currRing);
[d14712]357x1:
358    for (i = pVariables; i; i--)
359    {
[0f98876]360      c = p_GetExpDiff(p2, p1,i,currRing);
[d14712]361      if (c>0)
362      {
[0f98876]363        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
[d14712]364      }
365      else
366      {
[0f98876]367        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
[d14712]368      }
369    }
370    if ((c1==c2)||(c1!=0))
371    {
[0f98876]372      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
[d14712]373    }
374    else
375    {
[0f98876]376      p_SetComp(m1,c2,currRing);
[d14712]377    }
[0f98876]378    p_Setm(m1, currRing);
[d14712]379    nNew(&(pGetCoeff(m1)));
380    return m1;
381  }
[0f98876]382  m1 = p_Init(currRing);
383  m2 = p_Init(currRing);
[d14712]384  for(;;)
385  {
386    for (i = pVariables; i; i--)
387    {
[0f98876]388      c = p_GetExpDiff(p1, p2,i,currRing);
[d14712]389      if (c > 0)
390      {
[0f98876]391        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
392        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
[d14712]393      }
394      else
395      {
[0f98876]396        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
397        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
[d14712]398      }
399    }
400    if(c1==c2)
401    {
[0f98876]402      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
403      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
[d14712]404    }
405    else
406    {
407      if(c1!=0)
408      {
[0f98876]409        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
410        p_SetComp(m2,c1, currRing);
[d14712]411      }
412      else
413      {
[0f98876]414        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
415        p_SetComp(m1,c2, currRing);
[d14712]416      }
417    }
[0f98876]418    p_Setm(m1,currRing);
419    p_Setm(m2,currRing);
420    cm = p_LmCmp(m1, m2,currRing);
[d14712]421    if (cm!=0)
422    {
423      if(cm==1)
424      {
[0f98876]425        p_LmFree(m2,currRing);
[d14712]426        nNew(&(pGetCoeff(m1)));
427        return m1;
428      }
429      else
430      {
[0f98876]431        p_LmFree(m1,currRing);
[d14712]432        nNew(&(pGetCoeff(m2)));
433        return m2;
434      }
435    }
436    t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
437    t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
438    equal = nEqual(t1,t2);
439    nDelete(&t2);
440    nDelete(&t1);
441    if (!equal)
442    {
[0f98876]443      p_LmFree(m2,currRing);
[d14712]444      nNew(&(pGetCoeff(m1)));
445      return m1;
446    }
447    pIter(a1);
448    pIter(a2);
449    if (a2==NULL)
450    {
[0f98876]451      p_LmFree(m2,currRing);
[d14712]452      if (a1==NULL)
453      {
[0f98876]454        p_LmFree(m1,currRing);
[d14712]455        return NULL;
456      }
457      goto x1;
458    }
459    if (a1==NULL)
460    {
[0f98876]461      p_LmFree(m1,currRing);
[d14712]462      goto x2;
463    }
464  }
465}
Note: See TracBrowser for help on using the repository browser.