My Project
kbuckets.cc
Go to the documentation of this file.
1 /****************************************
2 * Computer Algebra System SINGULAR *
3 ****************************************/
4 
5 #include "misc/auxiliary.h"
6 #include "misc/options.h"
7 
9 #include "coeffs/coeffs.h"
10 #include "coeffs/numbers.h"
11 #include "polys/monomials/ring.h"
12 #include "polys/kbuckets.h"
13 
14 #ifdef HAVE_SHIFTBBA
15 #include "polys/shiftop.h"
16 #endif
17 
18 #ifdef HAVE_COEF_BUCKETS
19 #define USE_COEF_BUCKETS
20 #endif
21 
22 #ifdef USE_COEF_BUCKETS
23 #ifdef HAVE_RINGS_OLD
24 #define MULTIPLY_BUCKET(B,I) do \
25  { if (B->coef[I]!=NULL) \
26  { \
27  assume(p_IsConstant(B->Coef[i],B->bucket->ring)); \
28  B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
29  B->coef[I]=NULL; \
30  } \
31  } while(0) \
32  if (rField_is_Ring(B->bucket_ring)) B->buckets_length[i] = pLength(B->buckets[i]);
33 #else
34 #define MULTIPLY_BUCKET(B,I) do \
35  { if (B->coef[I]!=NULL) \
36  { \
37  B->buckets[I]=p_Mult_q(B->buckets[I],B->coef[I],B->bucket_ring); \
38  B->coef[I]=NULL; \
39  } \
40  } while(0)
41 #endif
42 #else
43 #define MULTIPLY_BUCKET(B,I)
44 #endif
46 #ifdef USE_COEF_BUCKETS
47 STATIC_VAR int coef_start=1;
48 #endif
49 //////////////////////////////////////////////////////////////////////////
50 ///
51 /// Some internal stuff
52 ///
53 
54 // https://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
55 #ifndef BUCKET_TWO_BASE
56 static inline int LOG4(int v)
57 {
58  const unsigned int b[] = {0x2, 0xC, 0xF0, 0xFF00, 0xFFFF0000};
59  const unsigned int S[] = {1, 2, 4, 8, 16};
60 
61  unsigned int r = 0; // result of log4(v) will go here
62  if (v & b[4]) { v >>= S[4]; r |= S[3]; }
63  if (v & b[3]) { v >>= S[3]; r |= S[2]; }
64  if (v & b[2]) { v >>= S[2]; r |= S[1]; }
65  if (v & b[1]) { v >>= S[1]; r |= S[0]; }
66  return (int)r;
67 }
68 #endif
69 
70 // returns ceil(log_4(l))
71 static inline unsigned int pLogLength(unsigned int l)
72 {
73  unsigned int i = 0;
74 
75  if (l == 0) return 0;
76  l--;
77 #ifdef BUCKET_TWO_BASE
78  i=SI_LOG2(l);
79 #else
80  i=LOG4(l);
81 #endif
82  return i+1;
83 }
84 
85 // returns ceil(log_4(pLength(p)))
86 static inline unsigned int pLogLength(poly p)
87 {
88  return pLogLength((unsigned int) pLength(p));
89 }
90 
91 #ifdef KDEBUG
92 
93 #ifndef HAVE_PSEUDO_BUCKETS
94 BOOLEAN kbTest_i(kBucket_pt bucket, int i)
95 {//sBucketSortMerge
96  #ifdef USE_COEF_BUCKETS
97  assume(bucket->coef[0]==NULL);
98  if ((bucket->coef[i]!=NULL) && (bucket->buckets[i]==NULL))
99  {
100  dReportError("Bucket %d coef not NULL", i);
101  }
102  if (bucket->coef[i]!=NULL)
103  {
104  assume(bucket->buckets[i]!=NULL);
105  p_Test(bucket->coef[i],bucket->bucket_ring);
106  }
107  #endif
108  pFalseReturn(p_Test(bucket->buckets[i], bucket->bucket_ring));
109  if ((unsigned)bucket->buckets_length[i] != pLength(bucket->buckets[i]))
110  {
111  dReportError("Bucket %d lengths difference should:%d has:%d",
112  i, bucket->buckets_length[i], pLength(bucket->buckets[i]));
113  }
114  else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
115  {
116  dReportError("Bucket %d too long %d",
117  i, bucket->buckets_length[i]);
118  }
119  if (i==0 && bucket->buckets_length[0] > 1)
120  {
121  dReportError("Bucket 0 too long");
122  }
123  return TRUE;
124 }
125 
126 
127 BOOLEAN kbTest(kBucket_pt bucket)
128 {
129  #ifdef HAVE_COEF_BUCKETS
130  assume(bucket->coef[0]==NULL);
131  #endif
132  int i;
133  poly lm = bucket->buckets[0];
134 
135  omCheckAddrBin(bucket, kBucket_bin);
136  assume(bucket->buckets_used <= MAX_BUCKET);
137  if (! kbTest_i(bucket, 0)) return FALSE;
138  for (i=1; i<= (int) bucket->buckets_used; i++)
139  {
140  if (!kbTest_i(bucket, i)) return FALSE;
141  if (lm != NULL && bucket->buckets[i] != NULL
142  && p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) != 1)
143  {
144  dReportError("Bucket %d larger or equal than lm", i);
145  if (p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) ==0)
146  dReportError("Bucket %d equal to lm", i);
147  return FALSE;
148  }
149  if (!p_Test(bucket->buckets[i],bucket->bucket_ring))
150  {
151  dReportError("Bucket %d is not =0(4)", i);
152  return FALSE;
153  }
154  }
155 
156  for (; i<=MAX_BUCKET; i++)
157  {
158  if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
159  {
160  dReportError("Bucket %d not zero", i);
161  return FALSE;
162  }
163  }
164  for(i=0;i<=MAX_BUCKET;i++)
165  {
166  if (bucket->buckets[i]!=NULL)
167  {
168  int j;
169  for(j=i+1;j<=MAX_BUCKET;j++)
170  {
171  if (bucket->buckets[j]==bucket->buckets[i])
172  {
173  dReportError("Bucket %d %d equal", i,j);
174  return FALSE;
175  }
176  }
177  }
178  #ifdef HAVE_COEF_BUCKETS
179  if (bucket->coef[i]!=NULL)
180  {
181  int j;
182  for(j=i+1;j<=MAX_BUCKET;j++)
183  {
184  if (bucket->coef[j]==bucket->coef[i])
185  {
186  dReportError("internal coef %d %d equal", i,j);
187  return FALSE;
188  }
189  }
190  }
191  #endif
192  }
193  return TRUE;
194 }
195 
196 #else // HAVE_PSEUDO_BUCKETS
198 {
199  return TRUE;
200 }
201 #endif // ! HAVE_PSEUDO_BUCKETS
202 #endif // KDEBUG
203 
204 //////////////////////////////////////////////////////////////////////////
205 ///
206 /// Creation/Destruction of buckets
207 ///
208 
209 kBucket_pt kBucketCreate(const ring bucket_ring)
210 {
211  assume(bucket_ring != NULL);
213  bucket->bucket_ring = bucket_ring;
214  return bucket;
215 }
216 void kBucketDestroy(kBucket_pt *bucket_pt)
217 {
218  omFreeBin(*bucket_pt, kBucket_bin);
219  *bucket_pt = NULL;
220 }
221 
222 
224 {
225  kBucket_pt bucket = *bucket_pt;
226  kbTest(bucket);
227  int i;
228  for (i=0; i<= bucket->buckets_used; i++)
229  {
230  p_Delete(&(bucket->buckets[i]), bucket->bucket_ring);
231 #ifdef USE_COEF_BUCKETS
232  p_Delete(&(bucket->coef[i]), bucket->bucket_ring);
233 #endif
234  }
235  omFreeBin(bucket, kBucket_bin);
236  *bucket_pt = NULL;
237 }
238 
239 /////////////////////////////////////////////////////////////////////////////
240 // Convertion from/to Bpolys
241 //
242 #ifndef HAVE_PSEUDO_BUCKETS
243 
244 inline void kBucketMergeLm(kBucket_pt bucket)
245 {
246  kbTest(bucket);
247  if (bucket->buckets[0] != NULL)
248  {
249  poly lm = bucket->buckets[0];
250  int i = 1;
251 #ifdef BUCKET_TWO_BASE
252  int l = 2;
253  while ( bucket->buckets_length[i] >= l)
254  {
255  i++;
256  l = l << 1;
257  }
258 #else
259  int l = 4;
260  while ( bucket->buckets_length[i] >= l)
261  {
262  i++;
263  l = l << 2;
264  }
265 #endif
266 #ifndef USE_COEF_BUCKETS
267  MULTIPLY_BUCKET(bucket,i);
268  pNext(lm) = bucket->buckets[i];
269  bucket->buckets[i] = lm;
270  bucket->buckets_length[i]++;
271  assume(i <= bucket->buckets_used+1);
272  if (i > bucket->buckets_used) bucket->buckets_used = i;
273  bucket->buckets[0] = NULL;
274  bucket->buckets_length[0] = 0;
275  kbTest(bucket);
276 #else
277  if (i > bucket->buckets_used) bucket->buckets_used = i;
278  assume(i!=0);
279  if (bucket->buckets[i]!=NULL)
280  {
281  MULTIPLY_BUCKET(bucket,i);
282  pNext(lm) = bucket->buckets[i];
283  bucket->buckets[i] = lm;
284  bucket->buckets_length[i]++;
285  assume(i <= bucket->buckets_used+1);
286  }
287  else
288  {
289  #if 1
290  assume(bucket->buckets[i]==NULL);
291  assume(bucket->coef[0]==NULL);
292  assume(pLength(lm)==1);
293  assume(pNext(lm)==NULL);
294  number coef=p_GetCoeff(lm,bucket->bucket_ring);
295  //WARNING: not thread_safe
296  p_SetCoeff0(lm, n_Init(1,bucket->bucket_ring), bucket->bucket_ring);
297  bucket->buckets[i]=lm;
298  bucket->buckets_length[i]=1;
299  bucket->coef[i]=p_NSet(n_Copy(coef,bucket->bucket_ring),bucket->bucket_ring);
300 
301  bucket->buckets[i]=lm;
302  bucket->buckets_length[i]=1;
303  #else
304  MULTIPLY_BUCKET(bucket,i);
305  pNext(lm) = bucket->buckets[i];
306  bucket->buckets[i] = lm;
307  bucket->buckets_length[i]++;
308  assume(i <= bucket->buckets_used+1);
309  #endif
310  }
311  bucket->buckets[0]=NULL;
312  bucket->buckets_length[0] = 0;
313  bucket->coef[0]=NULL;
314  kbTest(bucket);
315  #endif
316  }
317 
318 }
319 
321 {
322  int i;
323 
324  for (i = 0;i<=MAX_BUCKET;i++)
325  {
326  if (bucket->buckets[i] != NULL) return FALSE;
327  #ifdef HAVE_COEF_BUCKETS
328  if (bucket->coef[i] != NULL) return FALSE;
329  #endif
330  if (bucket->buckets_length[i] != 0) return FALSE;
331  }
332  return TRUE;
333 }
334 
335 void kBucketInit(kBucket_pt bucket, poly lm, int length)
336 {
337  //assume(false);
338  assume(bucket != NULL);
339  assume(length <= 0 || (unsigned)length == pLength(lm));
340  assume(kBucketIsCleared(bucket));
341 
342  if (lm == NULL) return;
343 
344  if (length <= 0)
345  length = pLength(lm);
346 
347  bucket->buckets[0] = lm;
348  #ifdef HAVE_COEF_BUCKETS
349  assume(bucket->coef[0]==NULL);
350  #endif
351  #ifdef USE_COEF_BUCKETS
352  bucket->coef[0]=NULL;
353  #endif
354  if (lm!=NULL)
355  bucket->buckets_length[0] = 1;
356  else
357  bucket->buckets_length[0]= 0;
358  if (length > 1)
359  {
360  unsigned int i = pLogLength(length-1);
361  bucket->buckets[i] = pNext(lm);
362  pNext(lm) = NULL;
363  bucket->buckets_length[i] = length-1;
364  bucket->buckets_used = i;
365  }
366  else
367  {
368  bucket->buckets_used = 0;
369  }
370 }
371 
373 {
374 #ifndef HAVE_PSEUDO_BUCKETS
375  assume(bucket->buckets_used<=MAX_BUCKET);
376  MULTIPLY_BUCKET(bucket,1);
377  kbTest(bucket);
378  poly p = bucket->buckets[1];
379  poly lm;
380  int pl = bucket->buckets_length[1];//, i;
381  int i;
382  bucket->buckets[1] = NULL;
383  bucket->buckets_length[1] = 0;
384  #ifdef USE_COEF_BUCKETS
385  assume(bucket->coef[1]==NULL);
386  #endif
387  ring r=bucket->bucket_ring;
388 
389 
390  for (i=1; i<=bucket->buckets_used; i++)
391  {
392  #ifdef USE_COEF_BUCKETS
393  if (bucket->coef[i]!=NULL)
394  {
395  assume(bucket->buckets[i]!=NULL);
396  p = p_Plus_mm_Mult_qq(p, bucket->coef[i], bucket->buckets[i],
397  pl, bucket->buckets_length[i], r);
398  p_Delete(&bucket->coef[i],r);
399  p_Delete(&bucket->buckets[i],r);
400  }
401  else
402  p = p_Add_q(p, bucket->buckets[i],
403  pl, bucket->buckets_length[i], r);
404  #else
405  p = p_Add_q(p, bucket->buckets[i],
406  pl, bucket->buckets_length[i], r);
407  #endif
408  if (i==1) continue;
409  bucket->buckets[i] = NULL;
410  bucket->buckets_length[i] = 0;
411  }
412  #ifdef HAVE_COEF_BUCKETS
413  assume(bucket->coef[0]==NULL);
414  #endif
415  lm = bucket->buckets[0];
416  if (lm != NULL)
417  {
418  pNext(lm) = p;
419  p = lm;
420  pl++;
421  bucket->buckets[0] = NULL;
422  bucket->buckets_length[0] = 0;
423  }
424  if (pl > 0)
425  {
426  i = pLogLength(pl);
427  bucket->buckets[i] = p;
428  bucket->buckets_length[i] = pl;
429  }
430  else
431  {
432  i = 0;
433  }
434  bucket->buckets_used = i;
435  assume(bucket->buckets_used <= MAX_BUCKET);
436  #ifdef USE_COEF_BUCKETS
437  assume(bucket->coef[0]==NULL);
438  assume(bucket->coef[i]==NULL);
439  #endif
440  assume(pLength(p) == (unsigned)pl);
441  //if (TEST_OPT_PROT) { Print("C(%d)",pl); }
442  kbTest(bucket);
443  return i;
444 #endif
445 }
446 
447 void kBucketNormalize(kBucket_pt bucket)
448 {
449 #ifdef HAVE_PSEUDO_BUCKETS
450  p_Normalize(bucket->p,bucket->bucket_ring);
451 #else
452  MULTIPLY_BUCKET(bucket,1);
453  for (int i=0; i<=bucket->buckets_used; i++)
454  {
455  p_Normalize(bucket->buckets[i],bucket->bucket_ring);
456  }
457 #endif
458 }
459 
460 void kBucketClear(kBucket_pt bucket, poly *p, int *length)
461 {
462  int i = kBucketCanonicalize(bucket);
463  if (i > 0)
464  {
465  #ifdef USE_COEF_BUCKETS
466  MULTIPLY_BUCKET(bucket,i);
467  //bucket->coef[i]=NULL;
468  #endif
469  *p = bucket->buckets[i];
470  *length = bucket->buckets_length[i];
471  bucket->buckets[i] = NULL;
472  bucket->buckets_length[i] = 0;
473  bucket->buckets_used = 0;
474 
475  }
476  else
477  {
478  *p = NULL;
479  *length = 0;
480  }
481 }
482 
483 void kBucketSetLm(kBucket_pt bucket, poly lm)
484 {
485  kBucketMergeLm(bucket);
486  pNext(lm) = NULL;
487  bucket->buckets[0] = lm;
488  bucket->buckets_length[0] = 1;
489 }
490 
491 #else // HAVE_PSEUDO_BUCKETS
492 
493 void kBucketInit(kBucket_pt bucket, poly lm, int length)
494 {
495  int i;
496 
497  assume(bucket != NULL);
498  assume(length <= 0 || length == pLength(lm));
499 
500  bucket->p = lm;
501  if (length <= 0) bucket->l = pLength(lm);
502  else bucket->l = length;
503 
504 }
505 
506 const poly kBucketGetLm(kBucket_pt bucket)
507 {
508  return bucket->p;
509 }
510 
512 {
513  poly lm = bucket->p;
514  assume(pLength(bucket->p) == bucket->l);
515  pIter(bucket->p);
516  (bucket->l)--;
517  pNext(lm) = NULL;
518  return lm;
519 }
520 
521 void kBucketClear(kBucket_pt bucket, poly *p, int *length)
522 {
523  assume(pLength(bucket->p) == bucket->l);
524  *p = bucket->p;
525  *length = bucket->l;
526  bucket->p = NULL;
527  bucket->l = 0;
528 }
529 
530 #endif // ! HAVE_PSEUDO_BUCKETS
531 //////////////////////////////////////////////////////////////////////////
532 ///
533 /// For changing the ring of the Bpoly to new_tailBin
534 ///
535 void kBucketShallowCopyDelete(kBucket_pt bucket,
536  ring new_tailRing, omBin new_tailBin,
537  pShallowCopyDeleteProc p_shallow_copy_delete)
538 {
539 #ifndef HAVE_PSEUDO_BUCKETS
540  int i;
541 
542  kBucketCanonicalize(bucket);
543  for (i=0; i<= bucket->buckets_used; i++)
544  if (bucket->buckets[i] != NULL)
545  {
546  MULTIPLY_BUCKET(bucket,i);
547  bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i],
548  bucket->bucket_ring,
549  new_tailRing,
550  new_tailBin);
551  }
552 #else
553  bucket->p = p_shallow_copy_delete(p,
554  bucket_ring,
555  new_tailRing,
556  new_tailBin);
557 #endif
558  bucket->bucket_ring = new_tailRing;
559 }
560 
561 //////////////////////////////////////////////////////////////////////////
562 ///
563 /// Bucket number i from bucket is out of length sync, resync
564 ///
565 void kBucketAdjust(kBucket_pt bucket, int i) {
566 
567  MULTIPLY_BUCKET(bucket,i);
568 
569  int l1 = bucket->buckets_length[i];
570  poly p1 = bucket->buckets[i];
571  bucket->buckets[i] = NULL;
572  bucket->buckets_length[i] = 0;
573  i = pLogLength(l1);
574 
575  while (bucket->buckets[i] != NULL)
576  {
577  //kbTest(bucket);
578  MULTIPLY_BUCKET(bucket,i);
579  p1 = p_Add_q(p1, bucket->buckets[i],
580  l1, bucket->buckets_length[i], bucket->bucket_ring);
581  bucket->buckets[i] = NULL;
582  bucket->buckets_length[i] = 0;
583  i = pLogLength(l1);
584  }
585 
586  bucket->buckets[i] = p1;
587  bucket->buckets_length[i]=l1;
588  if (i >= bucket->buckets_used)
589  bucket->buckets_used = i;
590  else
591  kBucketAdjustBucketsUsed(bucket);
592 }
593 
594 //////////////////////////////////////////////////////////////////////////
595 ///
596 /// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
597 ///
598 void kBucket_Mult_n(kBucket_pt bucket, number n)
599 {
600 #ifndef HAVE_PSEUDO_BUCKETS
601  kbTest(bucket);
602  ring r=bucket->bucket_ring;
603  int i;
604 
605  for (i=0; i<= bucket->buckets_used; i++)
606  {
607  if (bucket->buckets[i] != NULL)
608  {
609 #ifdef USE_COEF_BUCKETS
610  if (i<coef_start)
611  bucket->buckets[i] = __p_Mult_nn(bucket->buckets[i], n, r);
612  /* Frank Seelisch on March 11, 2010:
613  This looks a bit strange: The following "if" is indented
614  like the previous line of code. But coded as it is,
615  it should actually be two spaces less indented.
616  Question: Should the following "if" also only be
617  performed when "(i<coef_start)" is true?
618  For the time being, I leave it as it is. */
619  if (rField_is_Ring(r) && !(rField_is_Domain(r)))
620  {
621  bucket->buckets_length[i] = pLength(bucket->buckets[i]);
622  kBucketAdjust(bucket, i);
623  }
624  else
625  if (bucket->coef[i]!=NULL)
626  {
627  bucket->coef[i] = __p_Mult_nn(bucket->coef[i],n,r);
628  }
629  else
630  {
631  bucket->coef[i] = p_NSet(n_Copy(n,r),r);
632  }
633 #else
634  bucket->buckets[i] = __p_Mult_nn(bucket->buckets[i], n, r);
635 #endif
636  }
637  }
638  if (rField_is_Ring(r) && !(rField_is_Domain(r)))
639  {
640  for (i=0; i<= bucket->buckets_used; i++)
641  {
642  if (bucket->buckets[i] != NULL)
643  {
644  bucket->buckets_length[i] = pLength(bucket->buckets[i]);
645  kBucketAdjust(bucket, i);
646  }
647  }
648  }
649  kbTest(bucket);
650 #else
651  bucket->p = __p_Mult_nn(bucket->p, n, bucket->bucket_ring);
652 #endif
653 }
654 
655 
656 //////////////////////////////////////////////////////////////////////////
657 ///
658 /// Add to Bucket a poly ,i.e. Bpoly == q+Bpoly
659 ///
660 void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
661 {
662  if (q == NULL) return;
663  assume(*l <= 0 || pLength(q) == *l);
664 
665  int i, l1;
666  ring r = bucket->bucket_ring;
667 
668  if (*l <= 0)
669  {
670  l1 = pLength(q);
671  *l = l1;
672  }
673  else
674  l1 = *l;
675 
676  kBucketMergeLm(bucket);
677  kbTest(bucket);
678  i = pLogLength(l1);
679 
680  while (bucket->buckets[i] != NULL)
681  {
682  //MULTIPLY_BUCKET(bucket,i);
683  #ifdef USE_COEF_BUCKETS
684  if (bucket->coef[i]!=NULL)
685  {
686  q = p_Plus_mm_Mult_qq(q, bucket->coef[i], bucket->buckets[i],
687  l1, bucket->buckets_length[i], r);
688  p_Delete(&bucket->coef[i],r);
689  p_Delete(&bucket->buckets[i],r);
690  }
691  else
692  q = p_Add_q(q, bucket->buckets[i],
693  l1, bucket->buckets_length[i], r);
694  #else
695  q = p_Add_q(q, bucket->buckets[i],
696  l1, bucket->buckets_length[i], r);
697  #endif
698  bucket->buckets[i] = NULL;
699  bucket->buckets_length[i] = 0;
700  i = pLogLength(l1);
701  assume(i<= MAX_BUCKET);
702  assume(bucket->buckets_used<= MAX_BUCKET);
703  }
704 
705  kbTest(bucket);
706  bucket->buckets[i] = q;
707  bucket->buckets_length[i]=l1;
708  if (i >= bucket->buckets_used)
709  bucket->buckets_used = i;
710  else
711  kBucketAdjustBucketsUsed(bucket);
712  kbTest(bucket);
713 }
714 
715 
716 
717 //////////////////////////////////////////////////////////////////////////
718 ///
719 /// Bpoly == Bpoly - m*p; where m is a monom
720 /// Does not destroy p and m
721 /// assume (*l <= 0 || pLength(p) == *l)
722 void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
723  poly spNoether)
724 {
725  assume(*l <= 0 || pLength(p) == *l);
726  int i, l1;
727  poly p1 = p;
728  ring r = bucket->bucket_ring;
729 
730  if (*l <= 0)
731  {
732  l1 = pLength(p1);
733  *l = l1;
734  }
735  else
736  l1 = *l;
737 
738  if (m == NULL || p == NULL) return;
739 
740 #ifndef HAVE_PSEUDO_BUCKETS
741  kBucketMergeLm(bucket);
742  kbTest(bucket);
743  i = pLogLength(l1);
744 
745  {
746  if ((i <= bucket->buckets_used) && (bucket->buckets[i] != NULL))
747  {
748  assume(pLength(bucket->buckets[i])==(unsigned)bucket->buckets_length[i]);
749 //#ifdef USE_COEF_BUCKETS
750 // if(bucket->coef[i]!=NULL)
751 // {
752 // poly mult=p_Mult_mm(bucket->coef[i],m,r);
753 // bucket->coef[i]=NULL;
754 // p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], mult, p1,
755 // bucket->buckets_length[i], l1,
756 // spNoether, r);
757 // }
758 // else
759 //#endif
760  MULTIPLY_BUCKET(bucket,i);
761  p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
762  bucket->buckets_length[i], l1,
763  spNoether, r);
764  l1 = bucket->buckets_length[i];
765  bucket->buckets[i] = NULL;
766  bucket->buckets_length[i] = 0;
767  i = pLogLength(l1);
768  }
769  else
770  {
771  pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
772  if (spNoether != NULL)
773  {
774  l1 = -1;
775  p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r);
776  i = pLogLength(l1);
777  }
778  else
779  {
780  p1 = r->p_Procs->pp_mm_Mult(p1, m, r);
781  }
782  pSetCoeff0(m, n_InpNeg(pGetCoeff(m),r->cf));
783  }
784  }
785 
786  while (bucket->buckets[i] != NULL)
787  {
788  //kbTest(bucket);
789  MULTIPLY_BUCKET(bucket,i);
790  p1 = p_Add_q(p1, bucket->buckets[i],
791  l1, bucket->buckets_length[i], r);
792  bucket->buckets[i] = NULL;
793  bucket->buckets_length[i] = 0;
794  i = pLogLength(l1);
795  }
796 
797  bucket->buckets[i] = p1;
798  bucket->buckets_length[i]=l1;
799  if (i >= bucket->buckets_used)
800  bucket->buckets_used = i;
801  else
802  kBucketAdjustBucketsUsed(bucket);
803 #else // HAVE_PSEUDO_BUCKETS
804  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m, p,
805  bucket->l, l1,
806  spNoether, r);
807 #endif
808 }
809 
810 //////////////////////////////////////////////////////////////////////////
811 ///
812 /// Bpoly == Bpoly + m*p; where m is a monom
813 /// Does not destroy p and m
814 /// assume (l <= 0 || pLength(p) == l)
815 void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
816 {
817  assume((!rIsPluralRing(bucket->bucket_ring))||p_IsConstant(m, bucket->bucket_ring));
818  assume(l <= 0 || pLength(p) == (unsigned)l);
819  int i, l1;
820  poly p1 = p;
821  ring r = bucket->bucket_ring;
822 
823  if (m == NULL || p == NULL) return;
824 
825  if (l <= 0)
826  {
827  l1 = pLength(p1);
828  l = l1;
829  }
830  else
831  l1 = l;
832 
833  kBucketMergeLm(bucket);
834  kbTest(bucket);
835  i = pLogLength(l1);
836  #ifdef USE_COEF_BUCKETS
837  number n=n_Init(1,r->cf);
838  #endif
839  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
840  {
841  //if (FALSE){
842  #ifdef USE_COEF_BUCKETS
843  if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
844  {
845  number orig_coef=p_GetCoeff(bucket->coef[i],r);
846  //we take ownership:
847  p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
848  number add_coef=n_Copy(p_GetCoeff(m,r),r);
849  number gcd=n_Gcd(add_coef, orig_coef,r);
850 
851  if (!(n_IsOne(gcd,r)))
852  {
853  number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
854  number add_coef2=n_ExactDiv(add_coef, gcd,r);
855  n_Delete(&orig_coef,r);
856  n_Delete(&add_coef,r);
857  orig_coef=orig_coef2;
858  add_coef=add_coef2;
859 
860  //p_Mult_nn(bucket->buckets[i], orig_coef,r);
861  n_Delete(&n,r);
862  n=gcd;
863  }
864 
865  //assume(n_IsOne(n,r));
866  number backup=p_GetCoeff(m,r);
867 
868  p_SetCoeff0(m,add_coef,r);
869  bucket->buckets[i]=__p_Mult_nn(bucket->buckets[i],orig_coef,r);
870 
871  n_Delete(&orig_coef,r);
872  p_Delete(&bucket->coef[i],r);
873 
874  p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
875  bucket->buckets_length[i], l1, r);
876  l1=bucket->buckets_length[i];
877  bucket->buckets[i]=NULL;
878  bucket->buckets_length[i] = 0;
879  i = pLogLength(l1);
880  assume(l1==pLength(p1));
881 
882  p_SetCoeff(m,backup,r); //deletes add_coef
883  }
884  else
885  #endif
886  {
887  MULTIPLY_BUCKET(bucket,i);
888  p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
889  bucket->buckets_length[i], l1, r);
890  l1 = bucket->buckets_length[i];
891  bucket->buckets[i] = NULL;
892  bucket->buckets_length[i] = 0;
893  i = pLogLength(l1);
894  }
895  }
896  else
897  {
898  #ifdef USE_COEF_BUCKETS
899  number swap_n=p_GetCoeff(m,r);
900 
901  assume(n_IsOne(n,r));
902  p_SetCoeff0(m,n,r);
903  n=swap_n;
904  //p_SetCoeff0(n, swap_n, r);
905  //p_GetCoeff0(n, swap_n,r);
906  #endif
907  p1 = r->p_Procs->pp_Mult_mm(p1, m, r);
908  #ifdef USE_COEF_BUCKETS
909  //m may not be changed
910  p_SetCoeff(m,n_Copy(n,r),r);
911  #endif
912  }
913 
914  while ((bucket->buckets[i] != NULL) && (p1!=NULL))
915  {
916  assume(i!=0);
917  #ifdef USE_COEF_BUCKETS
918  if ((bucket->coef[i]!=NULL) &&(i>=coef_start))
919  {
920  number orig_coef=p_GetCoeff(bucket->coef[i],r);
921  //we take ownership:
922  p_SetCoeff0(bucket->coef[i],n_Init(0,r),r);
923  number add_coef=n_Copy(n,r);
924  number gcd=n_Gcd(add_coef, orig_coef,r);
925 
926  if (!(n_IsOne(gcd,r)))
927  {
928  number orig_coef2=n_ExactDiv(orig_coef,gcd,r);
929  number add_coef2=n_ExactDiv(add_coef, gcd,r);
930  n_Delete(&orig_coef,r);
931  n_Delete(&n,r);
932  n_Delete(&add_coef,r);
933  orig_coef=orig_coef2;
934  add_coef=add_coef2;
935  //p_Mult_nn(bucket->buckets[i], orig_coef,r);
936  n=gcd;
937  }
938  //assume(n_IsOne(n,r));
939  bucket->buckets[i]=__p_Mult_nn(bucket->buckets[i],orig_coef,r);
940  p1=__p_Mult_nn(p1,add_coef,r);
941 
942  p1 = p_Add_q(p1, bucket->buckets[i],r);
943  l1=pLength(p1);
944 
945  bucket->buckets[i]=NULL;
946  n_Delete(&orig_coef,r);
947  p_Delete(&bucket->coef[i],r);
948  //l1=bucket->buckets_length[i];
949  assume(l1==pLength(p1));
950  }
951  else
952  #endif
953  {
954  //don't do that, pull out gcd
955  #ifdef USE_COEF_BUCKETS
956  if(!(n_IsOne(n,r)))
957  {
958  p1=__p_Mult_nn(p1, n, r);
959  n_Delete(&n,r);
960  n=n_Init(1,r);
961  }
962  #endif
963  MULTIPLY_BUCKET(bucket,i);
964  p1 = p_Add_q(p1, bucket->buckets[i],
965  l1, bucket->buckets_length[i], r);
966  bucket->buckets[i] = NULL;
967  bucket->buckets_length[i] = 0;
968  }
969  i = pLogLength(l1);
970  }
971 
972  bucket->buckets[i] = p1;
973 #ifdef USE_COEF_BUCKETS
974  assume(bucket->coef[i]==NULL);
975 
976  if (!(n_IsOne(n,r)))
977  {
978  bucket->coef[i]=p_NSet(n,r);
979  }
980  else
981  {
982  bucket->coef[i]=NULL;
983  n_Delete(&n,r);
984  }
985 
986  if (p1==NULL)
987  p_Delete(&bucket->coef[i],r);
988 #endif
989  bucket->buckets_length[i]=l1;
990  if (i > bucket->buckets_used)
991  bucket->buckets_used = i;
992  else
993  kBucketAdjustBucketsUsed(bucket);
994 
995  kbTest(bucket);
996 }
997 
998 poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
999 {
1000  if (q == NULL) return append;
1001  poly lm;
1002  loop
1003  {
1004  lm = kBucketGetLm(bucket);
1005  if (lm == NULL) return append;
1006  if (p_LmCmp(lm, q, bucket->bucket_ring) == 1)
1007  {
1008  lm = kBucketExtractLm(bucket);
1009  pNext(append) = lm;
1010  pIter(append);
1011  }
1012  else
1013  {
1014  return append;
1015  }
1016  }
1017 }
1018 
1019 /////////////////////////////////////////////////////////////////////////////
1020 //
1021 // Extract all monomials from bucket with component comp
1022 // Return as a polynomial *p with length *l
1023 // In other words, afterwards
1024 // Bpoly = Bpoly - (poly consisting of all monomials with component comp)
1025 // and components of monomials of *p are all 0
1026 //
1027 
1028 // Hmm... for now I'm too lazy to implement those independent of currRing
1029 // But better declare it extern than including polys.h
1030 extern void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r);
1031 
1033  long comp,
1034  poly *r_p, int *l)
1035 {
1036  poly p = NULL, q;
1037  int i, lp = 0, lq;
1038 
1039 #ifndef HAVE_PSEUDO_BUCKETS
1040  kBucketMergeLm(bucket);
1041  for (i=1; i<=bucket->buckets_used; i++)
1042  {
1043  if (bucket->buckets[i] != NULL)
1044  {
1045  MULTIPLY_BUCKET(bucket,i);
1046  p_TakeOutComp(&(bucket->buckets[i]), comp, &q, &lq, bucket->bucket_ring);
1047  if (q != NULL)
1048  {
1049  assume(pLength(q) == (unsigned)lq);
1050  bucket->buckets_length[i] -= lq;
1051  assume(pLength(bucket->buckets[i]) == (unsigned)bucket->buckets_length[i]);
1052  p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
1053  }
1054  }
1055  }
1056  kBucketAdjustBucketsUsed(bucket);
1057 #else
1058  p_TakeOutComp(&(bucket->p), comp, &p, &lp,bucket->bucket_ring);
1059  (bucket->l) -= lp;
1060 #endif
1061  *r_p = p;
1062  *l = lp;
1063 
1064  kbTest(bucket);
1065 }
1066 
1067 /////////////////////////////////////////////////////////////////////////////
1068 // Reduction of Bpoly with a given poly
1069 //
1070 
1072  poly p1, int l1,
1073  poly spNoether)
1074 {
1075  ring r=bucket->bucket_ring;
1076  assume((!rIsPluralRing(r))||p_LmEqual(p1,kBucketGetLm(bucket), r));
1077  assume(p1 != NULL &&
1078  p_DivisibleBy(p1, kBucketGetLm(bucket), r));
1079  assume(pLength(p1) == (unsigned) l1);
1080 
1081  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
1082  BOOLEAN reset_vec=FALSE;
1083  number rn;
1084 
1085  /* we shall reduce bucket=bn*lm+... by p1=an*t+a1 where t=lm(p1)
1086  and an,bn shall be defined further down only if lc(p1)!=1
1087  we already know: an|bn and t|lm */
1088  if(a1==NULL)
1089  {
1090  p_LmDelete(&lm, r);
1091  return n_Init(1,r->cf);
1092  }
1093 
1094  if (! n_IsOne(pGetCoeff(p1),r->cf))
1095  {
1096  number an = pGetCoeff(p1), bn = pGetCoeff(lm);
1097  /* ksCheckCoeff: divide out gcd from an and bn: */
1098  int ct = ksCheckCoeff(&an, &bn,r->cf);
1099  /* the previous command returns ct=0 or ct=2 iff an!=1
1100  note: an is now 1 or -1 */
1101 
1102  /* setup factor for p1 which cancels leading terms */
1103  p_SetCoeff(lm, bn, r);
1104  if ((ct == 0) || (ct == 2))
1105  {
1106  /* correct factor for cancelation by changing sign if an=-1 */
1107  if (rField_is_Ring(r))
1108  lm = __p_Mult_nn(lm, an, r);
1109  else
1110  kBucket_Mult_n(bucket, an);
1111  }
1112  rn = an;
1113  }
1114  else
1115  {
1116  rn = n_Init(1,r->cf);
1117  }
1118 
1119  if (p_GetComp(p1, r) != p_GetComp(lm, r))
1120  {
1121  p_SetCompP(a1, p_GetComp(lm, r), r);
1122  reset_vec = TRUE;
1123  p_SetComp(lm, p_GetComp(p1, r), r);
1124  p_Setm(lm, r);
1125  }
1126 
1127  p_ExpVectorSub(lm, p1, r);
1128  l1--;
1129 
1130  assume((unsigned)l1==pLength(a1));
1131 
1132 #ifdef HAVE_SHIFTBBA
1133  poly lmRight;
1134  poly lm_org;
1135  if (r->isLPring)
1136  {
1137  int firstBlock = p_mFirstVblock(p1, r);
1138  lm_org=lm;
1139  k_SplitFrame(lm, lmRight, si_max(firstBlock, 1), r);
1140  }
1141 #endif
1142 #if 0
1143  BOOLEAN backuped=FALSE;
1144  number coef;
1145  //@Viktor, don't ignore coefficients on monomials
1146  if(l1==1) {
1147 
1148  //if (rField_is_Q(r)) {
1149  //avoid this for function fields, as gcds are expensive at the moment
1150 
1151 
1152  coef=p_GetCoeff(a1,r);
1153  lm=p_Mult_nn(lm, coef, r);
1154  p_SetCoeff0(a1, n_Init(1,r), r);
1155  backuped=TRUE;
1156  //WARNING: not thread_safe
1157  //deletes coef as side effect
1158  //}
1159  }
1160 #endif
1161 
1162 #ifdef HAVE_SHIFTBBA
1163  if (r->isLPring)
1164  {
1165  poly tmp=r->p_Procs->pp_Mult_mm(a1, lmRight, r);
1166  kBucket_Minus_m_Mult_p(bucket, lm,tmp, &l1, spNoether);
1167  p_Delete(&tmp,r);
1168  p_LmDelete(&lmRight,r);
1169  p_LmDelete(lm_org,r);
1170  }
1171  else
1172 #endif
1173  {
1174  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
1175  }
1176 
1177 #if 0
1178  if (backuped)
1179  p_SetCoeff0(a1,coef,r);
1180 #endif
1181 
1182  p_LmDelete(&lm, r);
1183  if (reset_vec) p_SetCompP(a1, 0, r);
1184  kbTest(bucket);
1185  return rn;
1186 }
1187 
1189  poly p1, int l1,
1190  poly spNoether)
1191 {
1192  ring r=bucket->bucket_ring;
1193  assume((!rIsPluralRing(r))||p_LmEqual(p1,kBucketGetLm(bucket), r));
1194  assume(p1 != NULL &&
1195  p_DivisibleBy(p1, kBucketGetLm(bucket), r));
1196  assume(pLength(p1) == (unsigned) l1);
1197 
1198  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
1199  BOOLEAN reset_vec=FALSE;
1200 
1201  /* we shall reduce bucket=bn*lm+... by p1=an*t+a1 where t=lm(p1)
1202  and an,bn shall be defined further down only if lc(p1)!=1
1203  we already know: an|bn and t|lm */
1204  if(a1==NULL)
1205  {
1206  p_LmDelete(&lm, r);
1207  return;
1208  }
1209 
1210  #ifdef KDEBUG
1211  if (n_DivBy(pGetCoeff(lm),pGetCoeff(p1),r->cf))
1212  #endif
1213  {
1214  number c=n_Div(pGetCoeff(lm),pGetCoeff(p1),r->cf);
1215  //StringSetS("mult cf:");n_Write(c,r->cf);StringAppendS("\n");
1216  //PrintS(StringEndS());
1217  #ifdef KDEBUG
1218  if (n_IsZero(c,r->cf))
1219  {
1220  StringSetS("a/b: ");n_Write(pGetCoeff(lm),r->cf);StringAppendS(" / ");
1221  n_Write(pGetCoeff(p1),r->cf);StringAppendS("\n");PrintS(StringEndS());
1222  }
1223  #endif
1224  p_SetCoeff(lm,c,r);
1225  }
1226  #ifdef KDEBUG
1227  else
1228  {
1229  PrintS("bug\n");
1230  }
1231  #endif
1232  if (p_GetComp(p1, r) != p_GetComp(lm, r))
1233  {
1234  p_SetCompP(a1, p_GetComp(lm, r), r);
1235  reset_vec = TRUE;
1236  p_SetComp(lm, p_GetComp(p1, r), r);
1237  p_Setm(lm, r);
1238  }
1239 
1240  p_ExpVectorSub(lm, p1, r);
1241  l1--;
1242 
1243  assume((unsigned)l1==pLength(a1));
1244 
1245 #ifdef HAVE_SHIFTBBA
1246  poly lmRight;
1247  poly lm_org;
1248  if (r->isLPring)
1249  {
1250  int firstBlock = p_mFirstVblock(p1, r);
1251  lm_org=lm;
1252  k_SplitFrame(lm, lmRight, si_max(firstBlock, 1), r);
1253  }
1254 #endif
1255 
1256 #ifdef HAVE_SHIFTBBA
1257  if (r->isLPring)
1258  {
1259  poly tmp=r->p_Procs->pp_Mult_mm(a1, lmRight, r);
1260  kBucket_Minus_m_Mult_p(bucket, lm,tmp, &l1, spNoether);
1261  p_Delete(&tmp,r);
1262  p_LmDelete(&lmRight,r);
1263  p_LmDelete(lm_org,r);
1264  }
1265  else
1266 #endif
1267  {
1268  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
1269  }
1270 
1271 #if 0
1272  if (backuped)
1273  p_SetCoeff0(a1,coef,r);
1274 #endif
1275 
1276  p_LmDelete(&lm, r);
1277  if (reset_vec) p_SetCompP(a1, 0, r);
1278  kbTest(bucket);
1279  return;
1280 }
1281 
1282 #ifndef USE_COEF_BUCKETS
1284 {
1285  if (bucket->buckets[0]==NULL) return;
1286 
1287  ring r=bucket->bucket_ring;
1288  if (rField_is_Ring(r)) return;
1289 
1290  coeffs cf=r->cf;
1291  if (cf->cfSubringGcd==ndGcd) /* trivial gcd*/ return;
1292 
1293  number nn=pGetCoeff(bucket->buckets[0]);
1294  //if ((bucket->buckets_used==0)
1295  //&&(!n_IsOne(nn,cf)))
1296  //{
1297  // if (TEST_OPT_PROT) PrintS("@");
1298  // p_SetCoeff(bucket->buckets[0],n_Init(1,cf),r);
1299  // return;
1300  //}
1301 
1302  if (n_Size(nn,cf)<2) return;
1303 
1304  //kBucketAdjustBucketsUsed(bucket);
1305  number coef=n_Copy(nn,cf);
1306  // find an initial guess of a gcd
1307  for (int i=1; i<=bucket->buckets_used;i++)
1308  {
1309  if (bucket->buckets[i]!=NULL)
1310  {
1311  number t=p_InitContent(bucket->buckets[i],r);
1312  if (n_Size(t,cf)<2)
1313  {
1314  n_Delete(&t,cf);
1315  n_Delete(&coef,cf);
1316  return;
1317  }
1318  number t2=n_SubringGcd(coef,t,cf);
1319  n_Delete(&t,cf);
1320  n_Delete(&coef,cf);
1321  coef=t2;
1322  if (n_Size(coef,cf)<2) { n_Delete(&coef,cf);return;}
1323  }
1324  }
1325  // find the gcd
1326  for (int i=0; i<=bucket->buckets_used;i++)
1327  {
1328  if (bucket->buckets[i]!=NULL)
1329  {
1330  poly p=bucket->buckets[i];
1331  while(p!=NULL)
1332  {
1333  number t=n_SubringGcd(coef,pGetCoeff(p),cf);
1334  if (n_Size(t,cf)<2)
1335  {
1336  n_Delete(&t,cf);
1337  n_Delete(&coef,cf);
1338  return;
1339  }
1340  pIter(p);
1341  }
1342  }
1343  }
1344  // divided by the gcd
1345  if (TEST_OPT_PROT) PrintS("@");
1346  for (int i=bucket->buckets_used;i>=0;i--)
1347  {
1348  if (bucket->buckets[i]!=NULL)
1349  {
1350  poly p=bucket->buckets[i];
1351  while(p!=NULL)
1352  {
1353  number d = n_ExactDiv(pGetCoeff(p),coef,cf);
1354  p_SetCoeff(p,d,r);
1355  pIter(p);
1356  }
1357  }
1358  }
1359  n_Delete(&coef,cf);
1360 }
1361 #else
1362 static BOOLEAN nIsPseudoUnit(number n, ring r)
1363 {
1364  if (rField_is_Zp(r))
1365  return TRUE;
1366 
1367  if (rParameter(r)==NULL)
1368  {
1369  return (n_Size(n,r->cf)==1);
1370  }
1371  //if (r->parameter!=NULL)
1372  return (n_IsOne(n,r->cf) || n_IsMOne(n,r->cf));
1373 }
1374 
1375 void kBucketSimpleContent(kBucket_pt bucket)
1376 {
1377  ring r=bucket->bucket_ring;
1378  int i;
1379  //PrintS("HHHHHHHHHHHHH");
1380  for (i=0;i<=MAX_BUCKET;i++)
1381  {
1382  //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
1383  // PrintS("H2H2H2");
1384  if (i==0)
1385  {
1386  assume(bucket->buckets[i]==NULL);
1387  }
1388  if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]==NULL))
1389  return;
1390  }
1391  for (i=0;i<=MAX_BUCKET;i++)
1392  {
1393  //if ((bucket->buckets[i]!=NULL) && (bucket->coef[i]!=NULL))
1394  // PrintS("H2H2H2");
1395  if (i==0)
1396  {
1397  assume(bucket->buckets[i]==NULL);
1398  }
1399  if ((bucket->buckets[i]!=NULL)
1400  && (nIsPseudoUnit(p_GetCoeff(bucket->coef[i],r),r)))
1401  return;
1402  }
1403  //return;
1404 
1405  number coef=n_Init(0,r);
1406  //ATTENTION: will not work correct for GB over ring
1407  //if (TEST_OPT_PROT)
1408  // PrintS("CCCCCCCCCCCCC");
1409  for (i=MAX_BUCKET;i>=0;i--)
1410  {
1411  if (i==0)
1412  {
1413  assume(bucket->buckets[i]==NULL);
1414  }
1415  if (bucket->buckets[i]!=NULL)
1416  {
1417  assume(bucket->coef[i]!=NULL);
1418  assume(!(n_IsZero(pGetCoeff(bucket->coef[i]),r)));
1419 
1420  //in this way it should crash on programming errors, yeah
1421  number temp=n_Gcd(coef, pGetCoeff(bucket->coef[i]),r);
1422  n_Delete(&coef,r );
1423  coef=temp;
1424  if (nIsPseudoUnit(coef,r))
1425  {
1426  n_Delete(&coef,r);
1427  return;
1428  }
1429  assume(!(n_IsZero(coef,r)));
1430  }
1431  }
1432  if (n_IsZero(coef,r))
1433  {
1434  n_Delete(&coef,r);
1435  return;
1436  }
1437  if (TEST_OPT_PROT)
1438  PrintS("S");
1439  for(i=0;i<=MAX_BUCKET;i++)
1440  {
1441  if (bucket->buckets[i]!=NULL)
1442  {
1443  assume(!(n_IsZero(coef,r)));
1444  assume(bucket->coef[i]!=NULL);
1445  number lc=p_GetCoeff(bucket->coef[i],r);
1446  p_SetCoeff(bucket->coef[i], n_ExactDiv(lc,coef,r),r);
1447  assume(!(n_IsZero(p_GetCoeff(bucket->coef[i],r),r)));
1448  }
1449  }
1450  n_Delete(&coef,r);
1451 }
1452 #endif
1453 
1454 
1456 {
1457  assume(bucket->buckets[i]!=NULL);
1458 
1459  poly p=bucket->buckets[i];
1460  bucket->buckets_length[i]--;
1461 #ifdef USE_COEF_BUCKETS
1462  ring r=bucket->bucket_ring;
1463  if (bucket->coef[i]!=NULL)
1464  {
1465  poly next=pNext(p);
1466  if (next==NULL)
1467  {
1468  MULTIPLY_BUCKET(bucket,i);
1469  p=bucket->buckets[i];
1470  bucket->buckets[i]=NULL;
1471  return p;
1472  }
1473  else
1474  {
1475  bucket->buckets[i]=next;
1476  number c=p_GetCoeff(bucket->coef[i],r);
1477  pNext(p)=NULL;
1478  p=__p_Mult_nn(p,c,r);
1479  assume(p!=NULL);
1480  return p;
1481  }
1482  }
1483  else
1484 #endif
1485  {
1486  bucket->buckets[i]=pNext(bucket->buckets[i]);
1487  pNext(p)=NULL;
1488  assume(p!=NULL);
1489  return p;
1490  }
1491 }
1492 
1493 /*
1494 * input - output: a, b
1495 * returns:
1496 * a := a/gcd(a,b), b := b/gcd(a,b)
1497 * and return value
1498 * 0 -> a != 1, b != 1
1499 * 1 -> a == 1, b != 1
1500 * 2 -> a != 1, b == 1
1501 * 3 -> a == 1, b == 1
1502 * this value is used to control the spolys
1503 */
1504 int ksCheckCoeff(number *a, number *b, const coeffs r)
1505 {
1506  int c = 0;
1507  number an = *a, bn = *b;
1508  n_Test(an,r);
1509  n_Test(bn,r);
1510 
1511  if (UNLIKELY(nCoeff_is_Ring(r) && n_DivBy(bn,an,r))) // in NF
1512  {
1513  bn = n_ExactDiv(bn, an, r);
1514  an = n_Init(1, r);
1515  }
1516  else
1517  {
1518  number cn = n_SubringGcd(an, bn, r);
1519  if(n_IsOne(cn, r))
1520  {
1521  an = n_Copy(an, r); // a/1
1522  bn = n_Copy(bn, r); // b/1
1523  }
1524  else
1525  {
1526  an = n_ExactDiv(an, cn, r);
1527  bn = n_ExactDiv(bn, cn, r);
1528  }
1529  n_Delete(&cn, r);
1530  }
1531  if (n_IsOne(an, r))
1532  {
1533  c = 1;
1534  }
1535  if (n_IsOne(bn, r))
1536  {
1537  c += 2;
1538  }
1539  *a = an;
1540  *b = bn;
1541  return c;
1542 }
1543 
All the auxiliary stuff.
static int si_max(const int a, const int b)
Definition: auxiliary.h:124
#define UNLIKELY(X)
Definition: auxiliary.h:404
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
CanonicalForm lc(const CanonicalForm &f)
int l
Definition: cfEzgcd.cc:100
int m
Definition: cfEzgcd.cc:128
int i
Definition: cfEzgcd.cc:132
int p
Definition: cfModGcd.cc:4078
CanonicalForm cf
Definition: cfModGcd.cc:4083
CanonicalForm b
Definition: cfModGcd.cc:4103
Coefficient rings, fields and other domains suitable for Singular polynomials.
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of 'n'
Definition: coeffs.h:448
#define n_Test(a, r)
BOOLEAN n_Test(number a, const coeffs r)
Definition: coeffs.h:709
static FORCE_INLINE number n_Gcd(number a, number b, const coeffs r)
in Z: return the gcd of 'a' and 'b' in Z/nZ, Z/2^kZ: computed as in the case Z in Z/pZ,...
Definition: coeffs.h:661
static FORCE_INLINE number n_ExactDiv(number a, number b, const coeffs r)
assume that there is a canonical subring in cf and we know that division is possible for these a and ...
Definition: coeffs.h:619
static FORCE_INLINE BOOLEAN n_IsMOne(number n, const coeffs r)
TRUE iff 'n' represents the additive inverse of the one element, i.e. -1.
Definition: coeffs.h:469
static FORCE_INLINE number n_InpNeg(number n, const coeffs r)
in-place negation of n MUST BE USED: n = n_InpNeg(n) (no copy is returned)
Definition: coeffs.h:554
static FORCE_INLINE number n_Div(number a, number b, const coeffs r)
return the quotient of 'a' and 'b', i.e., a/b; raises an error if 'b' is not invertible in r exceptio...
Definition: coeffs.h:612
static FORCE_INLINE BOOLEAN n_IsZero(number n, const coeffs r)
TRUE iff 'n' represents the zero element.
Definition: coeffs.h:461
static FORCE_INLINE int n_Size(number n, const coeffs r)
return a non-negative measure for the complexity of n; return 0 only when n represents zero; (used fo...
Definition: coeffs.h:567
static FORCE_INLINE BOOLEAN nCoeff_is_Ring(const coeffs r)
Definition: coeffs.h:727
static FORCE_INLINE void n_Delete(number *p, const coeffs r)
delete 'p'
Definition: coeffs.h:452
static FORCE_INLINE void n_Write(number n, const coeffs r, const BOOLEAN bShortOut=TRUE)
Definition: coeffs.h:588
static FORCE_INLINE number n_Init(long i, const coeffs r)
a number representing i in the given coeff field/ring r
Definition: coeffs.h:535
static FORCE_INLINE BOOLEAN n_DivBy(number a, number b, const coeffs r)
test whether 'a' is divisible 'b'; for r encoding a field: TRUE iff 'b' does not represent zero in Z:...
Definition: coeffs.h:750
static FORCE_INLINE number n_SubringGcd(number a, number b, const coeffs r)
Definition: coeffs.h:663
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition: coeffs.h:465
CFFList append(const CFFList &Inputlist, const CFFactor &TheFactor)
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
int j
Definition: facHensel.cc:110
int comp(const CanonicalForm &A, const CanonicalForm &B)
compare polynomials
#define STATIC_VAR
Definition: globaldefs.h:7
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:257
ListNode * next
Definition: janet.h:31
void kBucketDeleteAndDestroy(kBucket_pt *bucket_pt)
Definition: kbuckets.cc:223
void kBucketClear(kBucket_pt bucket, poly *p, int *length)
Definition: kbuckets.cc:521
BOOLEAN kbTest(kBucket_pt bucket)
Tests.
Definition: kbuckets.cc:197
void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l, poly spNoether)
Bpoly == Bpoly - m*p; where m is a monom Does not destroy p and m assume (*l <= 0 || pLength(p) == *l...
Definition: kbuckets.cc:722
void kBucketTakeOutComp(kBucket_pt bucket, long comp, poly *r_p, int *l)
Definition: kbuckets.cc:1032
void kBucket_Mult_n(kBucket_pt bucket, number n)
Multiply Bucket by number ,i.e. Bpoly == n*Bpoly.
Definition: kbuckets.cc:598
void kBucketDestroy(kBucket_pt *bucket_pt)
Definition: kbuckets.cc:216
void kBucketInit(kBucket_pt bucket, poly lm, int length)
Definition: kbuckets.cc:493
int ksCheckCoeff(number *a, number *b, const coeffs r)
Definition: kbuckets.cc:1504
poly kBucketExtractLm(kBucket_pt bucket)
Definition: kbuckets.cc:511
void kBucketAdjust(kBucket_pt bucket, int i)
Bucket number i from bucket is out of length sync, resync.
Definition: kbuckets.cc:565
#define MULTIPLY_BUCKET(B, I)
Definition: kbuckets.cc:43
poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
Extract all monomials of bucket which are larger than q Append those to append, and return last monom...
Definition: kbuckets.cc:998
poly kBucketExtractLmOfBucket(kBucket_pt bucket, int i)
Definition: kbuckets.cc:1455
STATIC_VAR omBin kBucket_bin
Definition: kbuckets.cc:45
kBucket_pt kBucketCreate(const ring bucket_ring)
Creation/Destruction of buckets.
Definition: kbuckets.cc:209
static int LOG4(int v)
Some internal stuff.
Definition: kbuckets.cc:56
number kBucketPolyRed(kBucket_pt bucket, poly p1, int l1, poly spNoether)
Definition: kbuckets.cc:1071
void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
Bpoly == Bpoly + m*p; where m is a monom Does not destroy p and m assume (l <= 0 || pLength(p) == l)
Definition: kbuckets.cc:815
void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r)
Definition: p_polys.cc:3492
void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
Add to Bucket a poly ,i.e. Bpoly == q+Bpoly.
Definition: kbuckets.cc:660
void kBucketPolyRedNF(kBucket_pt bucket, poly p1, int l1, poly spNoether)
Definition: kbuckets.cc:1188
static unsigned int pLogLength(unsigned int l)
Definition: kbuckets.cc:71
const poly kBucketGetLm(kBucket_pt bucket)
Definition: kbuckets.cc:506
void kBucketSimpleContent(kBucket_pt bucket)
Definition: kbuckets.cc:1283
int l
Definition: kbuckets.h:187
void kBucketSetLm(kBucket_pt bucket, poly lm)
void kBucketNormalize(kBucket_pt bucket)
apply n_Normalize to all coefficients
int kBucketCanonicalize(kBucket_pt bucket)
Canonicalizes Bpoly, i.e. converts polys of buckets into one poly in one bucket: Returns number of bu...
poly p
Definition: kbuckets.h:186
ring bucket_ring
Definition: kbuckets.h:196
BOOLEAN kBucketIsCleared(kBucket_pt bucket)
#define MAX_BUCKET
Bucket definition (should be no one elses business, though)
Definition: kbuckets.h:179
#define assume(x)
Definition: mod2.h:389
int dReportError(const char *fmt,...)
Definition: dError.cc:44
#define p_SetCoeff0(p, n, r)
Definition: monomials.h:60
#define p_GetComp(p, r)
Definition: monomials.h:64
#define pFalseReturn(cond)
Definition: monomials.h:139
#define pIter(p)
Definition: monomials.h:37
#define pNext(p)
Definition: monomials.h:36
static number & pGetCoeff(poly p)
return an alias to the leading coefficient of p assumes that p != NULL NOTE: not copy
Definition: monomials.h:44
#define pSetCoeff0(p, n)
Definition: monomials.h:59
#define p_GetCoeff(p, r)
Definition: monomials.h:50
The main handler for Singular numbers which are suitable for Singular polynomials.
Definition: lq.h:40
number ndGcd(number, number, const coeffs r)
Definition: numbers.cc:189
#define omCheckAddrBin(addr, bin)
Definition: omAllocDecl.h:325
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:206
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
#define omGetSpecBin(size)
Definition: omBin.h:11
#define NULL
Definition: omList.c:12
omBin_t * omBin
Definition: omStructs.h:12
#define TEST_OPT_PROT
Definition: options.h:104
void p_Normalize(poly p, const ring r)
Definition: p_polys.cc:3809
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition: p_polys.cc:1469
number p_InitContent(poly ph, const ring r)
Definition: p_polys.cc:2631
static int pLength(poly a)
Definition: p_polys.h:188
static poly p_Add_q(poly p, poly q, const ring r)
Definition: p_polys.h:934
static void p_LmDelete(poly p, const ring r)
Definition: p_polys.h:721
#define p_LmEqual(p1, p2, r)
Definition: p_polys.h:1721
static void p_SetCompP(poly p, int i, ring r)
Definition: p_polys.h:252
static unsigned long p_SetComp(poly p, unsigned long c, ring r)
Definition: p_polys.h:245
static void p_ExpVectorSub(poly p1, poly p2, const ring r)
Definition: p_polys.h:1438
static void p_Setm(poly p, const ring r)
Definition: p_polys.h:231
static number p_SetCoeff(poly p, number n, ring r)
Definition: p_polys.h:410
static int p_LmCmp(poly p, poly q, const ring r)
Definition: p_polys.h:1578
static BOOLEAN p_IsConstant(const poly p, const ring r)
Definition: p_polys.h:1962
static BOOLEAN p_DivisibleBy(poly a, poly b, const ring r)
Definition: p_polys.h:1898
static poly p_Mult_nn(poly p, number n, const ring r)
Definition: p_polys.h:956
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:899
static poly p_Minus_mm_Mult_qq(poly p, const poly m, const poly q, int &lp, int lq, const poly spNoether, const ring r)
Definition: p_polys.h:1068
static poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq, const ring r)
Definition: p_polys.h:1181
#define p_Test(p, r)
Definition: p_polys.h:159
#define __p_Mult_nn(p, n, r)
Definition: p_polys.h:969
void StringSetS(const char *st)
Definition: reporter.cc:128
void StringAppendS(const char *st)
Definition: reporter.cc:107
void PrintS(const char *s)
Definition: reporter.cc:284
char * StringEndS()
Definition: reporter.cc:151
static BOOLEAN rField_is_Zp(const ring r)
Definition: ring.h:500
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition: ring.h:400
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition: ring.h:625
static BOOLEAN rField_is_Domain(const ring r)
Definition: ring.h:487
kBucket * kBucket_pt
Definition: ring.h:24
poly(* pShallowCopyDeleteProc)(poly s_p, ring source_r, ring dest_r, omBin dest_bin)
returns a poly from dest_r which is a ShallowCopy of s_p from source_r assumes that source_r->N == de...
Definition: ring.h:44
#define rField_is_Ring(R)
Definition: ring.h:485
int p_mFirstVblock(poly p, const ring ri)
Definition: shiftop.cc:478
void k_SplitFrame(poly &m1, poly &m2, int at, const ring r)
Definition: shiftop.cc:600
static int SI_LOG2(int v)
Definition: si_log2.h:6
#define loop
Definition: structs.h:75
int gcd(int a, int b)
Definition: walkSupport.cc:836