source: git/Singular/kbuckets.cc @ a3bc95e

spielwiese
Last change on this file since a3bc95e was a3bc95e, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: namespaces ->ns git-svn-id: file:///usr/local/Singular/svn/trunk@5651 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 15.9 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kbuckets.cc,v 1.24 2001-10-09 16:36:06 Singular Exp $ */
5
6#include "mod2.h"
7#include "tok.h"
8#include "structs.h"
9#include "omalloc.h"
10#include "p_polys.h"
11#include "febase.h"
12#include "pShallowCopyDelete.h"
13#include "kbuckets.h"
14#include "numbers.h"
15#include "p_Procs.h"
16
17static omBin kBucket_bin = omGetSpecBin(sizeof(kBucket));
18
19//////////////////////////////////////////////////////////////////////////
20///
21/// Some internal stuff
22///
23
24// returns ceil(log_4(l))
25inline unsigned int pLogLength(unsigned int l)
26{
27  unsigned int i = 0;
28
29  if (l == 0) return 0;
30  l--;
31#ifdef BUCKET_TWO_BASE
32  while ((l = (l >> 1))) i++;
33#else
34  while ((l = (l >> 2))) i++;
35#endif
36  return i+1;
37}
38
39// returns ceil(log_4(pLength(p)))
40inline unsigned int pLogLength(poly p)
41{
42  return pLogLength((unsigned int) pLength(p));
43}
44
45#ifdef KDEBUG
46
47#ifndef HAVE_PSEUDO_BUCKETS
48BOOLEAN kbTest_i(kBucket_pt bucket, int i)
49{
50  pFalseReturn(p_Test(bucket->buckets[i], bucket->bucket_ring));
51  if (bucket->buckets_length[i] != pLength(bucket->buckets[i]))
52  {
53    dReportError("Bucket %d lengths difference should:%d has:%d",
54                 i, bucket->buckets_length[i], pLength(bucket->buckets[i]));
55  }
56  else if (i > 0 && (int) pLogLength(bucket->buckets_length[i]) > i)
57  {
58    dReportError("Bucket %d too long %d",
59                 i, bucket->buckets_length[i]);
60  }
61  if (i==0 && bucket->buckets_length[0] > 1)
62  {
63    dReportError("Bucket 0 too long");
64  }
65  return TRUE;
66}
67
68
69BOOLEAN kbTest(kBucket_pt bucket)
70{
71  int i;
72  poly lm = bucket->buckets[0];
73
74  omCheckAddrBin(bucket, kBucket_bin);
75  if (! kbTest_i(bucket, 0)) return FALSE;
76  for (i=1; i<= (int) bucket->buckets_used; i++)
77  {
78    if (!kbTest_i(bucket, i)) return FALSE;
79    if (lm != NULL &&  bucket->buckets[i] != NULL
80        && p_LmCmp(lm, bucket->buckets[i], bucket->bucket_ring) != 1)
81    {
82      dReportError("Bucket %d larger than lm", i);
83      return FALSE;
84    }
85  }
86
87  for (; i<=MAX_BUCKET; i++)
88  {
89    if (bucket->buckets[i] != NULL || bucket->buckets_length[i] != 0)
90    {
91      dReportError("Bucket %d not zero", i);
92      return FALSE;
93    }
94  }
95  return TRUE;
96}
97
98#else // HAVE_PSEUDO_BUCKETS
99BOOLEAN kbTest(kBucket_pt bucket)
100{
101  return TRUE;
102}
103#endif // ! HAVE_PSEUDO_BUCKETS
104#endif // KDEBUG
105
106//////////////////////////////////////////////////////////////////////////
107///
108/// Creation/Destruction of buckets
109///
110
111kBucket_pt kBucketCreate(ring bucket_ring)
112{
113  assume(bucket_ring != NULL);
114  kBucket_pt bucket = (kBucket_pt) omAlloc0Bin(kBucket_bin);
115  bucket->bucket_ring = bucket_ring;
116  return bucket;
117}
118void kBucketDestroy(kBucket_pt *bucket_pt)
119{
120  omFreeBin(*bucket_pt, kBucket_bin);
121  *bucket_pt = NULL;
122}
123
124
125void kBucketDeleteAndDestroy(kBucket_pt *bucket_pt)
126{
127  kBucket_pt bucket = *bucket_pt;
128  kbTest(bucket);
129  int i;
130  for (i=0; i<= bucket->buckets_used; i++)
131  {
132    if (bucket->buckets[i] != NULL)
133      p_Delete(&(bucket->buckets[i]), bucket->bucket_ring);
134  }
135  omFreeBin(bucket, kBucket_bin);
136  *bucket_pt = NULL;
137}
138
139/////////////////////////////////////////////////////////////////////////////
140// Convertion from/to Bpolys
141//
142#ifndef HAVE_PSEUDO_BUCKETS
143
144inline void kBucketMergeLm(kBucket_pt bucket)
145{
146  if (bucket->buckets[0] != NULL)
147  {
148    poly lm = bucket->buckets[0];
149    int i = 1;
150#ifdef BUCKET_TWO_BASE
151    int l = 2;
152    while ( bucket->buckets_length[i] >= l)
153    {
154      i++;
155      l = l << 1;
156    }
157#else
158    int l = 4;
159    while ( bucket->buckets_length[i] >= l)
160    {
161      i++;
162      l = l << 2;
163    }
164#endif
165    pNext(lm) = bucket->buckets[i];
166    bucket->buckets[i] = lm;
167    bucket->buckets_length[i]++;
168    assume(i <= bucket->buckets_used+1);
169    if (i > bucket->buckets_used)  bucket->buckets_used = i;
170    bucket->buckets[0] = NULL;
171    bucket->buckets_length[0] = 0;
172  }
173}
174
175static BOOLEAN kBucketIsCleared(kBucket_pt bucket)
176{
177  int i;
178
179  for (i = 0;i<=MAX_BUCKET;i++)
180  {
181    if (bucket->buckets[i] != NULL) return FALSE;
182    if (bucket->buckets_length[i] != 0) return FALSE;
183  }
184  return TRUE;
185}
186
187void kBucketInit(kBucket_pt bucket, poly lm, int length)
188{
189  assume(bucket != NULL);
190  assume(length <= 0 || length == pLength(lm));
191  assume(kBucketIsCleared(bucket));
192
193  if (lm == NULL) return;
194
195  if (length <= 0)
196    length = pLength(lm);
197
198  bucket->buckets[0] = lm;
199  bucket->buckets_length[0] = 1;
200  if (length > 1)
201  {
202    unsigned int i = pLogLength(length-1);
203    bucket->buckets[i] = pNext(lm);
204    pNext(lm) = NULL;
205    bucket->buckets_length[i] = length-1;
206    bucket->buckets_used = i;
207  }
208  else
209  {
210    bucket->buckets_used = 0;
211  }
212}
213
214int kBucketCanonicalize(kBucket_pt bucket)
215{
216  poly p = bucket->buckets[1];
217  poly lm;
218  int pl = bucket->buckets_length[1], i;
219  bucket->buckets[1] = NULL;
220  bucket->buckets_length[1] = 0;
221
222
223  for (i=2; i<=bucket->buckets_used; i++)
224  {
225    p = p_Add_q(p, bucket->buckets[i],
226                 pl, bucket->buckets_length[i], bucket->bucket_ring);
227    bucket->buckets[i] = NULL;
228    bucket->buckets_length[i] = 0;
229  }
230
231  lm = bucket->buckets[0];
232  if (lm != NULL)
233  {
234    pNext(lm) = p;
235    p = lm;
236    pl++;
237    bucket->buckets[0] = NULL;
238    bucket->buckets_length[0] = 0;
239  }
240  if (pl > 0)
241  {
242    i = pLogLength(pl);
243    bucket->buckets[i] = p;
244    bucket->buckets_length[i] = pl;
245  }
246  else
247  {
248    i = 0;
249  }
250  bucket->buckets_used = i;
251  assume(pLength(p) == (int) pl);
252  return i;
253}
254
255void kBucketClear(kBucket_pt bucket, poly *p, int *length)
256{
257  int i = kBucketCanonicalize(bucket);
258  if (i > 0)
259  {
260    *p = bucket->buckets[i];
261    *length = bucket->buckets_length[i];
262    bucket->buckets[i] = NULL;
263    bucket->buckets_length[i] = 0;
264    bucket->buckets_used = 0;
265  }
266  else
267  {
268    *p = NULL;
269    *length = 0;
270  }
271}
272
273void kBucketSetLm(kBucket_pt bucket, poly lm)
274{
275  kBucketMergeLm(bucket);
276  pNext(lm) = NULL;
277  bucket->buckets[0] = lm;
278  bucket->buckets_length[0] = 1;
279}
280
281#else // HAVE_PSEUDO_BUCKETS
282
283void kBucketInit(kBucket_pt bucket, poly lm, int length)
284{
285  int i;
286
287  assume(bucket != NULL);
288  assume(length <= 0 || length == pLength(lm));
289
290  bucket->p = lm;
291  if (length <= 0) bucket->l = pLength(lm);
292  else bucket->l = length;
293
294}
295
296const poly kBucketGetLm(kBucket_pt bucket)
297{
298  return bucket->p;
299}
300
301poly kBucketExtractLm(kBucket_pt bucket)
302{
303  poly lm = bucket->p;
304  assume(pLength(bucket->p) == bucket->l);
305  pIter(bucket->p);
306  (bucket->l)--;
307  pNext(lm) = NULL;
308  return lm;
309}
310
311void kBucketClear(kBucket_pt bucket, poly *p, int *length)
312{
313  assume(pLength(bucket->p) == bucket->l);
314  *p = bucket->p;
315  *length = bucket->l;
316  bucket->p = NULL;
317  bucket->l = 0;
318}
319
320#endif // ! HAVE_PSEUDO_BUCKETS
321//////////////////////////////////////////////////////////////////////////
322///
323/// For changing the ring of the Bpoly to new_tailBin
324///
325void kBucketShallowCopyDelete(kBucket_pt bucket,
326                              ring new_tailRing, omBin new_tailBin,
327                              pShallowCopyDeleteProc p_shallow_copy_delete)
328{
329#ifndef HAVE_PSEUDO_BUCKETS
330  int i;
331
332  kBucketCanonicalize(bucket);
333  for (i=0; i<= bucket->buckets_used; i++)
334    if (bucket->buckets[i] != NULL)
335      bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i],
336                                                 bucket->bucket_ring,
337                                                 new_tailRing,
338                                                 new_tailBin);
339#else
340  bucket->p = p_shallow_copy_delete(p,
341                                    bucket_ring,
342                                    new_tailRing,
343                                    new_tailBin);
344#endif
345  bucket->bucket_ring = new_tailRing;
346}
347
348
349
350//////////////////////////////////////////////////////////////////////////
351///
352/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
353///
354void kBucket_Mult_n(kBucket_pt bucket, number n)
355{
356#ifndef HAVE_PSEUDO_BUCKETS
357  int i;
358
359  for (i=0; i<= bucket->buckets_used; i++)
360    if (bucket->buckets[i] != NULL)
361      bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, bucket->bucket_ring);
362#else
363  bucket->p = p_Mult_nn(bucket->p, n, bucket->bucket_ring);
364#endif
365}
366
367
368//////////////////////////////////////////////////////////////////////////
369///
370/// Add to Bucket a poly ,i.e. Bpoly == n*Bpoly
371///
372void kBucket_Add_q(kBucket_pt bucket, poly q, int *l)
373{
374  if (q == NULL) return;
375  assume(*l <= 0 || pLength(q) == *l);
376
377  int i, l1;
378  ring r = bucket->bucket_ring;
379
380  if (*l <= 0)
381  {
382    l1 = pLength(q);
383    *l = l1;
384  }
385  else
386    l1 = *l;
387
388  kBucketMergeLm(bucket);
389  kbTest(bucket);
390  i = pLogLength(l1);
391
392  while (bucket->buckets[i] != NULL)
393  {
394    q = p_Add_q(q, bucket->buckets[i],
395                 l1, bucket->buckets_length[i], r);
396    bucket->buckets[i] = NULL;
397    bucket->buckets_length[i] = 0;
398    i = pLogLength(l1);
399  }
400
401  bucket->buckets[i] = q;
402  bucket->buckets_length[i]=l1;
403  if (i >= bucket->buckets_used)
404    bucket->buckets_used = i;
405  else
406    kBucketAdjustBucketsUsed(bucket);
407  kbTest(bucket);
408}
409
410
411
412//////////////////////////////////////////////////////////////////////////
413///
414/// Bpoly == Bpoly - m*p; where m is a monom
415/// Does not destroy p and m
416/// assume (*l <= 0 || pLength(p) == *l)
417void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
418                            poly spNoether)
419{
420  assume(*l <= 0 || pLength(p) == *l);
421  int i, l1;
422  poly p1 = p;
423  poly last;
424  ring r = bucket->bucket_ring;
425
426  if (*l <= 0)
427  {
428    l1 = pLength(p1);
429    *l = l1;
430  }
431  else
432    l1 = *l;
433
434  if (m == NULL || p == NULL) return;
435
436#ifndef HAVE_PSEUDO_BUCKETS
437  kBucketMergeLm(bucket);
438  kbTest(bucket);
439  i = pLogLength(l1);
440
441  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
442  {
443    p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
444                            bucket->buckets_length[i], l1,
445                            spNoether, r);
446    l1 = bucket->buckets_length[i];
447    bucket->buckets[i] = NULL;
448    bucket->buckets_length[i] = 0;
449    i = pLogLength(l1);
450  }
451  else
452  {
453    pSetCoeff0(m, nNeg(pGetCoeff(m)));
454    if (spNoether != NULL)
455    {
456      l1 = -1;
457      p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r, last);
458      i = pLogLength(l1);
459    }
460    else
461      p1 = r->p_Procs->pp_Mult_mm(p1, m, r, last);
462    pSetCoeff0(m, nNeg(pGetCoeff(m)));
463  }
464
465  while (bucket->buckets[i] != NULL)
466  {
467    p1 = p_Add_q(p1, bucket->buckets[i],
468                 l1, bucket->buckets_length[i], r);
469    bucket->buckets[i] = NULL;
470    bucket->buckets_length[i] = 0;
471    i = pLogLength(l1);
472  }
473
474  bucket->buckets[i] = p1;
475  bucket->buckets_length[i]=l1;
476  if (i >= bucket->buckets_used)
477    bucket->buckets_used = i;
478  else
479    kBucketAdjustBucketsUsed(bucket);
480#else // HAVE_PSEUDO_BUCKETS
481  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m,  p,
482                               bucket->l, l1,
483                               spNoether, r);
484#endif
485  kbTest(bucket);
486}
487
488//////////////////////////////////////////////////////////////////////////
489///
490/// Bpoly == Bpoly - m*p; where m is a monom
491/// Does not destroy p and m
492/// assume (l <= 0 || pLength(p) == l)
493void kBucket_Plus_mm_Mult_pp(kBucket_pt bucket, poly m, poly p, int l)
494{
495  assume(l <= 0 || pLength(p) == l);
496  int i, l1;
497  poly p1 = p;
498  poly last;
499  ring r = bucket->bucket_ring;
500
501  if (l <= 0)
502  {
503    l1 = pLength(p1);
504    l = l1;
505  }
506  else
507    l1 = l;
508
509  if (m == NULL || p == NULL) return;
510
511  kBucketMergeLm(bucket);
512  kbTest(bucket);
513  i = pLogLength(l1);
514
515  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
516  {
517    p1 = p_Plus_mm_Mult_qq(bucket->buckets[i], m, p1,
518                           bucket->buckets_length[i], l1, r);
519    l1 = bucket->buckets_length[i];
520    bucket->buckets[i] = NULL;
521    bucket->buckets_length[i] = 0;
522    i = pLogLength(l1);
523  }
524  else
525  {
526    p1 = r->p_Procs->pp_Mult_mm(p1, m, r, last);
527  }
528
529  while (bucket->buckets[i] != NULL)
530  {
531    p1 = p_Add_q(p1, bucket->buckets[i],
532                 l1, bucket->buckets_length[i], r);
533    bucket->buckets[i] = NULL;
534    bucket->buckets_length[i] = 0;
535    i = pLogLength(l1);
536  }
537
538  bucket->buckets[i] = p1;
539  bucket->buckets_length[i]=l1;
540  if (i >= bucket->buckets_used)
541    bucket->buckets_used = i;
542  else
543    kBucketAdjustBucketsUsed(bucket);
544
545  kbTest(bucket);
546}
547
548poly kBucket_ExtractLarger(kBucket_pt bucket, poly q, poly append)
549{
550  if (q == NULL) return append;
551  poly lm;
552  do
553  {
554    lm = kBucketGetLm(bucket);
555    if (lm == NULL) return append;
556    if (p_LmCmp(lm, q, bucket->bucket_ring) == 1)
557    {
558      lm = kBucketExtractLm(bucket);
559      pNext(append) = lm;
560      pIter(append);
561    }
562    else
563    {
564      return append;
565    }
566  }
567  while (1);
568}
569
570/////////////////////////////////////////////////////////////////////////////
571//
572// Extract all monomials from bucket with component comp
573// Return as a polynomial *p with length *l
574// In other words, afterwards
575// Bpoly == Bpoly - (poly consisting of all monomials with component comp)
576// and components of monomials of *p are all 0
577//
578
579// Hmm... for now I'm too lazy to implement those independent of currRing
580// But better declare it extern than including polys.h
581extern void pTakeOutComp(poly *p, Exponent_t comp, poly *q, int *lq);
582void pDecrOrdTakeOutComp(poly *p, Exponent_t comp, Order_t order,
583                         poly *q, int *lq);
584
585void kBucketTakeOutComp(kBucket_pt bucket,
586                        Exponent_t comp,
587                        poly *r_p, int *l)
588{
589  poly p = NULL, q;
590  int i, lp = 0, lq;
591
592#ifndef HAVE_PSEUDO_BUCKETS
593  kBucketMergeLm(bucket);
594  for (i=1; i<=bucket->buckets_used; i++)
595  {
596    if (bucket->buckets[i] != NULL)
597    {
598      pTakeOutComp(&(bucket->buckets[i]), comp, &q, &lq);
599      if (q != NULL)
600      {
601        assume(pLength(q) == lq);
602        bucket->buckets_length[i] -= lq;
603        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
604        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
605      }
606    }
607  }
608  kBucketAdjustBucketsUsed(bucket);
609#else
610  pTakeOutComp(&(bucket->p), comp, &p, &lp);
611  (bucket->l) -= lp;
612#endif
613  *r_p = p;
614  *l = lp;
615
616  kbTest(bucket);
617}
618
619void kBucketDecrOrdTakeOutComp(kBucket_pt bucket,
620                               Exponent_t comp, Order_t order,
621                               poly *r_p, int *l)
622{
623  poly p = NULL, q;
624  int i, lp = 0, lq;
625
626#ifndef HAVE_PSEUDO_BUCKETS
627  kBucketMergeLm(bucket);
628  for (i=1; i<=bucket->buckets_used; i++)
629  {
630    if (bucket->buckets[i] != NULL)
631    {
632      pDecrOrdTakeOutComp(&(bucket->buckets[i]), comp, order, &q, &lq);
633      if (q != NULL)
634      {
635        bucket->buckets_length[i] -= lq;
636        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
637      }
638    }
639  }
640  kBucketAdjustBucketsUsed(bucket);
641#else
642  pDecrOrdTakeOutComp(&(bucket->p), comp, order, &p, &lp);
643  (bucket->l) -= lp;
644#endif
645
646  *r_p = p;
647  *l = lp;
648}
649
650/////////////////////////////////////////////////////////////////////////////
651// Reduction of Bpoly with a given poly
652//
653
654extern int ksCheckCoeff(number *a, number *b);
655
656number kBucketPolyRed(kBucket_pt bucket,
657                      poly p1, int l1,
658                      poly spNoether)
659{
660  assume(p1 != NULL &&
661         p_DivisibleBy(p1,  kBucketGetLm(bucket), bucket->bucket_ring));
662  assume(pLength(p1) == (int) l1);
663
664  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
665  BOOLEAN reset_vec=FALSE;
666  number rn;
667
668  if(a1==NULL)
669  {
670    p_DeleteLm(&lm, bucket->bucket_ring);
671    return nInit(1);
672  }
673
674  if (! nIsOne(pGetCoeff(p1)))
675  {
676    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
677    int ct = ksCheckCoeff(&an, &bn);
678    p_SetCoeff(lm, bn, bucket->bucket_ring);
679    if ((ct == 0) || (ct == 2)) kBucket_Mult_n(bucket, an);
680    rn = an;
681  }
682  else
683  {
684    rn = nInit(1);
685  }
686
687  if (p_GetComp(p1, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
688  {
689    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
690    reset_vec = TRUE;
691    p_SetComp(lm, p_GetComp(p1, bucket->bucket_ring), bucket->bucket_ring);
692    p_Setm(lm, bucket->bucket_ring);
693  }
694
695  p_ExpVectorSub(lm,p1, bucket->bucket_ring);
696  l1--;
697
698  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
699
700  p_DeleteLm(&lm, bucket->bucket_ring);
701  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
702  kbTest(bucket);
703  return rn;
704}
705
706
Note: See TracBrowser for help on using the repository browser.