exQHV
Compute Exclusive HyperVolumes sequentially
 All Data Structures Files Functions Variables Macros
quickhvolume.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 <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <float.h>
32 #include <strings.h>
33 #include "quickhvolume.h"
34 #include "HSO.h"
35 #include "subsets.h"
36 #include "division.h"
37 #include "splitter.h"
38 #include "macros.h"
39 #include "inexclusion.h"
40 
41 /* global variables */
42 
43 /* file scope macro definitions */
44 
45 /* file scope type declarations */
46 
47 /* file scope variables */
48 
49 #ifdef COUNT
50 static double tops;
51 #endif /* COUNT */
52 
53 /* file scope functions declarations */
54 
66 static double quickExHVolumeR(point* zero,
67  point* one,
68  int n,
69  int* idx,
70  point* PS,
71  double* exHV);
72 #ifdef COUNT
73 static double WrappedExQuickHVolumeR(point* z,
74  point* o,
75  int n,
76  int* idx,
77  point* PS,
78  double* exHV);
79 #endif /* COUNT */
80 
81 /* paper: 1 */
82 static double quickExHVolumeR(point* z,
83  point* o,
84  int n,
85  int* idx,
86  point* PS,
87  double* exHV)
88 /* paper: 0 */
89 #ifdef COUNT
90 {
91  tops += n;
92  WrappedQuickExHVolumeR(z, o, n, idx, PS, exHV);
93 
94  return 0;
95 }
96 
97 static double WrappedQuickExHVolumeR(point* z,
98  point* o,
99  int n,
100  int* idx,
101  point* PS,
102  double* exHV);
103 #endif /* COUNT */
104 /* paper: 1 */
105 {
106  double tp[3];
107  double hv;
108  division d;
109  int i, j, k;
110  point p;
111  point pp;
112 /* paper: 0 */
113  point ppp;
114 /* paper: 1 */
115  point newo;
116  point newz;
117  double max;
118  point* A[3];
120 
122  k = 0;
123  A[0] = o;
124  A[1] = &ppp;
125  A[2] = &p;
126  while(k < 2)
127  {
128  max = -DBL_MAX;
129  i = k;
130  while(i < n)
131  {
132  intercept(&pp, A[k], &(PS[idx[i]]));
133  hv = objective(z, &pp, o);
134  if(hv > max)
135  {
136  max = hv;
137  j = i;
138  }
139  i++;
140  }
141 
142  intercept(A[k+1], A[k], &(PS[idx[j]]));
143  swap(idx, k, j);
144  k++;
145  }
146 
147  hv = HV(z, &p);
148 
150  i = 0;
151  while(i < n)
152  {
153  intercept(&pp, o, &(PS[idx[i]]));
154  push(idx[i], classify(&p, &pp));
155  i++;
156  }
157  d = newDivision(PS, o, &p);
158 
160  while(hasNext(d))
161  {
162  idx = next(d, &j, &n);
163  projectZero(&newz, &p, j, z);
164  projectOne(&newo, &p, j, o);
165 
166 /* paper: 0 */
167  if(n < N)
168  {
169  switch(n)
170  {
171  case 1:
172  intercept(&pp, &newo, &(PS[idx[0]]));
173  tp[0] = HV(&newz, &pp);
174  hv += tp[0];
175  exHV[idx[0]] += tp[0];
176  break;
177 
178  case 2:
179  intercept(&pp, &newo, &(PS[idx[0]]));
180  tp[0] = HV(&newz, &pp);
181  hv += tp[0];
182 
183  intercept(&ppp, &newo, &(PS[idx[1]]));
184  tp[1] = HV(&newz, &ppp);
185  hv += tp[1];
186 
187  intercept(&pp, &pp, &ppp);
188  tp[2] = HV(&newz, &pp);
189  hv -= tp[2];
190 
191  exHV[idx[0]] += tp[0] - tp[2];
192  exHV[idx[1]] += tp[1] - tp[2];
193  break;
194 
195  default:
196  if(HSOL < n)
197  hv += exHSO(&newz, &newo, n, idx, PS, exHV);
198  else
199  hv += exInExClusion(&newz, &newo, n, idx, PS, exHV);
200  break;
201  }
202  }
203  else
204 /* paper: 1 */
205  {
206  /* if(on > 10 && bits(j)+log2((double)n/(double)on) > 3) */
207  /* printf("bits:%d number:%d fraction:%f\n", bits(j), on, log2((double)n/(double)on)); */
208  hv += quickExHVolumeR(&newz, &newo, n, idx, PS, exHV);
209  }
210  }
211  freeDivision(&d);
212 
213  return hv;
214 }
215 /* paper: 0 */
216 
217 /* public functions */
218 
219 double quickExHVolume(int n, point* PS, double* exHV)
220 {
221  double res;
222  int* idx;
223  int i;
224 
225 #ifdef COUNT
226  tops = 0;
227 #endif /* COUNT */
228 
229  idx = (int*) malloc(n*sizeof(int));
230  i = 0;
231  while(i < n)
232  {
233  if(exHV != NULL)
234  exHV[i] = 0;
235  idx[i] = i;
236  i++;
237  }
238 
239  res = quickExHVolumeR(&cZero, &cOne, n, idx, PS, exHV);
240 
241  free(idx);
242 
243 #ifdef COUNT
244  printf("%d %d %f\n", n, D, tops);
245 #endif /* COUNT */
246 
247  return res;
248 }
249 
250 /* ------------------------------------------------------ */
double exHSO(point *zero, point *one, int n, int *idx, point *PS, double *exHV)
Definition: HSO.c:288
double exInExClusion(point *zero, point *one, int n, int *idx, point *PS, double *exHV)
Definition: inexclusion.c:177
#define objective(Z, A, O)
Definition: point.h:96
point cZero
Definition: point.c:44
void freeDivision(division *d)
New divisions are created in the splitter object.
Definition: division.c:53
int * next(division d, int *hypoct, int *n)
Definition: division.c:68
This returns iterators for diferent type. WARNING, these objects are singleton, so new overwrites exi...
This struct is public because of splitter. Do not use direct access.
void push(int idx, int tp)
Definition: splitter.c:111
#define D
Definition: point.h:49
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.
division newDivision(point *PS, point *o, point *p)
Definition: splitter.c:122
Inclusion Exclusion Algorithm better than HSO for high d and small n.
Point is an array of coordinates, in a struct for simple and fast copy.
Definition: point.h:58
int hasNext(division d)
Definition: division.c:63
Header: copy HSO.
point cOne
Definition: point.c:45