source: git/libpolys/polys/kbuckets.cc @ 18dab28

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