source: git/libpolys/polys/kbuckets.cc @ 8ee887

spielwiese
Last change on this file since 8ee887 was 8ee887, checked in by Hans Schoenemann <hannes@…>, 10 years ago
fix: ksCheckCoeff: may be used with coeffs in Q
  • Property mode set to 100644
File size: 32.0 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
[58ea04]4//#include <kernel/mod2.h>
[9f7665]5
6
7
[934108]8
9#include <omalloc/omalloc.h>
[16f511]10#include <misc/auxiliary.h>
11
[58ea04]12#include <polys/monomials/p_polys.h>
13//#include <kernel/pShallowCopyDelete.h>
14#include <coeffs/coeffs.h>
15#include <polys/monomials/ring.h>
16//#include <kernel/p_Procs.h>
[57fa2c4]17//#include <kernel/GBEngine/kutil.h>
[58ea04]18#include <polys/kbuckets.h>
[35aab3]19
[a3d94c]20// #include <polys/operations/pShallowCopyDelete.h>
21
22
[35aab3]23#ifdef HAVE_COEF_BUCKETS
24#define USE_COEF_BUCKETS
25#endif
26
27#ifdef USE_COEF_BUCKETS
[009d80]28#ifdef HAVE_RINGS_OLD
[cea6f3]29#define MULTIPLY_BUCKET(B,I) do                                        \
30  { if (B->coef[I]!=NULL)                                              \
31    {                                                                  \
[21ee92]32      assume(p_IsConstant(B->Coef[i],B->bucket->ring));           \
[cea6f3]33      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
34      B->coef[I]=NULL;                                                 \
35    }                                                                  \
36  } while(0)                                                           \
[58ea04]37    if (rField_is_Ring(B->bucket_ring)) B->buckets_length[i] = pLength(B->buckets[i]);
[cea6f3]38#else
[35aab3]39#define MULTIPLY_BUCKET(B,I) do                                        \
40  { if (B->coef[I]!=NULL)                                              \
41    {                                                                  \
42      B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
43      B->coef[I]=NULL;                                                 \
44    }                                                                  \
45  } while(0)
[cea6f3]46#endif
[35aab3]47#else
48#define MULTIPLY_BUCKET(B,I)
49#endif
50static omBin kBucket_bin = omGetSpecBin(sizeof(kBucket));
[0276c1]51#ifdef USE_COEF_BUCKETS
[473b74]52static int coef_start=1;
[0276c1]53#endif
[35aab3]54//////////////////////////////////////////////////////////////////////////
55///
56/// Some internal stuff
57///
58
59// returns ceil(log_4(l))
60inline unsigned int pLogLength(unsigned int l)
61{
62  unsigned int i = 0;
63
64  if (l == 0) return 0;
65  l--;
66#ifdef BUCKET_TWO_BASE
67  while ((l = (l >> 1))) i++;
68#else
69  while ((l = (l >> 2))) i++;
70#endif
71  return i+1;
72}
73
74// returns ceil(log_4(pLength(p)))
75inline unsigned int pLogLength(poly p)
76{
77  return pLogLength((unsigned int) pLength(p));
78}
79
80#ifdef KDEBUG
81
82#ifndef HAVE_PSEUDO_BUCKETS
83BOOLEAN kbTest_i(kBucket_pt bucket, int i)
[473b74]84{//sBucketSortMerge
[35aab3]85  #ifdef USE_COEF_BUCKETS
86  assume(bucket->coef[0]==NULL);
87  if ((bucket->coef[i]!=NULL) && (bucket->buckets[i]==NULL))
88  {
89    dReportError("Bucket %d coef not NULL", i);
90  }
91  if (bucket->coef[i]!=NULL)
[473b74]92  {
93    assume(bucket->buckets[i]!=NULL);
[35aab3]94    _p_Test(bucket->coef[i],bucket->bucket_ring,PDEBUG);
[473b74]95    }
[35aab3]96  #endif
97  pFalseReturn(p_Test(bucket->buckets[i], bucket->bucket_ring));
98  if (bucket->buckets_length[i] != pLength(bucket->buckets[i]))
99  {
100    dReportError("Bucket %d lengths difference should:%d has:%d",
101                 i, bucket->buckets_length[i], pLength(bucket->buckets[i]));
102  }
103  else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
104  {
105    dReportError("Bucket %d too long %d",
106                 i, bucket->buckets_length[i]);
107  }
108  if (i==0 && bucket->buckets_length[0] > 1)
109  {
110    dReportError("Bucket 0 too long");
111  }
112  return TRUE;
113}
114
115
116BOOLEAN kbTest(kBucket_pt bucket)
117{
[42ddd0]118  #ifdef HAVE_COEF_BUCKETS
[473b74]119  assume(bucket->coef[0]==NULL);
[42ddd0]120  #endif
[35aab3]121  int i;
122  poly lm = bucket->buckets[0];
123
124  omCheckAddrBin(bucket, kBucket_bin);
[27fef2]125  assume(bucket->buckets_used <= MAX_BUCKET);
[35aab3]126  if (! kbTest_i(bucket, 0)) return FALSE;
127  for (i=1; i<= (int) bucket->buckets_used; i++)
128  {
129    if (!kbTest_i(bucket, i)) return FALSE;
130    if (lm != NULL &&  bucket->buckets[i] != NULL
131        && p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) != 1)
132    {
[39e957]133      dReportError("Bucket %d larger or equal than lm", i);
134      if (p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) ==0)
[c7afb70]135        dReportError("Bucket %d equal to lm", i);
[35aab3]136      return FALSE;
137    }
138    if (!p_Test(bucket->buckets[i],bucket->bucket_ring))
139    {
140      dReportError("Bucket %d is not =0(4)", i);
141      return FALSE;
142    }
143  }
144
145  for (; i<=MAX_BUCKET; i++)
146  {
147    if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
148    {
149      dReportError("Bucket %d not zero", i);
150      return FALSE;
151    }
152  }
[c7afb70]153  for(i=0;i<=MAX_BUCKET;i++)
154  {
155    if (bucket->buckets[i]!=NULL)
156    {
157      int j;
158      for(j=i+1;j<=MAX_BUCKET;j++)
159      {
160        if (bucket->buckets[j]==bucket->buckets[i])
161        {
162          dReportError("Bucket %d %d equal", i,j);
163          return FALSE;
[473b74]164        }
[c7afb70]165      }
[473b74]166    }
[42ddd0]167    #ifdef HAVE_COEF_BUCKETS
[c7afb70]168    if (bucket->coef[i]!=NULL)
169    {
170      int j;
171      for(j=i+1;j<=MAX_BUCKET;j++)
172      {
173        if (bucket->coef[j]==bucket->coef[i])
174        {
175          dReportError("internal coef %d %d equal", i,j);
176          return FALSE;
[473b74]177        }
[c7afb70]178      }
[473b74]179    }
[42ddd0]180    #endif
[473b74]181  }
[35aab3]182  return TRUE;
183}
184
185#else // HAVE_PSEUDO_BUCKETS
186BOOLEAN kbTest(kBucket_pt bucket)
187{
188  return TRUE;
189}
190#endif // ! HAVE_PSEUDO_BUCKETS
191#endif // KDEBUG
192
193//////////////////////////////////////////////////////////////////////////
194///
195/// Creation/Destruction of buckets
196///
197
198kBucket_pt kBucketCreate(ring bucket_ring)
199{
200  assume(bucket_ring != NULL);
201  kBucket_pt bucket = (kBucket_pt) omAlloc0Bin(kBucket_bin);
202  bucket->bucket_ring = bucket_ring;
203  return bucket;
204}
205void kBucketDestroy(kBucket_pt *bucket_pt)
206{
207  omFreeBin(*bucket_pt, kBucket_bin);
208  *bucket_pt = NULL;
209}
210
211
212void kBucketDeleteAndDestroy(kBucket_pt *bucket_pt)
213{
214  kBucket_pt bucket = *bucket_pt;
215  kbTest(bucket);
216  int i;
217  for (i=0; i<= bucket->buckets_used; i++)
218  {
[42ddd0]219
[35aab3]220    if (bucket->buckets[i] != NULL)
221    {
222      p_Delete(&(bucket->buckets[i]), bucket->bucket_ring);
223#ifdef USE_COEF_BUCKETS
224      if (bucket->coef[i]!=NULL)
225        p_Delete(&(bucket->coef[i]), bucket->bucket_ring);
226#endif
227    }
228  }
229  omFreeBin(bucket, kBucket_bin);
230  *bucket_pt = NULL;
231}
232
233/////////////////////////////////////////////////////////////////////////////
234// Convertion from/to Bpolys
235//
236#ifndef HAVE_PSEUDO_BUCKETS
237
238inline void kBucketMergeLm(kBucket_pt bucket)
239{
[c7afb70]240  kbTest(bucket);
[35aab3]241  if (bucket->buckets[0] != NULL)
242  {
243    poly lm = bucket->buckets[0];
244    int i = 1;
245#ifdef BUCKET_TWO_BASE
246    int l = 2;
247    while ( bucket->buckets_length[i] >= l)
248    {
249      i++;
250      l = l << 1;
251    }
252#else
253    int l = 4;
254    while ( bucket->buckets_length[i] >= l)
255    {
256      i++;
257      l = l << 2;
258    }
259#endif
[924cca]260#ifndef USE_COEF_BUCKETS
[35aab3]261    MULTIPLY_BUCKET(bucket,i);
262    pNext(lm) = bucket->buckets[i];
263    bucket->buckets[i] = lm;
264    bucket->buckets_length[i]++;
265    assume(i <= bucket->buckets_used+1);
266    if (i > bucket->buckets_used)  bucket->buckets_used = i;
267    bucket->buckets[0] = NULL;
268    bucket->buckets_length[0] = 0;
[924cca]269    kbTest(bucket);
270#else
[473b74]271    if (i > bucket->buckets_used)  bucket->buckets_used = i;
272    assume(i!=0);
[c7afb70]273    if (bucket->buckets[i]!=NULL)
274    {
[473b74]275       MULTIPLY_BUCKET(bucket,i);
276       pNext(lm) = bucket->buckets[i];
277       bucket->buckets[i] = lm;
278       bucket->buckets_length[i]++;
279       assume(i <= bucket->buckets_used+1);
[c7afb70]280    }
281    else
282    {
[473b74]283      #if 1
284       assume(bucket->buckets[i]==NULL);
285       assume(bucket->coef[0]==NULL);
286       assume(pLength(lm)==1);
287       assume(pNext(lm)==NULL);
288       number coef=p_GetCoeff(lm,bucket->bucket_ring);
[9f1083]289       //WARNING: not thread_safe
[473b74]290       p_SetCoeff0(lm, n_Init(1,bucket->bucket_ring), bucket->bucket_ring);
291       bucket->buckets[i]=lm;
292       bucket->buckets_length[i]=1;
293       bucket->coef[i]=p_NSet(n_Copy(coef,bucket->bucket_ring),bucket->bucket_ring);
[26336c]294
[473b74]295       bucket->buckets[i]=lm;
296       bucket->buckets_length[i]=1;
[c7afb70]297      #else
[473b74]298       MULTIPLY_BUCKET(bucket,i);
299       pNext(lm) = bucket->buckets[i];
300       bucket->buckets[i] = lm;
301       bucket->buckets_length[i]++;
302       assume(i <= bucket->buckets_used+1);
[c7afb70]303      #endif
[473b74]304    }
305    bucket->buckets[0]=NULL;
306    bucket->buckets_length[0] = 0;
307    bucket->coef[0]=NULL;
308    kbTest(bucket);
[924cca]309    #endif
[35aab3]310  }
[924cca]311
[35aab3]312}
313
[86e6577]314BOOLEAN kBucketIsCleared(kBucket_pt bucket)
[35aab3]315{
316  int i;
317
318  for (i = 0;i<=MAX_BUCKET;i++)
319  {
320    if (bucket->buckets[i] != NULL) return FALSE;
[42ddd0]321    #ifdef HAVE_COEF_BUCKETS
[86e6577]322    if (bucket->coef[i] != NULL) return FALSE;
[42ddd0]323    #endif
[35aab3]324    if (bucket->buckets_length[i] != 0) return FALSE;
325  }
326  return TRUE;
327}
328
329void kBucketInit(kBucket_pt bucket, poly lm, int length)
330{
[473b74]331  //assume(false);
[35aab3]332  assume(bucket != NULL);
333  assume(length <= 0 || length == pLength(lm));
334  assume(kBucketIsCleared(bucket));
335
336  if (lm == NULL) return;
337
338  if (length <= 0)
339    length = pLength(lm);
340
341  bucket->buckets[0] = lm;
[42ddd0]342  #ifdef HAVE_COEF_BUCKETS
[86e6577]343  assume(bucket->coef[0]==NULL);
[42ddd0]344  #endif
345  #ifdef USE_COEF_BUCKETS
[86e6577]346  bucket->coef[0]=NULL;
[42ddd0]347  #endif
[86e6577]348  if (lm!=NULL)
349    bucket->buckets_length[0] = 1;
350  else
351    bucket->buckets_length[0]= 0;
[35aab3]352  if (length > 1)
353  {
354    unsigned int i = pLogLength(length-1);
355    bucket->buckets[i] = pNext(lm);
356    pNext(lm) = NULL;
357    bucket->buckets_length[i] = length-1;
358    bucket->buckets_used = i;
359  }
360  else
361  {
362    bucket->buckets_used = 0;
363  }
364}
365
366int kBucketCanonicalize(kBucket_pt bucket)
367{
[4ecd42]368  assume(bucket->buckets_used<=MAX_BUCKET);
[473b74]369  MULTIPLY_BUCKET(bucket,1);
[35aab3]370  kbTest(bucket);
371  poly p = bucket->buckets[1];
372  poly lm;
[86e6577]373  int pl = bucket->buckets_length[1];//, i;
374  int i;
[35aab3]375  bucket->buckets[1] = NULL;
376  bucket->buckets_length[1] = 0;
[c7afb70]377  #ifdef USE_COEF_BUCKETS
378    assume(bucket->coef[1]==NULL);
379  #endif
[35aab3]380  ring r=bucket->bucket_ring;
381
382
[473b74]383  for (i=1; i<=bucket->buckets_used; i++)
[35aab3]384  {
385  #ifdef USE_COEF_BUCKETS
386    if (bucket->coef[i]!=NULL)
387    {
[473b74]388      assume(bucket->buckets[i]!=NULL);
[35aab3]389      p = p_Plus_mm_Mult_qq(p, bucket->coef[i], bucket->buckets[i],
390                 pl, bucket->buckets_length[i], r);
391      p_Delete(&bucket->coef[i],r);
392      p_Delete(&bucket->buckets[i],r);
393    }
394    else
395    p = p_Add_q(p, bucket->buckets[i],
396                 pl, bucket->buckets_length[i], r);
397  #else
[dc5c491]398    p = p_Add_q(p, bucket->buckets[i],
[35aab3]399                 pl, bucket->buckets_length[i], r);
400  #endif
[473b74]401    if (i==1) continue;
[35aab3]402    bucket->buckets[i] = NULL;
403    bucket->buckets_length[i] = 0;
404  }
[42ddd0]405  #ifdef HAVE_COEF_BUCKETS
[86e6577]406  assume(bucket->coef[0]==NULL);
[42ddd0]407  #endif
[35aab3]408  lm = bucket->buckets[0];
409  if (lm != NULL)
410  {
411    pNext(lm) = p;
412    p = lm;
413    pl++;
414    bucket->buckets[0] = NULL;
415    bucket->buckets_length[0] = 0;
416  }
417  if (pl > 0)
418  {
419    i = pLogLength(pl);
420    bucket->buckets[i] = p;
421    bucket->buckets_length[i] = pl;
422  }
423  else
424  {
425    i = 0;
426  }
427  bucket->buckets_used = i;
[c7afb70]428  assume(bucket->buckets_used <= MAX_BUCKET);
429  #ifdef USE_COEF_BUCKETS
430    assume(bucket->coef[0]==NULL);
431    assume(bucket->coef[i]==NULL);
432  #endif
[35aab3]433  assume(pLength(p) == (int) pl);
[6ad5ce]434  //if (TEST_OPT_PROT) { Print("C(%d)",pl); }
[35aab3]435  kbTest(bucket);
436  return i;
437}
438
439void kBucketClear(kBucket_pt bucket, poly *p, int *length)
440{
441  int i = kBucketCanonicalize(bucket);
442  if (i > 0)
443  {
[f52579a]444  #ifdef USE_COEF_BUCKETS
445    MULTIPLY_BUCKET(bucket,i);
446    //bucket->coef[i]=NULL;
[6ad5ce]447  #endif
[35aab3]448    *p = bucket->buckets[i];
449    *length = bucket->buckets_length[i];
450    bucket->buckets[i] = NULL;
451    bucket->buckets_length[i] = 0;
452    bucket->buckets_used = 0;
[f52579a]453
[35aab3]454  }
455  else
456  {
457    *p = NULL;
458    *length = 0;
459  }
460}
461
462void kBucketSetLm(kBucket_pt bucket, poly lm)
463{
464  kBucketMergeLm(bucket);
465  pNext(lm) = NULL;
466  bucket->buckets[0] = lm;
467  bucket->buckets_length[0] = 1;
468}
469
470#else // HAVE_PSEUDO_BUCKETS
471
472void kBucketInit(kBucket_pt bucket, poly lm, int length)
473{
474  int i;
475
476  assume(bucket != NULL);
477  assume(length <= 0 || length == pLength(lm));
478
479  bucket->p = lm;
480  if (length <= 0) bucket->l = pLength(lm);
481  else bucket->l = length;
482
483}
484
485const poly kBucketGetLm(kBucket_pt bucket)
486{
487  return bucket->p;
488}
489
490poly kBucketExtractLm(kBucket_pt bucket)
491{
492  poly lm = bucket->p;
493  assume(pLength(bucket->p) == bucket->l);
494  pIter(bucket->p);
495  (bucket->l)--;
496  pNext(lm) = NULL;
497  return lm;
498}
499
500void kBucketClear(kBucket_pt bucket, poly *p, int *length)
501{
502  assume(pLength(bucket->p) == bucket->l);
503  *p = bucket->p;
504  *length = bucket->l;
505  bucket->p = NULL;
506  bucket->l = 0;
507}
508
509#endif // ! HAVE_PSEUDO_BUCKETS
510//////////////////////////////////////////////////////////////////////////
511///
512/// For changing the ring of the Bpoly to new_tailBin
513///
514void kBucketShallowCopyDelete(kBucket_pt bucket,
515                              ring new_tailRing, omBin new_tailBin,
516                              pShallowCopyDeleteProc p_shallow_copy_delete)
517{
518#ifndef HAVE_PSEUDO_BUCKETS
519  int i;
520
521  kBucketCanonicalize(bucket);
522  for (i=0; i<= bucket->buckets_used; i++)
523    if (bucket->buckets[i] != NULL)
524    {
525      MULTIPLY_BUCKET(bucket,i);
526      bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i],
527                                                 bucket->bucket_ring,
528                                                 new_tailRing,
529                                                 new_tailBin);
530    }
531#else
532  bucket->p = p_shallow_copy_delete(p,
533                                    bucket_ring,
534                                    new_tailRing,
535                                    new_tailBin);
536#endif
537  bucket->bucket_ring = new_tailRing;
538}
539
[cea6f3]540//////////////////////////////////////////////////////////////////////////
541///
542/// Bucket number i from bucket is out of length sync, resync
543///
544void kBucketAdjust(kBucket_pt bucket, int i) {
545
546  MULTIPLY_BUCKET(bucket,i);
[35aab3]547
[cea6f3]548  int l1 = bucket->buckets_length[i];
549  poly p1 = bucket->buckets[i];
550  bucket->buckets[i] = NULL;
551  bucket->buckets_length[i] = 0;
552  i = pLogLength(l1);
553
554  while (bucket->buckets[i] != NULL)
555  {
556    //kbTest(bucket);
557    MULTIPLY_BUCKET(bucket,i);
558    p1 = p_Add_q(p1, bucket->buckets[i],
559                 l1, bucket->buckets_length[i], bucket->bucket_ring);
560    bucket->buckets[i] = NULL;
561    bucket->buckets_length[i] = 0;
562    i = pLogLength(l1);
563  }
564
565  bucket->buckets[i] = p1;
566  bucket->buckets_length[i]=l1;
567  if (i >= bucket->buckets_used)
568    bucket->buckets_used = i;
569  else
570    kBucketAdjustBucketsUsed(bucket);
571}
[35aab3]572
573//////////////////////////////////////////////////////////////////////////
574///
575/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
576///
577void kBucket_Mult_n(kBucket_pt bucket, number n)
578{
579#ifndef HAVE_PSEUDO_BUCKETS
580  kbTest(bucket);
581  ring r=bucket->bucket_ring;
582  int i;
583
584  for (i=0; i<= bucket->buckets_used; i++)
585  {
586    if (bucket->buckets[i] != NULL)
587    {
588#ifdef USE_COEF_BUCKETS
[473b74]589      if (i<coef_start)
[35aab3]590        bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
[206e158]591#ifdef HAVE_RINGS
[271730]592        /* Frank Seelisch on March 11, 2010:
593           This looks a bit strange: The following "if" is indented
594           like the previous line of code. But coded as it is,
595           it should actually be two spaces less indented.
596           Question: Should the following "if" also only be
597           performed when "(i<coef_start)" is true?
598           For the time being, I leave it as it is. */
[58ea04]599        if (rField_is_Ring(r) && !(rField_is_Domain(r)))
[803cb2d]600        {
[cea6f3]601          bucket->buckets_length[i] = pLength(bucket->buckets[i]);
602          kBucketAdjust(bucket, i);
603        }
604#endif
[35aab3]605      else
606      if (bucket->coef[i]!=NULL)
607      {
608        bucket->coef[i] = p_Mult_nn(bucket->coef[i],n,r);
609      }
610      else
611      {
[1b82a2]612        bucket->coef[i] = p_NSet(n_Copy(n,r),r);
[35aab3]613      }
614#else
615      bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, r);
[009d80]616#ifdef HAVE_RINGS
[58ea04]617      if (rField_is_Ring(r) && !(rField_is_Domain(r)))
618      {
[cea6f3]619        bucket->buckets_length[i] = pLength(bucket->buckets[i]);
620        kBucketAdjust(bucket, i);
621      }
622#endif
[35aab3]623#endif
624    }
625  }
626  kbTest(bucket);
627#else
628  bucket->p = p_Mult_nn(bucket->p, n, bucket->bucket_ring);
629#endif
630}
631
632
633//////////////////////////////////////////////////////////////////////////
634///
[473b74]635/// Add to Bucket a poly ,i.e. Bpoly == q+Bpoly
[35aab3]636///
637void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
638{
639  if (q == NULL) return;
640  assume(*l <= 0 || pLength(q) == *l);
641
642  int i, l1;
643  ring r = bucket->bucket_ring;
644
645  if (*l <= 0)
646  {
647    l1 = pLength(q);
648    *l = l1;
649  }
650  else
651    l1 = *l;
652
653  kBucketMergeLm(bucket);
654  kbTest(bucket);
655  i = pLogLength(l1);
656
657  while (bucket->buckets[i] != NULL)
658  {
659    //MULTIPLY_BUCKET(bucket,i);
660  #ifdef USE_COEF_BUCKETS
661    if (bucket->coef[i]!=NULL)
662    {
663      q = p_Plus_mm_Mult_qq(q, bucket->coef[i], bucket->buckets[i],
664                 l1, bucket->buckets_length[i], r);
665      p_Delete(&bucket->coef[i],r);
666      p_Delete(&bucket->buckets[i],r);
667    }
668    else
669    q = p_Add_q(q, bucket->buckets[i],
670                 l1, bucket->buckets_length[i], r);
671  #else
672    q = p_Add_q(q, bucket->buckets[i],
673                 l1, bucket->buckets_length[i], r);
674  #endif
675    bucket->buckets[i] = NULL;
676    bucket->buckets_length[i] = 0;
677    i = pLogLength(l1);
[c7afb70]678    assume(i<= MAX_BUCKET);
679    assume(bucket->buckets_used<= MAX_BUCKET);
[35aab3]680  }
681
[6c39ff]682  kbTest(bucket);
[35aab3]683  bucket->buckets[i] = q;
684  bucket->buckets_length[i]=l1;
685  if (i >= bucket->buckets_used)
686    bucket->buckets_used = i;
687  else
688    kBucketAdjustBucketsUsed(bucket);
689  kbTest(bucket);
690}
691
692
693
694//////////////////////////////////////////////////////////////////////////
695///
696/// Bpoly == Bpoly - m*p; where m is a monom
697/// Does not destroy p and m
698/// assume (*l <= 0 || pLength(p) == *l)
699void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
700                            poly spNoether)
701{
702  assume(*l <= 0 || pLength(p) == *l);
703  int i, l1;
704  poly p1 = p;
705  ring r = bucket->bucket_ring;
706
707  if (*l <= 0)
708  {
709    l1 = pLength(p1);
710    *l = l1;
711  }
712  else
713    l1 = *l;
714
715  if (m == NULL || p == NULL) return;
716
717#ifndef HAVE_PSEUDO_BUCKETS
718  kBucketMergeLm(bucket);
719  kbTest(bucket);
720  i = pLogLength(l1);
721
[d5a330]722#if defined(HAVE_RINGS)||defined(HAVE_PLURAL)
723  if ((rField_is_Ring(r) && !(rField_is_Domain(r)))
724  ||(rIsPluralRing(r)))
[35aab3]725  {
[d5a330]726    pSetCoeff0(m, n_Neg(pGetCoeff(m),r->cf));
727    p1=pp_Mult_mm(p,m,r);
728    pSetCoeff0(m, n_Neg(pGetCoeff(m),r->cf));
729    l1=pLength(p1);
730    i = pLogLength(l1);
731  }
732  else
733#endif
734  {
735    if ((i <= bucket->buckets_used) && (bucket->buckets[i] != NULL))
736    {
737      assume(pLength(bucket->buckets[i])==bucket->buckets_length[i]);
[35aab3]738//#ifdef USE_COEF_BUCKETS
739//     if(bucket->coef[i]!=NULL)
740//     {
741//       poly mult=p_Mult_mm(bucket->coef[i],m,r);
742//       bucket->coef[i]=NULL;
743//       p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], mult, p1,
744//                               bucket->buckets_length[i], l1,
745//                             spNoether, r);
746//     }
747//     else
748//#endif
[d5a330]749      MULTIPLY_BUCKET(bucket,i);
750      p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
[35aab3]751                            bucket->buckets_length[i], l1,
752                            spNoether, r);
[d5a330]753      l1 = bucket->buckets_length[i];
754      bucket->buckets[i] = NULL;
755      bucket->buckets_length[i] = 0;
[35aab3]756      i = pLogLength(l1);
757    }
[abe5c8]758    else
759    {
[d5a330]760      pSetCoeff0(m, n_Neg(pGetCoeff(m),r->cf));
761      if (spNoether != NULL)
[009d80]762      {
[d5a330]763        l1 = -1;
764        p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r);
[009d80]765        i = pLogLength(l1);
766      }
[d5a330]767      else
[161e20]768      {
[d5a330]769        p1 = r->p_Procs->pp_Mult_mm(p1, m, r);
[161e20]770      }
[d5a330]771      pSetCoeff0(m, n_Neg(pGetCoeff(m),r->cf));
[cea6f3]772    }
[35aab3]773  }
774
775  while (bucket->buckets[i] != NULL)
776  {
777    //kbTest(bucket);
778    MULTIPLY_BUCKET(bucket,i);
779    p1 = p_Add_q(p1, bucket->buckets[i],
780                 l1, bucket->buckets_length[i], r);
781    bucket->buckets[i] = NULL;
782    bucket->buckets_length[i] = 0;
783    i = pLogLength(l1);
784  }
785
786  bucket->buckets[i] = p1;
787  bucket->buckets_length[i]=l1;
788  if (i >= bucket->buckets_used)
789    bucket->buckets_used = i;
790  else
791    kBucketAdjustBucketsUsed(bucket);
792#else // HAVE_PSEUDO_BUCKETS
793  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m,  p,
794                               bucket->l, l1,
795                               spNoether, r);
796#endif
797}
798
799//////////////////////////////////////////////////////////////////////////
800///
801/// Bpoly == Bpoly + m*p; where m is a monom
802/// Does not destroy p and m
803/// assume (l <= 0 || pLength(p) == l)
804void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
805{
[8227a9]806    assume((!rIsPluralRing(bucket->bucket_ring))||p_IsConstant(m, bucket->bucket_ring));
[35aab3]807  assume(l <= 0 || pLength(p) == l);
808  int i, l1;
809  poly p1 = p;
810  ring r = bucket->bucket_ring;
811
[26336c]812  if (m == NULL || p == NULL) return;
813
[35aab3]814  if (l <= 0)
815  {
816    l1 = pLength(p1);
817    l = l1;
818  }
819  else
820    l1 = l;
821
822  kBucketMergeLm(bucket);
823  kbTest(bucket);
824  i = pLogLength(l1);
[1b74f3]825  #ifdef USE_COEF_BUCKETS
[58ea04]826  number n=n_Init(1,r->cf);
[1b74f3]827  #endif
[35aab3]828  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
[26336c]829  {
[e8bfdb9]830    //if (FALSE){
[924cca]831    #ifdef USE_COEF_BUCKETS
[26336c]832    if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
833    {
834      number orig_coef=p_GetCoeff(bucket->coef[i],r);
835      //we take ownership:
836      p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
837      number add_coef=n_Copy(p_GetCoeff(m,r),r);
838      number gcd=n_Gcd(add_coef, orig_coef,r);
839
840      if (!(n_IsOne(gcd,r)))
841      {
[2d3e75]842        number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
843        number add_coef2=n_ExactDiv(add_coef, gcd,r);
[e8bfdb9]844        n_Delete(&orig_coef,r);
[26336c]845        n_Delete(&add_coef,r);
846        orig_coef=orig_coef2;
847        add_coef=add_coef2;
[e8bfdb9]848
[26336c]849        //p_Mult_nn(bucket->buckets[i], orig_coef,r);
850        n_Delete(&n,r);
851        n=gcd;
852      }
853
854      //assume(n_IsOne(n,r));
855      number backup=p_GetCoeff(m,r);
856
857      p_SetCoeff0(m,add_coef,r);
858      bucket->buckets[i]=p_Mult_nn(bucket->buckets[i],orig_coef,r);
859
860      n_Delete(&orig_coef,r);
861      p_Delete(&bucket->coef[i],r);
862
863      p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
[e8bfdb9]864                           bucket->buckets_length[i], l1, r);
[26336c]865      l1=bucket->buckets_length[i];
866      bucket->buckets[i]=NULL;
867      bucket->buckets_length[i] = 0;
868      i = pLogLength(l1);
869      assume(l1==pLength(p1));
870
871      p_SetCoeff(m,backup,r); //deletes add_coef
[e8bfdb9]872    }
[26336c]873    else
[924cca]874    #endif
[26336c]875    {
876      MULTIPLY_BUCKET(bucket,i);
877      p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
[35aab3]878                           bucket->buckets_length[i], l1, r);
[26336c]879      l1 = bucket->buckets_length[i];
880      bucket->buckets[i] = NULL;
881      bucket->buckets_length[i] = 0;
882      i = pLogLength(l1);
[e8bfdb9]883    }
[35aab3]884  }
[8227a9]885
[35aab3]886  else
887  {
[b8214b]888    #ifdef USE_COEF_BUCKETS
[f52579a]889    number swap_n=p_GetCoeff(m,r);
[26336c]890
[f52579a]891    assume(n_IsOne(n,r));
892    p_SetCoeff0(m,n,r);
893    n=swap_n;
894    //p_SetCoeff0(n, swap_n, r);
895    //p_GetCoeff0(n, swap_n,r);
[b8214b]896    #endif
[abe5c8]897    p1 = r->p_Procs->pp_Mult_mm(p1, m, r);
[b8214b]898    #ifdef USE_COEF_BUCKETS
[86e6577]899    //m may not be changed
900    p_SetCoeff(m,n_Copy(n,r),r);
[b8214b]901    #endif
[35aab3]902  }
[8227a9]903
[35aab3]904
[ab716ed]905  while ((bucket->buckets[i] != NULL) && (p1!=NULL))
[35aab3]906  {
[86e6577]907    assume(i!=0);
[924cca]908    #ifdef USE_COEF_BUCKETS
[26336c]909    if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
910    {
911      number orig_coef=p_GetCoeff(bucket->coef[i],r);
912      //we take ownership:
913      p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
[81b5cc]914      number add_coef=n_Copy(n,r);
[26336c]915      number gcd=n_Gcd(add_coef, orig_coef,r);
916
917      if (!(n_IsOne(gcd,r)))
918      {
[2d3e75]919        number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
920        number add_coef2=n_ExactDiv(add_coef, gcd,r);
[ab716ed]921        n_Delete(&orig_coef,r);
[81b5cc]922        n_Delete(&n,r);
[26336c]923        n_Delete(&add_coef,r);
924        orig_coef=orig_coef2;
925        add_coef=add_coef2;
926        //p_Mult_nn(bucket->buckets[i], orig_coef,r);
927        n=gcd;
928      }
929      //assume(n_IsOne(n,r));
930      bucket->buckets[i]=p_Mult_nn(bucket->buckets[i],orig_coef,r);
931      p1=p_Mult_nn(p1,add_coef,r);
932
933      p1 = p_Add_q(p1, bucket->buckets[i],r);
934      l1=pLength(p1);
935
936      bucket->buckets[i]=NULL;
937      n_Delete(&orig_coef,r);
938      p_Delete(&bucket->coef[i],r);
939      //l1=bucket->buckets_length[i];
940      assume(l1==pLength(p1));
941    }
942    else
[924cca]943    #endif
[26336c]944    {
945      //don't do that, pull out gcd
[924cca]946      #ifdef USE_COEF_BUCKETS
[26336c]947      if(!(n_IsOne(n,r)))
948      {
[f52579a]949        p1=p_Mult_nn(p1, n, r);
950        n_Delete(&n,r);
951        n=n_Init(1,r);
[26336c]952      }
[924cca]953      #endif
[26336c]954      MULTIPLY_BUCKET(bucket,i);
955      p1 = p_Add_q(p1, bucket->buckets[i],
[35aab3]956                 l1, bucket->buckets_length[i], r);
[26336c]957      bucket->buckets[i] = NULL;
958      bucket->buckets_length[i] = 0;
[ab716ed]959    }
[26336c]960    i = pLogLength(l1);
[35aab3]961  }
962
963  bucket->buckets[i] = p1;
[924cca]964#ifdef USE_COEF_BUCKETS
[f52579a]965  assume(bucket->coef[i]==NULL);
[8227a9]966
[26336c]967  if (!(n_IsOne(n,r)))
968  {
[f52579a]969    bucket->coef[i]=p_NSet(n,r);
[26336c]970  }
971  else
972  {
[f52579a]973    bucket->coef[i]=NULL;
974    n_Delete(&n,r);
975  }
[8227a9]976
[26336c]977  if ((p1==NULL) && (bucket->coef[i]!=NULL))
978    p_Delete(&bucket->coef[i],r);
[42ddd0]979#endif
[35aab3]980  bucket->buckets_length[i]=l1;
981  if (i >= bucket->buckets_used)
982    bucket->buckets_used = i;
983  else
984    kBucketAdjustBucketsUsed(bucket);
985
986  kbTest(bucket);
987}
988
989poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
990{
991  if (q == NULL) return append;
992  poly lm;
993  loop
994  {
995    lm = kBucketGetLm(bucket);
996    if (lm == NULL) return append;
997    if (p_LmCmp(lm, q, bucket->bucket_ring) == 1)
998    {
999      lm = kBucketExtractLm(bucket);
1000      pNext(append) = lm;
1001      pIter(append);
1002    }
1003    else
1004    {
1005      return append;
1006    }
1007  }
1008}
1009
1010/////////////////////////////////////////////////////////////////////////////
1011//
1012// Extract all monomials from bucket with component comp
1013// Return as a polynomial *p with length *l
1014// In other words, afterwards
1015// Bpoly = Bpoly - (poly consisting of all monomials with component comp)
1016// and components of monomials of *p are all 0
1017//
1018
1019// Hmm... for now I'm too lazy to implement those independent of currRing
1020// But better declare it extern than including polys.h
[dd693a]1021extern void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r);
[35aab3]1022
1023void kBucketTakeOutComp(kBucket_pt bucket,
[0b5e3d]1024                        long comp,
[35aab3]1025                        poly *r_p, int *l)
1026{
1027  poly p = NULL, q;
1028  int i, lp = 0, lq;
1029
1030#ifndef HAVE_PSEUDO_BUCKETS
1031  kBucketMergeLm(bucket);
1032  for (i=1; i<=bucket->buckets_used; i++)
1033  {
1034    if (bucket->buckets[i] != NULL)
1035    {
1036      MULTIPLY_BUCKET(bucket,i);
[dd693a]1037      p_TakeOutComp(&(bucket->buckets[i]), comp, &q, &lq, bucket->bucket_ring);
[35aab3]1038      if (q != NULL)
1039      {
1040        assume(pLength(q) == lq);
1041        bucket->buckets_length[i] -= lq;
1042        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
1043        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
1044      }
1045    }
1046  }
1047  kBucketAdjustBucketsUsed(bucket);
1048#else
[dd693a]1049  p_TakeOutComp(&(bucket->p), comp, &p, &lp,bucket->bucket_ring);
[35aab3]1050  (bucket->l) -= lp;
1051#endif
1052  *r_p = p;
1053  *l = lp;
1054
1055  kbTest(bucket);
1056}
1057
1058/////////////////////////////////////////////////////////////////////////////
1059// Reduction of Bpoly with a given poly
1060//
1061
1062extern int ksCheckCoeff(number *a, number *b);
1063
1064number kBucketPolyRed(kBucket_pt bucket,
1065                      poly p1, int l1,
1066                      poly spNoether)
1067{
[58ea04]1068  ring r=bucket->bucket_ring;
1069  assume((!rIsPluralRing(r))||p_LmEqual(p1,kBucketGetLm(bucket), r));
[35aab3]1070  assume(p1 != NULL &&
[58ea04]1071         p_DivisibleBy(p1,  kBucketGetLm(bucket), r));
[35aab3]1072  assume(pLength(p1) == (int) l1);
1073
1074  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
1075  BOOLEAN reset_vec=FALSE;
1076  number rn;
1077
[1b38b23]1078  /* we shall reduce bucket=bn*lm+... by p1=an*t+a1 where t=lm(p1)
1079     and an,bn shall be defined further down only if lc(p1)!=1
1080     we already know: an|bn and t|lm */
[35aab3]1081  if(a1==NULL)
1082  {
[58ea04]1083    p_LmDelete(&lm, r);
1084    return n_Init(1,r->cf);
[35aab3]1085  }
1086
[58ea04]1087  if (! n_IsOne(pGetCoeff(p1),r->cf))
[35aab3]1088  {
1089    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
[803cb2d]1090//StringSetS("##### an = "); nWrite(an); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
1091//StringSetS("##### bn = "); nWrite(bn); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
[1b38b23]1092    /* ksCheckCoeff: divide out gcd from an and bn: */
[0ebd7e]1093    int ct = ksCheckCoeff(&an, &bn,r->cf);
[1b38b23]1094    /* the previous command returns ct=0 or ct=2 iff an!=1
1095       note: an is now 1 or -1 */
1096
1097    /* setup factor for p1 which cancels leading terms */
[58ea04]1098    p_SetCoeff(lm, bn, r);
[cfbee28]1099    if ((ct == 0) || (ct == 2))
1100    {
[1b38b23]1101      /* next line used to be here before but is WRONG:
[e3ab44]1102      kBucket_Mult_n(bucket, an);
[1b38b23]1103        its use would result in a wrong sign for the tail of bucket
1104        in the reduction */
1105
1106      /* correct factor for cancelation by changing sign if an=-1 */
[58ea04]1107      if (rField_is_Ring(r))
1108        lm = p_Mult_nn(lm, an, r);
[aba0db]1109      else
[e3ab44]1110        kBucket_Mult_n(bucket, an);
[cfbee28]1111    }
[35aab3]1112    rn = an;
1113  }
1114  else
1115  {
[58ea04]1116    rn = n_Init(1,r->cf);
[35aab3]1117  }
1118
[58ea04]1119  if (p_GetComp(p1, r) != p_GetComp(lm, r))
[35aab3]1120  {
[58ea04]1121    p_SetCompP(a1, p_GetComp(lm, r), r);
[35aab3]1122    reset_vec = TRUE;
[58ea04]1123    p_SetComp(lm, p_GetComp(p1, r), r);
1124    p_Setm(lm, r);
[35aab3]1125  }
1126
[58ea04]1127  p_ExpVectorSub(lm, p1, r);
[35aab3]1128  l1--;
1129
[9f1083]1130  assume(l1==pLength(a1));
[cc4cc80]1131#if 0
[9f1083]1132  BOOLEAN backuped=FALSE;
1133  number coef;
[ab10f7b]1134  //@Viktor, don't ignore coefficients on monomials
[9f1083]1135  if(l1==1) {
[8227a9]1136
[58ea04]1137    //if (rField_is_Q(r)) {
[9f1083]1138      //avoid this for function fields, as gcds are expensive at the moment
[8227a9]1139
1140
[58ea04]1141      coef=p_GetCoeff(a1,r);
1142      lm=p_Mult_nn(lm, coef, r);
1143      p_SetCoeff0(a1, n_Init(1,r), r);
[9f1083]1144      backuped=TRUE;
1145      //WARNING: not thread_safe
1146    //deletes coef as side effect
1147    //}
1148  }
[cc4cc80]1149#endif
[1b38b23]1150
[9f1083]1151  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
[8227a9]1152
[cc4cc80]1153#if 0
[9f1083]1154  if (backuped)
[58ea04]1155    p_SetCoeff0(a1,coef,r);
[cc4cc80]1156#endif
1157
[58ea04]1158  p_LmDelete(&lm, r);
1159  if (reset_vec) p_SetCompP(a1, 0, r);
[35aab3]1160  kbTest(bucket);
1161  return rn;
1162}
[654726]1163
1164#ifndef USE_COEF_BUCKETS
1165void kBucketSimpleContent(kBucket_pt) {}
1166#else
[8227a9]1167static BOOLEAN nIsPseudoUnit(number n, ring r)
1168{
1169  if (rField_is_Zp(r))
[473b74]1170    return TRUE;
[4c6e420]1171
1172  if (rParameter(r)==NULL)
[8227a9]1173  {
[4c6e420]1174    return (n_Size(n,r->cf)==1);
[8227a9]1175  }
1176  //if (r->parameter!=NULL)
[58ea04]1177  return (n_IsOne(n,r->cf) || n_IsMOne(n,r->cf));
[473b74]1178}
[26336c]1179
1180void kBucketSimpleContent(kBucket_pt bucket)
1181{
[2e4de3d]1182  ring r=bucket->bucket_ring;
[26336c]1183  int i;
1184  //PrintS("HHHHHHHHHHHHH");
1185  for (i=0;i<=MAX_BUCKET;i++)
1186  {
1187    //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
1188    //    PrintS("H2H2H2");
1189    if (i==0)
1190    {
1191      assume(bucket->buckets[i]==NULL);
[473b74]1192    }
[26336c]1193    if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]==NULL))
1194      return;
1195  }
[2e4de3d]1196  for (i=0;i<=MAX_BUCKET;i++)
1197  {
1198    //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
1199    //    PrintS("H2H2H2");
1200    if (i==0)
1201    {
1202      assume(bucket->buckets[i]==NULL);
1203    }
[8227a9]1204    if ((bucket->buckets[i]!=NULL)
1205    && (nIsPseudoUnit(p_GetCoeff(bucket->coef[i],r),r)))
[2e4de3d]1206      return;
1207  }
[26336c]1208  //return;
[8227a9]1209
[26336c]1210  number coef=n_Init(0,r);
1211  //ATTENTION: will not work correct for GB over ring
1212  //if (TEST_OPT_PROT)
1213  //    PrintS("CCCCCCCCCCCCC");
[4c8d61]1214  for (i=MAX_BUCKET;i>=0;i--)
[26336c]1215  {
1216    if (i==0)
1217    {
1218      assume(bucket->buckets[i]==NULL);
[473b74]1219    }
[26336c]1220    if (bucket->buckets[i]!=NULL)
1221    {
1222      assume(bucket->coef[i]!=NULL);
[4c8d61]1223      assume(!(n_IsZero(pGetCoeff(bucket->coef[i]),r)));
[8227a9]1224
[26336c]1225      //in this way it should crash on programming errors, yeah
[32d07a5]1226      number temp=n_Gcd(coef, pGetCoeff(bucket->coef[i]),r);
[26336c]1227      n_Delete(&coef,r );
1228      coef=temp;
1229      if (nIsPseudoUnit(coef,r))
1230      {
1231        n_Delete(&coef,r);
1232        return;
1233      }
[4c8d61]1234      assume(!(n_IsZero(coef,r)));
[473b74]1235    }
[26336c]1236  }
[086a96]1237  if (n_IsZero(coef,r))
1238  {
[75a3fb7]1239    n_Delete(&coef,r);
1240    return;
[086a96]1241  }
[26336c]1242  if (TEST_OPT_PROT)
1243    PrintS("S");
1244  for(i=0;i<=MAX_BUCKET;i++)
1245  {
1246    if (bucket->buckets[i]!=NULL)
1247    {
[4c8d61]1248      assume(!(n_IsZero(coef,r)));
[26336c]1249      assume(bucket->coef[i]!=NULL);
1250      number lc=p_GetCoeff(bucket->coef[i],r);
[2d3e75]1251      p_SetCoeff(bucket->coef[i], n_ExactDiv(lc,coef,r),r);
[4c8d61]1252      assume(!(n_IsZero(p_GetCoeff(bucket->coef[i],r),r)));
[26336c]1253    }
1254  }
[9f1083]1255  n_Delete(&coef,r);
[473b74]1256}
[0276c1]1257#endif
[35aab3]1258
1259
[26336c]1260poly kBucketExtractLmOfBucket(kBucket_pt bucket, int i)
1261{
1262  assume(bucket->buckets[i]!=NULL);
1263
1264  poly p=bucket->buckets[i];
1265  bucket->buckets_length[i]--;
[42ddd0]1266#ifdef USE_COEF_BUCKETS
[1b74f3]1267  ring r=bucket->bucket_ring;
[26336c]1268  if (bucket->coef[i]!=NULL)
1269  {
1270    poly next=pNext(p);
1271    if (next==NULL)
1272    {
1273      MULTIPLY_BUCKET(bucket,i);
1274      p=bucket->buckets[i];
1275      bucket->buckets[i]=NULL;
1276      return p;
1277    }
1278    else
1279    {
1280      bucket->buckets[i]=next;
1281      number c=p_GetCoeff(bucket->coef[i],r);
1282      pNext(p)=NULL;
1283      p=p_Mult_nn(p,c,r);
1284      assume(p!=NULL);
1285      return p;
[39e957]1286    }
[26336c]1287  }
1288  else
[42ddd0]1289#endif
[26336c]1290  {
1291    bucket->buckets[i]=pNext(bucket->buckets[i]);
1292    pNext(p)=NULL;
1293    assume(p!=NULL);
1294    return p;
1295  }
1296}
[0ebd7e]1297
1298/*
1299* input - output: a, b
1300* returns:
1301*   a := a/gcd(a,b), b := b/gcd(a,b)
1302*   and return value
1303*       0  ->  a != 1,  b != 1
1304*       1  ->  a == 1,  b != 1
1305*       2  ->  a != 1,  b == 1
1306*       3  ->  a == 1,  b == 1
1307*   this value is used to control the spolys
1308*/
1309int ksCheckCoeff(number *a, number *b, const coeffs r)
1310{
1311  int c = 0;
1312  number an = *a, bn = *b;
1313  n_Test(an,r);
1314  n_Test(bn,r);
1315
1316  number cn = n_Gcd(an, bn, r);
1317
1318  if(n_IsOne(cn, r))
1319  {
1320    an = n_Copy(an, r);
1321    bn = n_Copy(bn, r);
1322  }
1323  else
1324  {
[8ee887]1325    an = n_Div(an, cn, r); n_Normalize(an,r);
1326    bn = n_Div(bn, cn, r); n_Normalize(bn,r);
[0ebd7e]1327  }
1328  n_Delete(&cn, r);
1329  if (n_IsOne(an, r))
1330  {
1331    c = 1;
1332  }
1333  if (n_IsOne(bn, r))
1334  {
1335    c += 2;
1336  }
1337  *a = an;
1338  *b = bn;
1339  return c;
1340}
1341
Note: See TracBrowser for help on using the repository browser.