source: git/kernel/sbuckets.cc @ 68349d

spielwiese
Last change on this file since 68349d was 35aab3, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6879, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6880 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 6.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    sbuckets.cc
6 *  Purpose: implementation of routines for sorting polys using
7 *           a bucket sort
8 *  Author:  obachman (Olaf Bachmann)
9 *  Created: 9/00
10 *  Version: $Id: sbuckets.cc,v 1.1.1.1 2003-10-06 12:16:02 Singular Exp $
11 *******************************************************************/
12#include "mod2.h"
13
14#include "sbuckets.h"
15#include "omalloc.h"
16#include "ring.h"
17#include "p_Procs.h"
18#include "p_polys.h"
19
20
21
22//////////////////////////////////////////////////////////////////////////
23// Declarations
24//
25
26class sBucketPoly
27{
28public:
29  poly p;
30  long length;
31};
32
33class sBucket
34{
35public:
36  ring          bucket_ring;
37  long          max_bucket;
38  sBucketPoly   buckets[BIT_SIZEOF_LONG - 3];
39}
40;
41
42static omBin sBucket_bin = omGetSpecBin(sizeof(sBucket));
43
44/////////////////////////////////////////////////////////////////////////////
45// internal routines
46//
47// returns floor(log_2(i))
48inline int LOG2(int i)
49{
50  assume (i > 0);
51  int j = 0;
52
53  do
54  {
55    i = i >> 1;
56    if (i == 0) return j;
57    j++;
58  }
59  while (1);
60
61  return j;
62}
63
64//////////////////////////////////////////////////////////////////////////
65// Creation/Destruction of buckets
66//
67sBucket_pt    sBucketCreate(ring r)
68{
69  sBucket_pt bucket = (sBucket_pt) omAlloc0Bin(sBucket_bin);
70  bucket->bucket_ring = r;
71  return bucket;
72}
73
74void          sBucketDestroy(sBucket_pt *bucket)
75{
76  assume(bucket != NULL);
77  omFreeBin(*bucket, sBucket_bin);
78  *bucket = NULL;
79}
80
81/////////////////////////////////////////////////////////////////////////////
82// Convertion from/to SBpolys
83//
84
85static void sBucket_Merge_m(sBucket_pt bucket, poly p)
86{
87  assume(p != NULL && pNext(p) == NULL);
88  int length = 1;
89  int i = 0;
90
91  while (bucket->buckets[i].p != NULL)
92  {
93    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
94    length += bucket->buckets[i].length;
95    bucket->buckets[i].p = NULL;
96    bucket->buckets[i].length = 0;
97    i++;
98    assume(LOG2(length) == i);
99  }
100
101  bucket->buckets[i].p = p;
102  bucket->buckets[i].length = length;
103  if (i > bucket->max_bucket) bucket->max_bucket = i;
104}
105
106void sBucket_Merge_p(sBucket_pt bucket, poly p, int length)
107{
108  assume(bucket != NULL);
109  assume(length <= 0 || length == pLength(p));
110
111  if (p == NULL) return;
112  if (length <= 0) length = pLength(p);
113
114  int i = LOG2(length);
115
116  while (bucket->buckets[i].p != NULL)
117  {
118    p = p_Merge_q(p, bucket->buckets[i].p, bucket->bucket_ring);
119    length += bucket->buckets[i].length;
120    bucket->buckets[i].p = NULL;
121    bucket->buckets[i].length = 0;
122    i++;
123    assume(LOG2(length) == i);
124  }
125
126  bucket->buckets[i].p = p;
127  bucket->buckets[i].length = length;
128  if (i > bucket->max_bucket) bucket->max_bucket = i;
129}
130
131void sBucket_Add_p(sBucket_pt bucket, poly p, int length)
132{
133  assume(bucket != NULL);
134  assume(length <= 0 || length == pLength(p));
135
136  if (p == NULL) return;
137  if (length <= 0) length = pLength(p);
138
139  int i = LOG2(length);
140
141  while (bucket->buckets[i].p != NULL)
142  {
143    p = p_Add_q(p, bucket->buckets[i].p, length, bucket->buckets[i].length,
144                bucket->bucket_ring);
145    bucket->buckets[i].p = NULL;
146    bucket->buckets[i].length = 0;
147    i = LOG2(length);
148  }
149
150  bucket->buckets[i].p = p;
151  bucket->buckets[i].length = length;
152  if (i > bucket->max_bucket) bucket->max_bucket = i;
153}
154
155// Converts SBpoly into a poly and clears bucket
156// i.e., afterwards SBpoly == 0
157void sBucketClearMerge(sBucket_pt bucket, poly *p, int *length)
158{
159  poly pr = NULL;
160  int  lr = 0;
161  int i = 0;
162
163  while (bucket->buckets[i].p == NULL)
164  {
165    i++;
166    if (i > bucket->max_bucket) goto done;
167  }
168
169  pr = bucket->buckets[i].p;
170  lr = bucket->buckets[i].length;
171  bucket->buckets[i].p = NULL;
172  bucket->buckets[i].length = 0;
173  i++;
174
175  while (i <= bucket->max_bucket)
176  {
177    if (bucket->buckets[i].p != NULL)
178    {
179      pr = p_Merge_q(pr, bucket->buckets[i].p,bucket->bucket_ring);
180      lr += bucket->buckets[i].length;
181      bucket->buckets[i].p = NULL;
182      bucket->buckets[i].length = 0;
183    }
184    i++;
185  }
186
187  done:
188  *p = pr;
189  *length = lr;
190  bucket->max_bucket = 0;
191}
192
193// Converts SBpoly into a poly and clears bucket
194// i.e., afterwards SBpoly == 0
195void sBucketClearAdd(sBucket_pt bucket, poly *p, int *length)
196{
197  poly pr = NULL;
198  int  lr = 0;
199  int i = 0;
200
201  while (bucket->buckets[i].p == NULL)
202  {
203    i++;
204    if (i > bucket->max_bucket) goto done;
205  }
206
207  pr = bucket->buckets[i].p;
208  lr = bucket->buckets[i].length;
209  bucket->buckets[i].p = NULL;
210  bucket->buckets[i].length = 0;
211  i++;
212
213  while (i <= bucket->max_bucket)
214  {
215    if (bucket->buckets[i].p != NULL)
216    {
217      pr = p_Add_q(pr, bucket->buckets[i].p, lr, bucket->buckets[i].length,
218                   bucket->bucket_ring);
219      bucket->buckets[i].p = NULL;
220      bucket->buckets[i].length = 0;
221    }
222    i++;
223  }
224
225  done:
226  *p = pr;
227  *length = lr;
228  bucket->max_bucket = 0;
229}
230
231/////////////////////////////////////////////////////////////////////////////
232// Sorts a poly using BucketSort
233//
234
235poly sBucketSortMerge(poly p, ring r)
236{
237#ifdef HAVE_ASSUME
238  int l_in = pLength(p);
239#endif
240
241  if (p == NULL || pNext(p) == NULL) return p;
242
243  sBucket_pt bucket = sBucketCreate(r);
244  poly pn = pNext(p);
245
246  do
247  {
248    pNext(p) = NULL;
249    sBucket_Merge_m(bucket, p);
250    p = pn;
251    if (p == NULL) break;
252    pn = pNext(pn);
253  }
254  while (1);
255
256  int l_dummy;
257  sBucketClearMerge(bucket, &pn, &l_dummy);
258  sBucketDestroy(&bucket);
259
260  p_Test(pn, r);
261#ifdef HAVE_ASSUME
262  assume(l_dummy == pLength(pn));
263  assume(l_in == l_dummy);
264#endif
265  return pn;
266}
267
268/////////////////////////////////////////////////////////////////////////////
269// Sorts a poly using BucketSort
270//
271
272poly sBucketSortAdd(poly p, ring r)
273{
274#ifdef HAVE_ASSUME
275  int l_in = pLength(p);
276#endif
277
278  if (p == NULL || pNext(p) == NULL) return p;
279
280  sBucket_pt bucket = sBucketCreate(r);
281  poly pn = pNext(p);
282
283  do
284  {
285    pNext(p) = NULL;
286    sBucket_Add_p(bucket, p, 1);
287    p = pn;
288    if (p == NULL) break;
289    pn = pNext(pn);
290  }
291  while (1);
292
293  int l_dummy;
294  sBucketClearAdd(bucket, &pn, &l_dummy);
295  sBucketDestroy(&bucket);
296
297  p_Test(pn, r);
298#ifdef HAVE_ASSUME
299  assume(l_dummy == pLength(pn));
300  assume(l_in >= l_dummy);
301#endif
302  return pn;
303}
Note: See TracBrowser for help on using the repository browser.