parExQHV
Compute Exclusive 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 #warning TODO: Changing semantics. Module may be incoherent.
190  d->points[jj] = get(piList[i])[j];
191  CHinc(counters, get(hoList[i])[j], 1);
192  j++;
193  }
194 
196  jj = k;
197  j = get(pPositions)[jj];
198  while(jj < d->n)
199  {
200  resetUnion(&(sd->uD));
201  get(pPositions)[jj] = limit;
202  /* printf("%d - (", limit); */
203  while(j < get(pPositions)[jj+1])
204  {
205  if(!member(d->points[j], &(sd->uD)))
206  {
207  insertUnion(d->points[j], &(sd->uD));
208  /* printf("%d, ", d->points[j]); */
209  d->points[limit] = d->points[j];
210  limit++;
211  }
212  j++;
213  }
214  /* printf(")\n"); */
215  jj++;
216  }
217  get(pPositions)[jj] = limit;
218 
220  int L;
221  int R;
222  int B;
224  while(k < d->n)
225  {
226  L = get(hypocts)[k];
227  R = 0;
228  B = 0;
229  while(L != 0)
230  {
231  R = R | B;
232  B = Rbit(L);
233  L = Rpop(L);
234  if((L | R) != 0)
235  {
236  jj = get(pPositions)[k];
239  j = dominant(tPS, &(d->points[jj]),
240  get(pPositions)[k+1] - jj,
241  o, p,
242  L | R,
243  B,
244  &(sd->doD));
245  while(j > 0)
246  {
247  j--;
248  push(d->points[jj+j], L | R, sd);
249  }
250  }
251  }
252  k++;
253  }
254 
257  popAL(pPositions);
258  i--;
259  }
260  pushAL(pPositions, limit);
261 
263  i = D;
264  while(i > 0)
265  {
266  j = 0;
267  while(j < size(hoList[i]))
268  {
269  CHzero(counters, get(hoList[i])[j]);
270  j++;
271  }
272  clean(hoList[i]);
273  clean(piList[i]);
274  i--;
275  }
276 
277 
279  d->hypocts = splitAL(&hypocts);
280  d->pPositions = splitAL(&pPositions);
281  d->points = (int*) realloc(d->points, limit*sizeof(int));
282 
283  return d;
284 }
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