QHV
Compute 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 "Quick
8  * HyperVolume, Luís M. S. Russo, Alexandre P. Francisco IEEE Trans.
9  * Evolutionary Computation 18(4): 481-502(2014)".
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 
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <strings.h>
32 #include <assert.h>
33 #include "point.h"
34 #include "splitter.h"
35 #include "division.h"
36 #include "divisionStruct.c"
37 #include "arrayList.h"
38 #include "counterHash.h"
39 #include "unionFilter.h"
40 #include "subsets.h"
41 #include "dominant.h"
42 
43 /*** global variables *************************************/
44 
45 arrayList hoList[D+1];
46 arrayList piList[D+1];
47 counterHash counters;
48 point* PS;
50 /*** file scope macro definitions *************************/
51 
52 /*** file scope type declarations *************************/
53 
54 /*** file scope variables *********************************/
55 
56 /*** file scope functions declarations ********************/
57 
58 static sureInline(int) popcount(unsigned int i);
59 
60 /*** public functions declarations ************************/
61 
62 /*** file scope functions *********************************/
63 
64 /* Classic binary divide-and-conquer popcount.
65  This is popcount_2() from
66  http://en.wikipedia.org/wiki/Hamming_weight */
67 /* 15 ops, 3 long immediates, 14 stages */
68 static sureInline(int) popcount(unsigned int x)
69 {
70  unsigned int m1 = 0x55555555;
71  unsigned int m2 = 0x33333333;
72  unsigned int m4 = 0x0f0f0f0f;
73  x -= (x >> 1) & m1;
74  x = (x & m2) + ((x >> 2) & m2);
75  x = (x + (x >> 4)) & m4;
76  x += x >> 8;
77  return (x + (x >> 16)) & 0x3f;
78 }
79 
80 /* ------------------------------------------------------ */
81 
82 /*** public functions *************************************/
83 
84 void initSplitter(void)
85 {
86  int i;
87 
88  i = 0;
89  while(i <= D)
90  {
91  hoList[i] = newArrayListDef();
92  piList[i] = newArrayListDef();
93  i++;
94  }
95  counters = CHalloc(1<<D);
96 }
97 
98 void destroySplitter(void)
99 {
100  int i;
101  i = 0;
102  while(i <= D)
103  {
104  freeArrayList(&(hoList[i]));
105  freeArrayList(&(piList[i]));
106  i++;
107  }
108  CHfree(&counters);
109  finishUnion();
110 }
111 
112 void push(int idx, int tp)
113 {
114  int i;
115 
116  i = popcount(tp);
117 
118  pushAL(hoList[i], tp);
119  pushAL(piList[i], idx);
120  CHinc(counters, tp, -1);
121 }
122 
124 {
125  division d;
126  int i;
127  int j;
128  int jj;
129  int limit;
130  int k;
131  arrayList hypocts;
132  arrayList pPositions;
133  int piAL;
134  int tc;
136  /* PS = tPS; */
137 
138  hypocts = newArrayList(1<<D);
139  pPositions = newArrayListDef();
140  d = (division) calloc(1, sizeof(struct division));
141 
142  limit = 0;
143  piAL = 10;
144  d->points = (int*) calloc(piAL, sizeof(int));
145 
146  i = D;
147  while(i > 0)
148  {
151  tc = limit;
152  k = d->n;
153  j = 0;
154  while(j < size(hoList[i]))
155  {
156  if(CHget(counters, get(hoList[i])[j]) < 0)
157  {
158  d->n++;
159  pushAL(pPositions, tc);
160  tc -= CHget(counters, get(hoList[i])[j]);
161  /* printf("tc %d\n", tc); */
162  pushAL(hypocts, get(hoList[i])[j]);
163  CHinc(counters, get(hoList[i])[j], tc);
164  }
165  j++;
166  }
167  pushAL(pPositions, tc);
168 
169  if(piAL < tc)
170  { /* Alloc until position is accessible */
171  while(piAL < tc)
172  piAL *= 2;
173  d->points = (int*) realloc(d->points, piAL*sizeof(int));
174  }
175 
177  j = 0;
178  while(j < size(piList[i]))
179  {
180  jj = CHget(counters, get(hoList[i])[j]);
181  d->points[jj] = get(piList[i])[j];
182  CHinc(counters, get(hoList[i])[j], 1);
183  j++;
184  }
185 
187  jj = k;
188  j = get(pPositions)[jj];
189  while(jj < d->n)
190  {
191  resetUnion();
192  get(pPositions)[jj] = limit;
193  /* printf("%d - (", limit); */
194  while(j < get(pPositions)[jj+1])
195  {
196  if(!member(d->points[j]))
197  {
198  insertUnion(d->points[j]);
199  /* printf("%d, ", d->points[j]); */
200  d->points[limit] = d->points[j];
201  limit++;
202  }
203  j++;
204  }
205  /* printf(")\n"); */
206  jj++;
207  }
208  get(pPositions)[jj] = limit;
209 
211  int L;
212  int R;
213  int B;
215  while(k < d->n)
216  {
217  L = get(hypocts)[k];
218  R = 0;
219  B = 0;
220  while(L != 0)
221  {
222  R = R | B;
223  B = Rbit(L);
224  L = Rpop(L);
225  if((L | R) != 0)
226  {
227  jj = get(pPositions)[k];
230  j = dominant(tPS, &(d->points[jj]),
231  get(pPositions)[k+1] - jj,
232  o, p,
233  L | R,
234  B);
235  while(j > 0)
236  {
237  j--;
238  push(d->points[jj+j], L | R);
239  }
240  }
241  }
242  k++;
243  }
244 
247  popAL(pPositions);
248  i--;
249  }
250  pushAL(pPositions, limit);
251 
253  i = D;
254  while(i > 0)
255  {
256  j = 0;
257  while(j < size(hoList[i]))
258  {
259  CHzero(counters, get(hoList[i])[j]);
260  j++;
261  }
262  clean(hoList[i]);
263  clean(piList[i]);
264  i--;
265  }
266 
267 
269  d->hypocts = splitAL(&hypocts);
270  d->pPositions = splitAL(&pPositions);
271  d->points = (int*) realloc(d->points, limit*sizeof(int));
272 
273  return d;
274 }
counterHash CHalloc(int n)
Definition: counterHash.c:57
void CHzero(counterHash this, int i)
Definition: counterHash.c:79
int CHget(counterHash this, int i)
Definition: counterHash.c:84
A hash for containing counter values.
#define D
D is the number of dimensions.
Definition: pointStruct.h:43
void CHinc(counterHash this, int i, int a)
Definition: counterHash.c:74
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:98
int * hypocts
void resetUnion(void)
Definition: unionFilter.c:78
void push(int idx, int tp)
Definition: splitter.c:112
int * pPositions
void initSplitter(void)
Definition: splitter.c:84
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:72
Structure for uniting two sets, without repetition.
division newDivision(point *PS, point *o, point *p)
Definition: splitter.c:123
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:67
#define Rbit(N)
Definition: subsets.h:81
Less than 1K use array of counters.
Definition: counterHash.c:40
void insertUnion(int i)
Definition: unionFilter.c:96
int member(int i)
Definition: unionFilter.c:91