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"
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
47STATIC_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
56static 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))
71static 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)))
86static 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
94BOOLEAN 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
128{
129 #ifdef HAVE_COEF_BUCKETS
130 assume(bucket->coef[0]==NULL);
131 #endif
132 int i;
133 poly lm = bucket->buckets[0];
134
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
209kBucket_pt kBucketCreate(const ring bucket_ring)
210{
211 assume(bucket_ring != NULL);
213 bucket->bucket_ring = bucket_ring;
214 return bucket;
215}
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
244inline 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
335void 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
447void 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
460void 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
483void 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
493void 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
506const 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
521void 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///
535void 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///
565void 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///
598void 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///
660void 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);
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)
722void 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)
815void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
816{
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
998poly 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
1030extern 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
1362static 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
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*/
1504int 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
#define pSetCoeff0(p, n)
Definition: monomials.h:59
#define p_GetCoeff(p, r)
Definition: monomials.h:50
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
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 BOOLEAN rField_is_Domain(const ring r)
Definition: ring.h:487
kBucket * kBucket_pt
Definition: ring.h:25
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition: ring.h:625
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