source: git/Singular/sbuckets.cc @ 8cfee1c

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