source: git/libpolys/polys/kbuckets.cc @ 0635d51

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