exQHV
Compute Exclusive HyperVolumes sequentially
 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 arrayList hoList[D+1];
45 arrayList piList[D+1];
46 counterHash counters;
47 point* PS;
49 /*** file scope macro definitions *************************/
50 
51 /*** file scope type declarations *************************/
52 
53 /*** file scope variables *********************************/
54 
55 /*** file scope functions declarations ********************/
56 
57 static sureInline(int) popcount(unsigned int i);
58 
59 /*** public functions declarations ************************/
60 
61 /*** file scope functions *********************************/
62 
63 /* Classic binary divide-and-conquer popcount.
64  This is popcount_2() from
65  http://en.wikipedia.org/wiki/Hamming_weight */
66 /* 15 ops, 3 long immediates, 14 stages */
67 static sureInline(int) popcount(unsigned int x)
68 {
69  unsigned int m1 = 0x55555555;
70  unsigned int m2 = 0x33333333;
71  unsigned int m4 = 0x0f0f0f0f;
72  x -= (x >> 1) & m1;
73  x = (x & m2) + ((x >> 2) & m2);
74  x = (x + (x >> 4)) & m4;
75  x += x >> 8;
76  return (x + (x >> 16)) & 0x3f;
77 }
78 
79 /* ------------------------------------------------------ */
80 
81 /*** public functions *************************************/
82 
83 void initSplitter(void)
84 {
85  int i;
86 
87  i = 0;
88  while(i <= D)
89  {
90  hoList[i] = newArrayListDef();
91  piList[i] = newArrayListDef();
92  i++;
93  }
94  counters = CHalloc(1<<D);
95 }
96 
97 void destroySplitter(void)
98 {
99  int i;
100  i = 0;
101  while(i <= D)
102  {
103  freeArrayList(&(hoList[i]));
104  freeArrayList(&(piList[i]));
105  i++;
106  }
107  CHfree(&counters);
108  finishUnion();
109 }
110 
111 void push(int idx, int tp)
112 {
113  int i;
114 
115  i = popcount(tp);
116 
117  pushAL(hoList[i], tp);
118  pushAL(piList[i], idx);
119  CHinc(counters, tp, -1);
120 }
121 
123 {
124  division d;
125  int i;
126  int j;
127  int jj;
128  int limit;
129  int k;
130  arrayList hypocts;
131  arrayList pPositions;
132  int piAL;
133  int tc;
135  PS = tPS;
136 
137  hypocts = newArrayList(1<<D);
138  pPositions = newArrayListDef();
139  d = (division) calloc(1, sizeof(struct division));
140 
141  limit = 0;
142  piAL = 10;
143  d->points = (int*) calloc(piAL, sizeof(int));
144 
145  i = D;
146  while(i > 0)
147  {
150  tc = limit;
151  k = d->n;
152  j = 0;
153  while(j < size(hoList[i]))
154  {
155  if(CHget(counters, get(hoList[i])[j]) < 0)
156  {
157  d->n++;
158  pushAL(pPositions, tc);
159  tc -= CHget(counters, get(hoList[i])[j]);
160  /* printf("tc %d\n", tc); */
161  pushAL(hypocts, get(hoList[i])[j]);
162  CHinc(counters, get(hoList[i])[j], tc);
163  }
164  j++;
165  }
166  pushAL(pPositions, tc);
167 
168  if(piAL < tc)
169  { /* Alloc until position is accessible */
170  while(piAL < tc)
171  piAL *= 2;
172  d->points = (int*) realloc(d->points, piAL*sizeof(int));
173  }
174 
176  j = 0;
177  while(j < size(piList[i]))
178  {
179  jj = CHget(counters, get(hoList[i])[j]);
180  d->points[jj] = get(piList[i])[j];
181  CHinc(counters, get(hoList[i])[j], 1);
182  j++;
183  }
184 
186  jj = k;
187  j = get(pPositions)[jj];
188  while(jj < d->n)
189  {
190  resetUnion();
191  get(pPositions)[jj] = limit;
192  /* printf("%d - (", limit); */
193  while(j < get(pPositions)[jj+1])
194  {
195  if(!member(d->points[j]))
196  {
197  insertUnion(d->points[j]);
198  /* printf("%d, ", d->points[j]); */
199  d->points[limit] = d->points[j];
200  limit++;
201  }
202  j++;
203  }
204  /* printf(")\n"); */
205  jj++;
206  }
207  get(pPositions)[jj] = limit;
208 
210  int L;
211  int R;
212  int B;
214  while(k < d->n)
215  {
216  L = get(hypocts)[k];
217  R = 0;
218  B = 0;
219  while(L != 0)
220  {
221  R = R | B;
222  B = Rbit(L);
223  L = Rpop(L);
224  if((L | R) != 0)
225  {
226  jj = get(pPositions)[k];
229  j = dominant(PS, &(d->points[jj]),
230  get(pPositions)[k+1] - jj,
231  o, p,
232  L | R,
233  B);
234  while(j > 0)
235  {
236  j--;
237  push(d->points[jj+j], L | R);
238  }
239  }
240  }
241  k++;
242  }
243 
246  popAL(pPositions);
247  i--;
248  }
249  pushAL(pPositions, limit);
250 
252  i = D;
253  while(i > 0)
254  {
255  j = 0;
256  while(j < size(hoList[i]))
257  {
258  CHzero(counters, get(hoList[i])[j]);
259  j++;
260  }
261  clean(hoList[i]);
262  clean(piList[i]);
263  i--;
264  }
265 
266 
268  d->hypocts = splitAL(&hypocts);
269  d->pPositions = splitAL(&pPositions);
270  d->points = (int*) realloc(d->points, limit*sizeof(int));
271 
272  return d;
273 }
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.
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.
void destroySplitter(void)
Definition: splitter.c:97
int * hypocts
void resetUnion(void)
Definition: unionFilter.c:77
void push(int idx, int tp)
Definition: splitter.c:111
int * pPositions
#define D
Definition: point.h:49
void initSplitter(void)
Definition: splitter.c:83
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
void finishUnion(void)
Definition: unionFilter.c:71
Structure for uniting two sets, without repetition.
division newDivision(point *PS, point *o, point *p)
Definition: splitter.c:122
Point is an array of coordinates, in a struct for simple and fast copy.
Definition: point.h:58
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 insertUnion(int i)
Definition: unionFilter.c:95
int member(int i)
Definition: unionFilter.c:90