source: git/kernel/kspoly.cc @ 68349d

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