parQHV
Compute HyperVolumes using threads
 All Data Structures Files Functions Variables Macros
splitter.c
1 /*
2  *
3  * Copyright (c) Year(s), 2013, Luis M. S. Russo and Alexandre
4  * P. Francisco / KDBIO / INESC-ID, <qhv@kdbio.inesc-id.pt>
5  *
6  * Any published media that is related with to use of the distributed
7  * software, or derived software, must contain a reference to "Extending
8  * quick hypervolume. Luís M. S. Russo, Alexandre P. Francisco:
9  * J. Heuristics 22(3): 245-271 (2016)".
10  *
11  * Permission to use, copy, modify, and/or distribute this software for
12  * any purpose with or without fee is hereby granted, provided that the
13  * above copyright notice and this permission notice appear in all
14  * copies.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
17  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
18  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
19  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
20  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
21  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23  * PERFORMANCE OF THIS SOFTWARE.
24  *
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <strings.h>
31 #include <assert.h>
32 #include "point.h"
33 #include "splitter.h"
34 #include "division.h"
35 #include "divisionStruct.c"
36 #include "arrayList.h"
37 #include "counterHash.h"
38 #include "unionFilter.h"
39 #include "subsets.h"
40 #include "dominant.h"
41 
42 /*** global variables *************************************/
43 
44 /*** file scope macro definitions *************************/
45 
46 /*** file scope type declarations *************************/
47 
48 /*** file scope variables *********************************/
49 
50 /*** file scope functions declarations ********************/
51 
52 static sureInline(int) popcount(unsigned int i);
53 
54 /*** public functions declarations ************************/
55 
56 /*** file scope functions *********************************/
57 
58 /* Classic binary divide-and-conquer popcount.
59  This is popcount_2() from
60  http://en.wikipedia.org/wiki/Hamming_weight */
61 /* 15 ops, 3 long immediates, 14 stages */
62 static sureInline(int) popcount(unsigned int x)
63 {
64  unsigned int m1 = 0x55555555;
65  unsigned int m2 = 0x33333333;
66  unsigned int m4 = 0x0f0f0f0f;
67  x -= (x >> 1) & m1;
68  x = (x & m2) + ((x >> 2) & m2);
69  x = (x + (x >> 4)) & m4;
70  x += x >> 8;
71  return (x + (x >> 16)) & 0x3f;
72 }
73 
74 /* ------------------------------------------------------ */
75 
76 /*** public functions *************************************/
77 
78 void initSplitter(struct spData * sd)
79 {
80  int i;
81 
82  arrayList* hoList = sd->hoList;
83  arrayList* piList = sd->piList;
84 
85  i = 0;
86  while(i <= D)
87  {
88  hoList[i] = newArrayListDef();
89  piList[i] = newArrayListDef();
90  i++;
91  }
92  sd->counters = CHalloc(1<<D);
93 }
94 
95 void destroySplitter(struct spData * sd)
96 {
97  int i;
98 
99  arrayList* hoList = sd->hoList;
100  arrayList* piList = sd->piList;
101 
102  i = 0;
103  while(i <= D)
104  {
105  freeArrayList(&(hoList[i]));
106  freeArrayList(&(piList[i]));
107  i++;
108  }
109 
110  CHfree(&(sd->counters));
111  finishUnion(&(sd->uD));
112 }
113 
114 void push(int idx, int tp, struct spData * sd)
115 {
116  int i;
117 
118  arrayList* hoList = sd->hoList;
119  arrayList* piList = sd->piList;
120  counterHash counters = sd->counters;
121 
122  i = popcount(tp);
123 
124  pushAL(hoList[i], tp);
125  pushAL(piList[i], idx);
126  CHinc(counters, tp, -1);
127 }
128 
129 division newDivision(point* tPS, point* o, point* p, struct spData * sd)
130 {
131  division d;
132  int i;
133  int j;
134  int jj;
135  int limit;
136  int k;
137  arrayList hypocts;
138  arrayList pPositions;
139  int piAL;
140  int tc;
142  arrayList* hoList = sd->hoList;
143  arrayList* piList = sd->piList;
144  counterHash counters = sd->counters;
145 
146  hypocts = newArrayList(1<<D);
147  pPositions = newArrayListDef();
148  d = (division) calloc(1, sizeof(struct division));
149 
150  limit = 0;
151  piAL = 10;
152  d->points = (int*) calloc(piAL, sizeof(int));
153 
154  i = D;
155  while(i > 0)
156  {
159  tc = limit;
160  k = d->n;
161  j = 0;
162  while(j < size(hoList[i]))
163  {
164  if(CHget(counters, get(hoList[i])[j]) < 0)
165  {
166  d->n++;
167  pushAL(pPositions, tc);
168  tc -= CHget(counters, get(hoList[i])[j]);
169  /* printf("tc %d\n", tc); */
170  pushAL(hypocts, get(hoList[i])[j]);
171  CHinc(counters, get(hoList[i])[j], tc);
172  }
173  j++;
174  }
175  pushAL(pPositions, tc);
176 
177  if(piAL < tc)
178  { /* Alloc until position is accessible */
179  while(piAL < tc)
180  piAL *= 2;
181  d->points = (int*) realloc(d->points, piAL*sizeof(int));
182  }
183 
185  j = 0;
186  while(j < size(piList[i]))
187  {
188  jj = CHget(counters, get(hoList[i])[j]);
189  d->points[jj] = get(piList[i])[j];
190  CHinc(counters, get(hoList[i])[j], 1);
191  j++;
192  }
193 
195  jj = k;
196  j = get(pPositions)[jj];
197  while(jj < d->n)
198  {
199  resetUnion(&(sd->uD));
200  get(pPositions)[jj] = limit;
201  /* printf("%d - (", limit); */
202  while(j < get(pPositions)[jj+1])
203  {
204  if(!member(d->points[j], &(sd->uD)))
205  {
206  insertUnion(d->points[j], &(sd->uD));
207  /* printf("%d, ", d->points[j]); */
208  d->points[limit] = d->points[j];
209  limit++;
210  }
211  j++;
212  }
213  /* printf(")\n"); */
214  jj++;
215  }
216  get(pPositions)[jj] = limit;
217 
219  int L;
220  int R;
221  int B;
223  while(k < d->n)
224  {
225  L = get(hypocts)[k];
226  R = 0;
227  B = 0;
228  while(L != 0)
229  {
230  R = R | B;
231  B = Rbit(L);
232  L = Rpop(L);
233  if((L | R) != 0)
234  {
235  jj = get(pPositions)[k];
238  j = dominant(tPS, &(d->points[jj]),
239  get(pPositions)[k+1] - jj,
240  o, p,
241  L | R,
242  B,
243  &(sd->doD));
244  while(j > 0)
245  {
246  j--;
247  push(d->points[jj+j], L | R, sd);
248  }
249  }
250  }
251  k++;
252  }
253 
256  popAL(pPositions);
257  i--;
258  }
259  pushAL(pPositions, limit);
260 
262  i = D;
263  while(i > 0)
264  {
265  j = 0;
266  while(j < size(hoList[i]))
267  {
268  CHzero(counters, get(hoList[i])[j]);
269  j++;
270  }
271  clean(hoList[i]);
272  clean(piList[i]);
273  i--;
274  }
275 
276 
278  d->hypocts = splitAL(&hypocts);
279  d->pPositions = splitAL(&pPositions);
280  d->points = (int*) realloc(d->points, limit*sizeof(int));
281 
282  return d;
283 }
counterHash CHalloc(int n)
Definition: counterHash.c:56
void CHzero(counterHash this, int i)
Definition: counterHash.c:78
int CHget(counterHash this, int i)
Definition: counterHash.c:83
A hash for containing counter values.
#define D
D is the number of dimensions.
Definition: pointStruct.h:43
division newDivision(point *PS, point *o, point *p, struct spData *sd)
Definition: splitter.c:129
void CHinc(counterHash this, int i, int a)
Definition: counterHash.c:73
This header implements an arrayList for integers.
This returns iterators for diferent type. WARNING, these objects are singleton, so new overwrites exi...
Simple point interface. Contains simple point manipulation functions.
#define Rpop(N)
Definition: subsets.h:88
This struct is public because of splitter. Do not use direct access.
int * hypocts
void initSplitter(struct spData *sd)
Definition: splitter.c:78
int * pPositions
void push(int idx, int tp, struct spData *sd)
Definition: splitter.c:114
A splitter for storing classified points. The splitter is an array that grows dinamically, when all points are inserted they are separeted into classes by sorting. Preferably count sort or hased count sort.
int * points
int member(int i, struct unionData *ud)
Definition: unionFilter.c:88
Structure for uniting two sets, without repetition.
Point is an array of coordinates, in a struct for simple and fast copy.
Definition: pointStruct.h:47
void CHfree(counterHash *this)
Definition: counterHash.c:66
#define Rbit(N)
Definition: subsets.h:81
Less than 1K use array of counters.
Definition: counterHash.c:39
void finishUnion(struct unionData *ud)
Definition: unionFilter.c:66
void resetUnion(struct unionData *ud)
Definition: unionFilter.c:72
void insertUnion(int i, struct unionData *ud)
Definition: unionFilter.c:93
void destroySplitter(struct spData *sd)
Definition: splitter.c:95