source: git/kernel/kspoly.cc @ 585bbcb

spielwiese
Last change on this file since 585bbcb was 585bbcb, checked in by Oliver Wienand <wienand@…>, 18 years ago
Makefile.in: --> rmodulo2m.[h/cc] in HEADERS / CXXSOURCES eingetragen kspoly.cc: --> ksReducePoly beachtet Nullteiler --> ksRingReducePoly (neu) --> ksCreateSpoly beachtet Nullteiler kstd1.cc: --> use strat->red = redRing2toM if currRing->cring == 1 kstd2.cc: --> kRingFindDivisibleByInT (neu) --> kRingFindDivisibleByInS (neu) --> redRing2toM (neu) kutil.cc: --> kRingFindDivisibleByInS (neu) --> redTailBba beachtet Nullteiler und andere Strategien (zum Teil) kutil.h: --> int redRing2toM (LObject* h,kStrategy strat); (neu) --> Dekl. von kRingFind* und ksRingReducePoly numbers.cc: --> Unterstützung für Z/2^m pDebug.cc: --> p_DebugLmDivisibleByNoComp beachtet coeff für Ringe pInline1.h: --> *LmRing* Teilbarkeit mit Beachtung des Koeff p_Minus_mm_Mult_qq__T.cc: --> Term*Term = 0 möglich polys.cc: --> nGetUnit (neu) --> pNorm beachtet Nullteiler polys.h: --> nGetUnit (neu) polys1.cc: --> pCleardenom: in case of ring, just do a pNorm --> pContent: in case of ring do nothing pp_Mult_mm__T.cc: --> Term*Term = 0 möglich bei KoeffRing ring.cc: --> rSetOption: setze intStrategy ring.h: --> rField_is_Ring_2toM (neu) --> alle anderen Fkt. angepasst ringgb.cc, ringgb.h: test container in Zshg. mit extra.cc structs.h: --> ring->cring property (neu) cring = 0 bei Körpern, cring = 1 bei Z/2^m git-svn-id: file:///usr/local/Singular/svn/trunk@8813 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kspoly.cc,v 1.2 2005-11-27 15:28:44 wienand 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#ifdef HAVE_RING2TOM
119    if (currRing->cring == 1) {
120      while (((long) an)%2 == 0 && ((long) bn)%2 == 0) {
121        an = (number) (((long) an) / 2);
122        bn = (number) (((long) bn) / 2);
123      }
124    }
125#endif
126    int ct = ksCheckCoeff(&an, &bn);
127    p_SetCoeff(lm, bn,tailRing);
128    if ((ct == 0) || (ct == 2))
129      PR->Tail_Mult_nn(an);
130    if (coef != NULL) *coef = an;
131    else n_Delete(&an, tailRing);
132  }
133  else
134  {
135    if (coef != NULL) *coef = n_Init(1, tailRing);
136  }
137
138
139  // and finally,
140  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
141  PR->LmDeleteAndIter();
142#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
143  if (TEST_OPT_DEBUG)
144  {
145    Print(" to: "); PR->wrp(); Print("\n");
146  }
147#endif
148  return ret;
149}
150
151#ifdef HAVE_RING2TOM
152/***************************************************************
153 *
154 * Reduces PR with PW
155 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
156 * as above, just for rings
157 *
158 ***************************************************************/
159int ksRingReducePoly(LObject* PR,
160                 TObject* PW,
161                 poly spNoether,
162                 number *coef,
163                 kStrategy strat)
164{
165#ifdef KDEBUG
166  red_count++;
167#ifdef TEST_OPT_DEBUG_RED
168  if (TEST_OPT_DEBUG)
169  {
170    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
171    PW->wrp();
172  }
173#endif
174#endif
175  int ret = 0;
176  ring tailRing = PR->tailRing;
177  kTest_L(PR);
178  kTest_T(PW);
179
180  poly p1 = PR->GetLmTailRing();
181  poly p2 = PW->GetLmTailRing();
182  poly t2 = pNext(p2), lm = p1;
183  assume(p1 != NULL && p2 != NULL);
184  p_CheckPolyRing(p1, tailRing);
185  p_CheckPolyRing(p2, tailRing);
186
187  pAssume1(p2 != NULL && p1 != NULL &&
188           p_RingDivisibleBy(p2,  p1, tailRing));
189
190  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
191           (p_GetComp(p2, tailRing) == 0 &&
192            p_MaxComp(pNext(p2),tailRing) == 0));
193
194  if (t2==NULL)
195  {
196    PR->LmDeleteAndIter();
197    if (coef != NULL) *coef = n_Init(1, tailRing);
198    return 0;
199  }
200
201  p_ExpVectorSub(lm, p2, tailRing);
202
203  if (tailRing != currRing)
204  {
205    // check that reduction does not violate exp bound
206    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
207    {
208      // undo changes of lm
209      p_ExpVectorAdd(lm, p2, tailRing);
210      if (strat == NULL) return 2;
211      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
212      tailRing = strat->tailRing;
213      p1 = PR->GetLmTailRing();
214      p2 = PW->GetLmTailRing();
215      t2 = pNext(p2);
216      lm = p1;
217      p_ExpVectorSub(lm, p2, tailRing);
218      ret = 1;
219    }
220  }
221
222  // take care of coef buisness
223  if (! n_IsOne(pGetCoeff(p2), tailRing))
224  {
225    number bn = pGetCoeff(lm);
226    number an = pGetCoeff(p2);
227    while (((long) an)%2 == 0 && ((long) bn)%2 == 0) {
228      an = (number) (((long) an) / 2);
229      bn = (number) (((long) bn) / 2);
230    }
231    int ct = ksCheckCoeff(&an, &bn);
232    p_SetCoeff(lm, bn,tailRing);
233    if ((ct == 0) || (ct == 2))
234      PR->Tail_Mult_nn(an);
235    if (coef != NULL) *coef = an;
236    else n_Delete(&an, tailRing);
237  }
238  else
239  {
240    if (coef != NULL) *coef = n_Init(1, tailRing);
241  }
242
243
244  // and finally,
245  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
246  PR->LmDeleteAndIter();
247#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
248  if (TEST_OPT_DEBUG)
249  {
250    Print(" to: "); PR->wrp(); Print("\n");
251  }
252#endif
253  return ret;
254}
255#endif
256
257/***************************************************************
258 *
259 * Creates S-Poly of p1 and p2
260 *
261 *
262 ***************************************************************/
263void ksCreateSpoly(LObject* Pair,   poly spNoether,
264                   int use_buckets, ring tailRing,
265                   poly m1, poly m2, TObject** R)
266{
267#ifdef KDEBUG
268  create_count++;
269#endif
270  kTest_L(Pair);
271  poly p1 = Pair->p1;
272  poly p2 = Pair->p2;
273  poly last;
274  Pair->tailRing = tailRing;
275
276  assume(p1 != NULL);
277  assume(p2 != NULL);
278  assume(tailRing != NULL);
279
280  poly a1 = pNext(p1), a2 = pNext(p2);
281  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
282#ifdef HAVE_RING2TOM
283  if (currRing->cring == 1) {
284    while (((long) lc1)%2 == 0 && ((long) lc2)%2 == 0) {
285      lc1 = (number) (((long) lc1) / 2);
286      lc2 = (number) (((long) lc2) / 2);
287    }
288  }
289#endif 
290  int co=0, ct = ksCheckCoeff(&lc1, &lc2);
291
292  int l1=0, l2=0;
293
294  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
295  {
296    if (p_GetComp(p1, currRing)==0)
297    {
298      co=1;
299      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
300    }
301    else
302    {
303      co=2;
304      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
305    }
306  }
307
308  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
309  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
310  if (m1 == NULL)
311    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
312
313  pSetCoeff0(m1, lc2);
314  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
315
316  if (R != NULL)
317  {
318    l1 = (R[Pair->i_r1])->GetpLength() - 1;
319    l2 = (R[Pair->i_r2])->GetpLength() - 1;
320  }
321
322  // get m2 * a2
323  if (spNoether != NULL)
324  {
325    l2 = -1;
326    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing,last);
327    assume(l2 == pLength(a2));
328  }
329  else
330    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing,last);
331  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing, last);
332
333  // get m2*a2 - m1*a1
334  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
335
336  // Clean-up time
337  Pair->LmDeleteAndIter();
338  p_LmDelete(m1, tailRing);
339
340  if (co != 0)
341  {
342    if (co==1)
343    {
344      p_SetCompP(p1,0, currRing, tailRing);
345    }
346    else
347    {
348      p_SetCompP(p2,0, currRing, tailRing);
349    }
350  }
351}
352
353int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
354{
355  BOOLEAN ret;
356  number coef;
357  poly Lp =     PR->GetLmCurrRing();
358  poly Save =   PW->GetLmCurrRing();
359
360  kTest_L(PR);
361  kTest_T(PW);
362  pAssume(pIsMonomOf(Lp, Current));
363
364  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
365  assume(PR->bucket == NULL);
366
367  LObject Red(pNext(Current), PR->tailRing);
368  TObject With(PW, Lp == Save);
369
370  pAssume(!pHaveCommonMonoms(Red.p, With.p));
371  ret = ksReducePoly(&Red, &With, spNoether, &coef);
372
373  if (!ret)
374  {
375    if (! n_IsOne(coef, currRing))
376    {
377      pNext(Current) = NULL;
378      if (Current == PR->p && PR->t_p != NULL)
379        pNext(PR->t_p) = NULL;
380      PR->Mult_nn(coef);
381    }
382
383    n_Delete(&coef, currRing);
384    pNext(Current) = Red.GetLmTailRing();
385    if (Current == PR->p && PR->t_p != NULL)
386      pNext(PR->t_p) = pNext(Current);
387  }
388
389  if (Lp == Save)
390    With.Delete();
391  return ret;
392}
393
394/***************************************************************
395 *
396 * Auxillary Routines
397 *
398 *
399 ***************************************************************/
400
401/*
402* input - output: a, b
403* returns:
404*   a := a/gcd(a,b), b := b/gcd(a,b)
405*   and return value
406*       0  ->  a != 1,  b != 1
407*       1  ->  a == 1,  b != 1
408*       2  ->  a != 1,  b == 1
409*       3  ->  a == 1,  b == 1
410*   this value is used to control the spolys
411*/
412int ksCheckCoeff(number *a, number *b)
413{
414  int c = 0;
415  number an = *a, bn = *b;
416  nTest(an);
417  nTest(bn);
418
419  number cn = nGcd(an, bn, currRing);
420
421  if(nIsOne(cn))
422  {
423    an = nCopy(an);
424    bn = nCopy(bn);
425  }
426  else
427  {
428    an = nIntDiv(an, cn);
429    bn = nIntDiv(bn, cn);
430  }
431  nDelete(&cn);
432  if (nIsOne(an))
433  {
434    c = 1;
435  }
436  if (nIsOne(bn))
437  {
438    c += 2;
439  }
440  *a = an;
441  *b = bn;
442  return c;
443}
444
445/*2
446* creates the leading term of the S-polynomial of p1 and p2
447* do not destroy p1 and p2
448* remarks:
449*   1. the coefficient is 0 (nNew)
450*   2. pNext is undefined
451*/
452//static void bbb() { int i=0; }
453poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
454{
455  poly a1 = pNext(p1), a2 = pNext(p2);
456  Exponent_t c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
457  Exponent_t c;
458  poly m1,m2;
459  number t1,t2;
460  int cm,i;
461  BOOLEAN equal;
462
463  if (a1==NULL)
464  {
465    if(a2!=NULL)
466    {
467      m2=p_Init(currRing);
468x2:
469      for (i = pVariables; i; i--)
470      {
471        c = p_GetExpDiff(p1, p2,i, currRing);
472        if (c>0)
473        {
474          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
475        }
476        else
477        {
478          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
479        }
480      }
481      if ((c1==c2)||(c2!=0))
482      {
483        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
484      }
485      else
486      {
487        p_SetComp(m2,c1,currRing);
488      }
489      p_Setm(m2, currRing);
490      nNew(&(pGetCoeff(m2)));
491      return m2;
492    }
493    else
494      return NULL;
495  }
496  if (a2==NULL)
497  {
498    m1=p_Init(currRing);
499x1:
500    for (i = pVariables; i; i--)
501    {
502      c = p_GetExpDiff(p2, p1,i,currRing);
503      if (c>0)
504      {
505        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
506      }
507      else
508      {
509        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
510      }
511    }
512    if ((c1==c2)||(c1!=0))
513    {
514      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
515    }
516    else
517    {
518      p_SetComp(m1,c2,currRing);
519    }
520    p_Setm(m1, currRing);
521    nNew(&(pGetCoeff(m1)));
522    return m1;
523  }
524  m1 = p_Init(currRing);
525  m2 = p_Init(currRing);
526  for(;;)
527  {
528    for (i = pVariables; i; i--)
529    {
530      c = p_GetExpDiff(p1, p2,i,currRing);
531      if (c > 0)
532      {
533        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
534        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
535      }
536      else
537      {
538        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
539        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
540      }
541    }
542    if(c1==c2)
543    {
544      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
545      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
546    }
547    else
548    {
549      if(c1!=0)
550      {
551        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
552        p_SetComp(m2,c1, currRing);
553      }
554      else
555      {
556        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
557        p_SetComp(m1,c2, currRing);
558      }
559    }
560    p_Setm(m1,currRing);
561    p_Setm(m2,currRing);
562    cm = p_LmCmp(m1, m2,currRing);
563    if (cm!=0)
564    {
565      if(cm==1)
566      {
567        p_LmFree(m2,currRing);
568        nNew(&(pGetCoeff(m1)));
569        return m1;
570      }
571      else
572      {
573        p_LmFree(m1,currRing);
574        nNew(&(pGetCoeff(m2)));
575        return m2;
576      }
577    }
578    t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
579    t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
580    equal = nEqual(t1,t2);
581    nDelete(&t2);
582    nDelete(&t1);
583    if (!equal)
584    {
585      p_LmFree(m2,currRing);
586      nNew(&(pGetCoeff(m1)));
587      return m1;
588    }
589    pIter(a1);
590    pIter(a2);
591    if (a2==NULL)
592    {
593      p_LmFree(m2,currRing);
594      if (a1==NULL)
595      {
596        p_LmFree(m1,currRing);
597        return NULL;
598      }
599      goto x1;
600    }
601    if (a1==NULL)
602    {
603      p_LmFree(m1,currRing);
604      goto x2;
605    }
606  }
607}
Note: See TracBrowser for help on using the repository browser.