source: git/Singular/kspoly.cc @ a29995

spielwiese
Last change on this file since a29995 was a29995, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* towards tailRings for local case git-svn-id: file:///usr/local/Singular/svn/trunk@4777 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 10.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kspoly.cc,v 1.22 2000-11-28 11:50:52 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
211//////////////////////////////////////////////////////////////////////////
212// Reduces PR at Current->next with PW
213// Assumes PR != NULL, Current contained in PR
214//         Current->next != NULL, LM(PW) devides LM(Current->next)
215// Changes: PR
216// Const:   PW
217int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
218{
219  BOOLEAN ret;
220  poly Lp =     PR->GetLmCurrRing();
221  poly Save =   PW->GetLmCurrRing();
222 
223  kTest_L(PR);
224  kTest_T(PW);
225  pAssume(pIsMonomOf(Lp, Current));
226 
227  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
228  assume(PR->bucket == NULL);
229
230  LObject Red(pNext(Current), PR->tailRing);
231  TObject With(PW, Lp == Save);
232  number coef;
233
234  pAssume(!pHaveCommonMonoms(Red.p, With.p));
235  ret = ksReducePoly(&Red, &With, spNoether, &coef);
236 
237  if (!ret)
238  {
239    if (! n_IsOne(coef, currRing))
240    {
241      pNext(Current) = NULL;
242      if (Current == PR->p && PR->t_p != NULL)
243        pNext(PR->t_p) = NULL;
244      PR->Mult_nn(coef);
245    }
246
247    n_Delete(&coef, currRing);
248    pNext(Current) = Red.GetLmTailRing();
249    if (Current == PR->p && PR->t_p != NULL)
250      pNext(PR->t_p) = pNext(Current);
251  }
252
253  if (Lp == Save) 
254    With.Delete();
255  return ret;
256}
257
258/***************************************************************
259 *
260 * Auxillary Routines
261 *
262 *
263 ***************************************************************/
264
265/*
266* input - output: a, b
267* returns:
268*   a := a/gcd(a,b), b := b/gcd(a,b)
269*   and return value
270*       0  ->  a != 1,  b != 1
271*       1  ->  a == 1,  b != 1
272*       2  ->  a != 1,  b == 1
273*       3  ->  a == 1,  b == 1
274*   this value is used to control the spolys
275*/
276int ksCheckCoeff(number *a, number *b)
277{
278  int c = 0;
279  number an = *a, bn = *b;
280  nTest(an);
281  nTest(bn);
282
283  number cn = nGcd(an, bn);
284
285  if(nIsOne(cn))
286  {
287    an = nCopy(an);
288    bn = nCopy(bn);
289  }
290  else
291  {
292    an = nIntDiv(an, cn);
293    bn = nIntDiv(bn, cn);
294  }
295  nDelete(&cn);
296  if (nIsOne(an))
297  {
298    c = 1;
299  }
300  if (nIsOne(bn))
301  {
302    c += 2;
303  }
304  *a = an;
305  *b = bn;
306  return c;
307}
308
309/*2
310* creates the leading term of the S-polynomial of p1 and p2
311* do not destroy p1 and p2
312* remarks:
313*   1. the coefficient is 0 (nNew)
314*   2. pNext is undefined
315*/
316//static void bbb() { int i=0; }
317poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
318{
319  poly a1 = pNext(p1), a2 = pNext(p2);
320  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
321  Exponent_t c;
322  poly m1,m2;
323  number t1,t2;
324  int cm,i;
325  BOOLEAN equal;
326
327  if (a1==NULL)
328  {
329    if(a2!=NULL)
330    {
331      m2=p_Init(currRing);
332x2:
333      for (i = pVariables; i; i--)
334      {
335        c = p_GetExpDiff(p1, p2,i, currRing);
336        if (c>0)
337        {
338          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
339        }
340        else
341        {
342          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
343        }
344      }
345      if ((c1==c2)||(c2!=0))
346      {
347        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
348      }
349      else
350      {
351        p_SetComp(m2,c1,currRing);
352      }
353      p_Setm(m2, currRing);
354      nNew(&(pGetCoeff(m2)));
355      return m2;
356    }
357    else
358      return NULL;
359  }
360  if (a2==NULL)
361  {
362    m1=p_Init(currRing);
363x1:
364    for (i = pVariables; i; i--)
365    {
366      c = p_GetExpDiff(p2, p1,i,currRing);
367      if (c>0)
368      {
369        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
370      }
371      else
372      {
373        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
374      }
375    }
376    if ((c1==c2)||(c1!=0))
377    {
378      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
379    }
380    else
381    {
382      p_SetComp(m1,c2,currRing);
383    }
384    p_Setm(m1, currRing);
385    nNew(&(pGetCoeff(m1)));
386    return m1;
387  }
388  m1 = p_Init(currRing);
389  m2 = p_Init(currRing);
390  for(;;)
391  {
392    for (i = pVariables; i; i--)
393    {
394      c = p_GetExpDiff(p1, p2,i,currRing);
395      if (c > 0)
396      {
397        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
398        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
399      }
400      else
401      {
402        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
403        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
404      }
405    }
406    if(c1==c2)
407    {
408      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
409      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
410    }
411    else
412    {
413      if(c1!=0)
414      {
415        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
416        p_SetComp(m2,c1, currRing);
417      }
418      else
419      {
420        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
421        p_SetComp(m1,c2, currRing);
422      }
423    }
424    p_Setm(m1,currRing);
425    p_Setm(m2,currRing);
426    cm = p_LmCmp(m1, m2,currRing);
427    if (cm!=0)
428    {
429      if(cm==1)
430      {
431        p_LmFree(m2,currRing);
432        nNew(&(pGetCoeff(m1)));
433        return m1;
434      }
435      else
436      {
437        p_LmFree(m1,currRing);
438        nNew(&(pGetCoeff(m2)));
439        return m2;
440      }
441    }
442    t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
443    t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
444    equal = nEqual(t1,t2);
445    nDelete(&t2);
446    nDelete(&t1);
447    if (!equal)
448    {
449      p_LmFree(m2,currRing);
450      nNew(&(pGetCoeff(m1)));
451      return m1;
452    }
453    pIter(a1);
454    pIter(a2);
455    if (a2==NULL)
456    {
457      p_LmFree(m2,currRing);
458      if (a1==NULL)
459      {
460        p_LmFree(m1,currRing);
461        return NULL;
462      }
463      goto x1;
464    }
465    if (a1==NULL)
466    {
467      p_LmFree(m1,currRing);
468      goto x2;
469    }
470  }
471}
472
473
474
475
476
477 
478 
Note: See TracBrowser for help on using the repository browser.