source: git/Singular/kbuckets.cc @ 4508ce5

fieker-DuValspielwiese
Last change on this file since 4508ce5 was a29995, checked in by Olaf Bachmann <obachman@…>, 23 years ago
* towards tailRings for local case git-svn-id: file:///usr/local/Singular/svn/trunk@4777 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 13.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kbuckets.cc,v 1.22 2000-11-28 11:50:51 obachman 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/////////////////////////////////////////////////////////////////////////////
141// Convertion from/to Bpolys
142//
143#ifndef HAVE_PSEUDO_BUCKETS
144
145inline void kBucketMergeLm(kBucket_pt bucket)
146{
147  if (bucket->buckets[0] != NULL)
148  {
149    poly lm = bucket->buckets[0];
150    int i = 1;
151#ifdef BUCKET_TWO_BASE
152    int l = 2;
153    while ( bucket->buckets_length[i] >= l)
154    {
155      i++;
156      l = l << 1;
157    }
158#else
159    int l = 4;
160    while ( bucket->buckets_length[i] >= l)
161    {
162      i++;
163      l = l << 2;
164    }
165#endif
166    pNext(lm) = bucket->buckets[i];
167    bucket->buckets[i] = lm;
168    bucket->buckets_length[i]++;
169    assume(i <= bucket->buckets_used+1);
170    if (i > bucket->buckets_used)  bucket->buckets_used = i;
171    bucket->buckets[0] = NULL;
172    bucket->buckets_length[0] = 0;
173  }
174}
175
176static BOOLEAN kBucketIsCleared(kBucket_pt bucket)
177{
178  int i;
179
180  for (i = 0;i<=MAX_BUCKET;i++)
181  {
182    if (bucket->buckets[i] != NULL) return FALSE;
183    if (bucket->buckets_length[i] != 0) return FALSE;
184  }
185  return TRUE;
186}
187
188void kBucketInit(kBucket_pt bucket, poly lm, int length)
189{
190  assume(bucket != NULL);
191  assume(length <= 0 || length == pLength(lm));
192  assume(kBucketIsCleared(bucket));
193 
194  if (lm == NULL) return;
195
196  if (length <= 0)
197    length = pLength(lm);
198
199  bucket->buckets[0] = lm;
200  bucket->buckets_length[0] = 1;
201  if (length > 1)
202  {
203    unsigned int i = pLogLength(length-1);
204    bucket->buckets[i] = pNext(lm);
205    pNext(lm) = NULL;
206    bucket->buckets_length[i] = length-1;
207    bucket->buckets_used = i;
208  }
209  else
210  {
211    bucket->buckets_used = 0;
212  }
213}
214
215int kBucketCanonicalize(kBucket_pt bucket)
216{
217  poly p = bucket->buckets[1];
218  poly lm;
219  int pl = bucket->buckets_length[1], i;
220  bucket->buckets[1] = NULL;
221  bucket->buckets_length[1] = 0;
222
223
224  for (i=2; i<=bucket->buckets_used; i++)
225  {
226    p = p_Add_q(p, bucket->buckets[i],
227                 pl, bucket->buckets_length[i], bucket->bucket_ring);
228    bucket->buckets[i] = NULL;
229    bucket->buckets_length[i] = 0;
230  }
231
232  lm = bucket->buckets[0];
233  if (lm != NULL)
234  {
235    pNext(lm) = p;
236    p = lm;
237    pl++;
238    bucket->buckets[0] = NULL;
239    bucket->buckets_length[0] = 0;
240  }
241  if (pl > 0)
242  {
243    i = pLogLength(pl);
244    bucket->buckets[i] = p;
245    bucket->buckets_length[i] = pl;
246  }
247  else
248  {
249    i = 0;
250  }
251  bucket->buckets_used = i;
252  assume(pLength(p) == (int) pl);
253  return i;
254}
255
256void kBucketClear(kBucket_pt bucket, poly *p, int *length)
257{
258  int i = kBucketCanonicalize(bucket);
259  if (i > 0)
260  {
261    *p = bucket->buckets[i];
262    *length = bucket->buckets_length[i];
263    bucket->buckets[i] = NULL;
264    bucket->buckets_length[i] = 0;
265    bucket->buckets_used = 0;
266  }
267  else
268  {
269    *p = NULL;
270    *length = 0;
271  }
272}
273
274#else // HAVE_PSEUDO_BUCKETS
275
276void kBucketInit(kBucket_pt bucket, poly lm, int length)
277{
278  int i;
279
280  assume(bucket != NULL);
281  assume(length <= 0 || length == pLength(lm));
282
283  bucket->p = lm;
284  if (length <= 0) bucket->l = pLength(lm);
285  else bucket->l = length;
286
287}
288
289const poly kBucketGetLm(kBucket_pt bucket)
290{
291  return bucket->p;
292}
293
294poly kBucketExtractLm(kBucket_pt bucket)
295{
296  poly lm = bucket->p;
297  assume(pLength(bucket->p) == bucket->l);
298  pIter(bucket->p);
299  (bucket->l)--;
300  pNext(lm) = NULL;
301  return lm;
302}
303
304void kBucketClear(kBucket_pt bucket, poly *p, int *length)
305{
306  assume(pLength(bucket->p) == bucket->l);
307  *p = bucket->p;
308  *length = bucket->l;
309  bucket->p = NULL;
310  bucket->l = 0;
311}
312
313#endif // ! HAVE_PSEUDO_BUCKETS
314//////////////////////////////////////////////////////////////////////////
315///
316/// For changing the ring of the Bpoly to new_tailBin
317///
318void kBucketShallowCopyDelete(kBucket_pt bucket,
319                              ring new_tailRing, omBin new_tailBin,
320                              pShallowCopyDeleteProc p_shallow_copy_delete)
321{
322#ifndef HAVE_PSEUDO_BUCKETS
323  int i;
324 
325  kBucketCanonicalize(bucket);
326  for (i=0; i<= bucket->buckets_used; i++)
327    if (bucket->buckets[i] != NULL)
328      bucket->buckets[i] = p_shallow_copy_delete(bucket->buckets[i], 
329                                                 bucket->bucket_ring,
330                                                 new_tailRing,
331                                                 new_tailBin);
332#else
333  bucket->p = p_shallow_copy_delete(p,
334                                    bucket_ring,
335                                    new_tailRing,
336                                    new_tailBin);
337#endif
338  bucket->bucket_ring = new_tailRing;
339}
340
341
342
343//////////////////////////////////////////////////////////////////////////
344///
345/// Multiply Bucket by number ,i.e. Bpoly == n*Bpoly
346///
347void kBucket_Mult_n(kBucket_pt bucket, number n)
348{
349#ifndef HAVE_PSEUDO_BUCKETS
350  int i;
351
352  for (i=0; i<= bucket->buckets_used; i++)
353    if (bucket->buckets[i] != NULL)
354      bucket->buckets[i] = p_Mult_nn(bucket->buckets[i], n, bucket->bucket_ring);
355#else
356  bucket->p = p_Mult_nn(bucket->p, n, bucket->bucket_ring);
357#endif
358}
359
360//////////////////////////////////////////////////////////////////////////
361///
362/// Bpoly == Bpoly - m*p; where m is a monom
363/// Does not destroy p and m
364/// assume (*l <= 0 || pLength(p) == *l)
365void kBucket_Minus_m_Mult_p(kBucket_pt bucket, poly m, poly p, int *l,
366                            poly spNoether)
367{
368  assume(*l <= 0 || pLength(p) == *l);
369  int i, l1;
370  poly p1 = p;
371  poly last;
372  ring r = bucket->bucket_ring;
373
374  if (*l <= 0)
375  {
376    l1 = pLength(p1);
377    *l = l1;
378  }
379  else
380    l1 = *l;
381
382  if (m == NULL || p == NULL) return;
383
384#ifndef HAVE_PSEUDO_BUCKETS
385  kBucketMergeLm(bucket);
386  kbTest(bucket);
387  i = pLogLength(l1);
388
389  if (i <= bucket->buckets_used && bucket->buckets[i] != NULL)
390  {
391    p1 = p_Minus_mm_Mult_qq(bucket->buckets[i], m, p1,
392                            bucket->buckets_length[i], l1, 
393                            spNoether, r);
394    l1 = bucket->buckets_length[i];
395    bucket->buckets[i] = NULL;
396    bucket->buckets_length[i] = 0;
397    i = pLogLength(l1);
398  }
399  else
400  {
401    pSetCoeff0(m, nNeg(pGetCoeff(m)));
402    if (spNoether != NULL)
403    {
404      l1 = -1;
405      p1 = r->p_Procs->pp_Mult_mm_Noether(p1, m, spNoether, l1, r, last);
406      i = pLogLength(l1);
407    }
408    else
409      p1 = r->p_Procs->pp_Mult_mm(p1, m, r, last);
410    pSetCoeff0(m, nNeg(pGetCoeff(m)));
411  }
412   
413  while (bucket->buckets[i] != NULL)
414  {
415    p1 = p_Add_q(p1, bucket->buckets[i],
416                 l1, bucket->buckets_length[i], r);
417    bucket->buckets[i] = NULL;
418    bucket->buckets_length[i] = 0;
419    i = pLogLength(l1);
420  }
421
422  bucket->buckets[i] = p1;
423  bucket->buckets_length[i]=l1;
424  if (i >= bucket->buckets_used)
425    bucket->buckets_used = i;
426  else
427    kBucketAdjustBucketsUsed(bucket);
428#else // HAVE_PSEUDO_BUCKETS
429  bucket->p = p_Minus_mm_Mult_qq(bucket->p, m,  p,
430                               bucket->l, l1,
431                               spNoether, r);
432#endif
433  kbTest(bucket);
434}
435
436/////////////////////////////////////////////////////////////////////////////
437//
438// Extract all monomials from bucket with component comp
439// Return as a polynomial *p with length *l
440// In other words, afterwards
441// Bpoly == Bpoly - (poly consisting of all monomials with component comp)
442// and components of monomials of *p are all 0
443//
444
445// Hmm... for now I'm too lazy to implement those independent of currRing
446// But better declare it extern than including polys.h
447extern void pTakeOutComp(poly *p, Exponent_t comp, poly *q, int *lq);
448void pDecrOrdTakeOutComp(poly *p, Exponent_t comp, Order_t order,
449                         poly *q, int *lq);
450
451void kBucketTakeOutComp(kBucket_pt bucket,
452                        Exponent_t comp,
453                        poly *r_p, int *l)
454{
455  poly p = NULL, q;
456  int i, lp = 0, lq;
457
458#ifndef HAVE_PSEUDO_BUCKETS
459  kBucketMergeLm(bucket);
460  for (i=1; i<=bucket->buckets_used; i++)
461  {
462    if (bucket->buckets[i] != NULL)
463    {
464      pTakeOutComp(&(bucket->buckets[i]), comp, &q, &lq);
465      if (q != NULL)
466      {
467        assume(pLength(q) == lq);
468        bucket->buckets_length[i] -= lq;
469        assume(pLength(bucket->buckets[i]) == bucket->buckets_length[i]);
470        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
471      }
472    }
473  }
474  kBucketAdjustBucketsUsed(bucket);
475#else
476  pTakeOutComp(&(bucket->p), comp, &p, &lp);
477  (bucket->l) -= lp;
478#endif
479  *r_p = p;
480  *l = lp;
481
482  kbTest(bucket);
483}
484
485void kBucketDecrOrdTakeOutComp(kBucket_pt bucket,
486                               Exponent_t comp, Order_t order,
487                               poly *r_p, int *l)
488{
489  poly p = NULL, q;
490  int i, lp = 0, lq;
491
492#ifndef HAVE_PSEUDO_BUCKETS
493  kBucketMergeLm(bucket);
494  for (i=1; i<=bucket->buckets_used; i++)
495  {
496    if (bucket->buckets[i] != NULL)
497    {
498      pDecrOrdTakeOutComp(&(bucket->buckets[i]), comp, order, &q, &lq);
499      if (q != NULL)
500      {
501        bucket->buckets_length[i] -= lq;
502        p = p_Add_q(p, q, lp, lq, bucket->bucket_ring);
503      }
504    }
505  }
506  kBucketAdjustBucketsUsed(bucket);
507#else
508  pDecrOrdTakeOutComp(&(bucket->p), comp, order, &p, &lp);
509  (bucket->l) -= lp;
510#endif
511
512  *r_p = p;
513  *l = lp;
514}
515
516/////////////////////////////////////////////////////////////////////////////
517// Reduction of Bpoly with a given poly
518//
519
520extern int ksCheckCoeff(number *a, number *b);
521
522number kBucketPolyRed(kBucket_pt bucket,
523                      poly p1, int l1,
524                      poly spNoether)
525{
526  assume(p1 != NULL &&
527         p_DivisibleBy(p1,  kBucketGetLm(bucket), bucket->bucket_ring));
528  assume(pLength(p1) == (int) l1);
529
530  poly a1 = pNext(p1), lm = kBucketExtractLm(bucket);
531  BOOLEAN reset_vec=FALSE;
532  number rn;
533
534  if(a1==NULL)
535  {
536    p_DeleteLm(&lm, bucket->bucket_ring);
537    return nInit(1);
538  }
539
540  if (! nIsOne(pGetCoeff(p1)))
541  {
542    number an = pGetCoeff(p1), bn = pGetCoeff(lm);
543    int ct = ksCheckCoeff(&an, &bn);
544    p_SetCoeff(lm, bn, bucket->bucket_ring);
545    if ((ct == 0) || (ct == 2)) kBucket_Mult_n(bucket, an);
546    rn = an;
547  }
548  else
549  {
550    rn = nInit(1);
551  }
552
553  if (p_GetComp(p1, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
554  {
555    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
556    reset_vec = TRUE;
557    p_SetComp(lm, p_GetComp(p1, bucket->bucket_ring), bucket->bucket_ring);
558    p_Setm(lm, bucket->bucket_ring);
559  }
560
561  p_ExpVectorSub(lm,p1, bucket->bucket_ring);
562  l1--;
563
564  kBucket_Minus_m_Mult_p(bucket, lm, a1, &l1, spNoether);
565
566  p_DeleteLm(&lm, bucket->bucket_ring);
567  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
568  kbTest(bucket);
569  return rn;
570}
571
572
Note: See TracBrowser for help on using the repository browser.