source: git/Singular/kspoly.cc @ fa1f52

spielwiese
Last change on this file since fa1f52 was 48aa42, checked in by Olaf Bachmann <obachman@…>, 23 years ago
opt(redThrough) etc added git-svn-id: file:///usr/local/Singular/svn/trunk@4905 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kspoly.cc,v 1.23 2000-12-14 16:38:50 obachman 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
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(PR) divides Lm(PW)
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 (t2==NULL)
66  {
67    PR->LmDeleteAndIter();
68    if (coef != NULL) *coef = n_Init(1, tailRing);
69    return 0;
70  }
71
72  p_ExpVectorSub(lm, p2, tailRing);
73 
74  if (tailRing != currRing)
75  {
76    // check that reduction does not violate exp bound
77    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
78    {
79      // undo changes of lm
80      p_ExpVectorAdd(lm, p2, tailRing);
81      if (strat == NULL) return 2;
82      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
83      tailRing = strat->tailRing;
84      p1 = PR->GetLmTailRing();
85      p2 = PW->GetLmTailRing();
86      t2 = pNext(p2);
87      lm = p1;
88      p_ExpVectorSub(lm, p2, tailRing);
89      ret = 1;
90    }
91  }
92
93  // take care of coef buisness
94  if (! n_IsOne(pGetCoeff(p2), tailRing))
95  {
96    number bn = pGetCoeff(lm);
97    number an = pGetCoeff(p2);
98    int ct = ksCheckCoeff(&an, &bn);
99    p_SetCoeff(lm, bn,tailRing);
100    if ((ct == 0) || (ct == 2)) 
101      PR->Tail_Mult_nn(an);
102    if (coef != NULL) *coef = an;
103    else n_Delete(&an, tailRing);
104  }
105  else
106  {
107    if (coef != NULL) *coef = n_Init(1, tailRing);
108  }
109 
110 
111  // and finally,
112  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
113  PR->LmDeleteAndIter();
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
120  return ret;
121}
122
123/***************************************************************
124 *
125 * Creates S-Poly of p1 and p2
126 *
127 *
128 ***************************************************************/
129void ksCreateSpoly(LObject* Pair,   poly spNoether, 
130                   int use_buckets, ring tailRing, 
131                   poly m1, poly m2, TObject** R)
132{
133#ifdef KDEBUG
134  create_count++;
135#endif
136  kTest_L(Pair);
137  poly p1 = Pair->p1;
138  poly p2 = Pair->p2;
139  poly last;
140  Pair->tailRing = tailRing;
141 
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
150  int l1=0, l2=0;
151 
152  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
153  {
154    if (p_GetComp(p1, currRing)==0)
155    {
156      co=1;
157      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
158    }
159    else
160    {
161      co=2;
162      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
163    }
164  }
165
166  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
167  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
168  if (m1 == NULL)
169    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
170   
171  pSetCoeff0(m1, lc2);
172  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
173
174  if (R != NULL)
175  {
176    l1 = (R[Pair->i_r1])->GetpLength() - 1;
177    l2 = (R[Pair->i_r2])->GetpLength() - 1;
178  }
179 
180  // get m2 * a2
181  if (spNoether != NULL)
182  {
183    l2 = -1;
184    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
185    assume(l2 == pLength(a2));
186  }
187  else
188    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
189  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
190
191  // get m2*a2 - m1*a1
192  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
193 
194  // Clean-up time
195  Pair->LmDeleteAndIter();
196  p_LmDelete(m1, tailRing);
197 
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
211int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
212{
213  BOOLEAN ret;
214  number coef;
215  poly Lp =     PR->GetLmCurrRing();
216  poly Save =   PW->GetLmCurrRing();
217 
218  kTest_L(PR);
219  kTest_T(PW);
220  pAssume(pIsMonomOf(Lp, Current));
221 
222  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
223  assume(PR->bucket == NULL);
224
225  LObject Red(pNext(Current), PR->tailRing);
226  TObject With(PW, Lp == Save);
227
228  pAssume(!pHaveCommonMonoms(Red.p, With.p));
229  ret = ksReducePoly(&Red, &With, spNoether, &coef);
230 
231  if (!ret)
232  {
233    if (! n_IsOne(coef, currRing))
234    {
235      pNext(Current) = NULL;
236      if (Current == PR->p && PR->t_p != NULL)
237        pNext(PR->t_p) = NULL;
238      PR->Mult_nn(coef);
239    }
240
241    n_Delete(&coef, currRing);
242    pNext(Current) = Red.GetLmTailRing();
243    if (Current == PR->p && PR->t_p != NULL)
244      pNext(PR->t_p) = pNext(Current);
245  }
246
247  if (Lp == Save) 
248    With.Delete();
249  return ret;
250}
251
252/***************************************************************
253 *
254 * Auxillary Routines
255 *
256 *
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);
276
277  number cn = nGcd(an, bn);
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; }
311poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
312{
313  poly a1 = pNext(p1), a2 = pNext(p2);
314  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
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    {
325      m2=p_Init(currRing);
326x2:
327      for (i = pVariables; i; i--)
328      {
329        c = p_GetExpDiff(p1, p2,i, currRing);
330        if (c>0)
331        {
332          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
333        }
334        else
335        {
336          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
337        }
338      }
339      if ((c1==c2)||(c2!=0))
340      {
341        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
342      }
343      else
344      {
345        p_SetComp(m2,c1,currRing);
346      }
347      p_Setm(m2, currRing);
348      nNew(&(pGetCoeff(m2)));
349      return m2;
350    }
351    else
352      return NULL;
353  }
354  if (a2==NULL)
355  {
356    m1=p_Init(currRing);
357x1:
358    for (i = pVariables; i; i--)
359    {
360      c = p_GetExpDiff(p2, p1,i,currRing);
361      if (c>0)
362      {
363        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
364      }
365      else
366      {
367        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
368      }
369    }
370    if ((c1==c2)||(c1!=0))
371    {
372      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
373    }
374    else
375    {
376      p_SetComp(m1,c2,currRing);
377    }
378    p_Setm(m1, currRing);
379    nNew(&(pGetCoeff(m1)));
380    return m1;
381  }
382  m1 = p_Init(currRing);
383  m2 = p_Init(currRing);
384  for(;;)
385  {
386    for (i = pVariables; i; i--)
387    {
388      c = p_GetExpDiff(p1, p2,i,currRing);
389      if (c > 0)
390      {
391        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
392        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
393      }
394      else
395      {
396        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
397        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
398      }
399    }
400    if(c1==c2)
401    {
402      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
403      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
404    }
405    else
406    {
407      if(c1!=0)
408      {
409        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
410        p_SetComp(m2,c1, currRing);
411      }
412      else
413      {
414        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
415        p_SetComp(m1,c2, currRing);
416      }
417    }
418    p_Setm(m1,currRing);
419    p_Setm(m2,currRing);
420    cm = p_LmCmp(m1, m2,currRing);
421    if (cm!=0)
422    {
423      if(cm==1)
424      {
425        p_LmFree(m2,currRing);
426        nNew(&(pGetCoeff(m1)));
427        return m1;
428      }
429      else
430      {
431        p_LmFree(m1,currRing);
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    {
443      p_LmFree(m2,currRing);
444      nNew(&(pGetCoeff(m1)));
445      return m1;
446    }
447    pIter(a1);
448    pIter(a2);
449    if (a2==NULL)
450    {
451      p_LmFree(m2,currRing);
452      if (a1==NULL)
453      {
454        p_LmFree(m1,currRing);
455        return NULL;
456      }
457      goto x1;
458    }
459    if (a1==NULL)
460    {
461      p_LmFree(m1,currRing);
462      goto x2;
463    }
464  }
465}
466
467
468
469
470
471 
472 
Note: See TracBrowser for help on using the repository browser.