parQHV
Compute HyperVolumes using threads
 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 <pthread.h>
28 #include <stdio.h>
29 #include <assert.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <float.h>
33 #include <strings.h>
34 #include <sys/types.h> /* basic system data types */
35 #include <limits.h> /* PIPE_BUF */
36 #include "unionFilter.h"
37 #include "quickhvolume.h"
38 #include "constants.h"
39 #include "HSO.h"
40 #include "subsets.h"
41 #include "division.h"
42 #include "splitter.h"
43 #include "macros.h"
44 #include "inexclusion.h"
45 #include "tpool.h"
46 
47 void openBox(toolBox* b)
48 {
49 #warning TODO: There should be a better solution to the initUnion problem.
50 
51  b->spt.uD.size = 0; /* This was hidden in a static variable. */
52  initUnion(NPOINTS, &(b->spt.uD));
54  initSplitter(&(b->spt));
55 }
56 
57 void closeBox(toolBox* b)
58 {
59  destroySplitter(&(b->spt));
60 }
61 
62 int priority(taskData* d)
63 {
64  return d->n;
65 }
66 
67 void jobCopy(jobData* dst, jobData* src)
68 {
69  dst->n = src->n;
70  memcpy(&(dst->PS[0]), &(src->PS[0]), (src->n)*sizeof(point));
71  dst->r = 0; /* Start at partial value 0 */
72 }
73 
74 void taskCopy(taskData* dst, taskData* src)
75 {
76  memcpy(dst, src, offsetof(struct taskData, idx));
77  memcpy(&(dst->idx[0]), &(src->idx[0]), (src->n)*sizeof(int));
78 
79  dst->r = 0; /* Do not copy results */
80 }
81 
82 void merge(jobData* dst, taskData* src)
83 {
84  dst->r += src->r;
85 }
86 
87 void publish(int jid, jobData* jd)
88 {
89  printf("%1.10f\n", jd->r);
90 }
91 
92 /* global variables */
93 
94 /* file scope macro definitions */
95 
96 /* file scope type declarations */
97 
98 /* file scope variables */
99 
100 /* file scope functions declarations */
101 
102 static void quickHVolumeR(toolBox* b, taskData* d, const jobData* jd);
103 
112 static void drop(int* idx, int* n, int j);
113 
114 /* file scope functions */
115 
116 static void drop(int* idx, int* n, int j)
117 {
118  (*n)--;
119  idx[j] = idx[*n];
120 }
121 
122 void quickHVolumeS(toolBox* b, taskData* d, const jobData* jd)
123 {
124  point p;
125  point pp;
127  if(d->n < N)
128  /* if(1 == d->n) */
129  {
130  switch(d->n)
131  {
132  case 1:
133  intercept(&p, &(d->o), &(jd->PS[d->idx[0]]));
134  d->r += HV(&(d->z), &p);
135  break;
136  case 2:
137  intercept(&p, &(d->o), &(jd->PS[d->idx[0]]));
138  d->r += HV(&(d->z), &p);
139  intercept(&pp, &(d->o), &(jd->PS[d->idx[1]]));
140  d->r += HV(&(d->z), &pp);
141  intercept(&p, &p, &pp);
142  d->r -= HV(&(d->z), &p);
143  break;
144  default:
145  d->r += InExClusion(&(d->z), &(d->o), d->n, d->idx, jd->PS, &(b->iex));
146  break;
147  }
148  }
149  else
150  {
151  quickHVolumeR(b, d, jd);
152  }
153 }
154 
155 /* paper: 1 */
156 static void quickHVolumeR(toolBox* b, taskData* d, const jobData* jd)
157 {
158  double hv;
159  division di;
160  int i, j;
161  point p;
162  point pp;
163  double max;
164  int* nidx;
166  taskData ld;
168  max = -DBL_MAX;
170  i = 0;
172  while(i < d->n)
173  {
174  intercept(&pp, &(d->o), &(jd->PS[d->idx[i]]));
175  hv = objective(&(d->z), &pp, &(d->o));
176  if(hv > max)
177  {
178  max = hv;
179  j = i;
180  }
181  i++;
182  }
183 
185  intercept(&p, &(d->o), &(jd->PS[d->idx[j]]));
186  d->r += HV(&(d->z), &p);
187  drop(d->idx, &(d->n), j);
188 
190  i = 0;
191  while(i < d->n)
192  {
193  intercept(&pp, &(d->o), &(jd->PS[d->idx[i]]));
194  push(d->idx[i], classify(&p, &pp), &(b->spt));
195  i++;
196  }
197  di = newDivision(&(jd->PS[0]), &(d->o), &p, &(b->spt));
198 
199  ld.o = d->o;
200  ld.z = d->z;
201  ld.n = d->n;
202 
204  while(hasNext(di))
205  {
206  nidx = next(di, &j, &(d->n));
207  memcpy(d->idx, nidx, (d->n)*sizeof(int));
208  projectZero(&(d->z), &p, j, &(ld.z));
209  projectOne(&(d->o), &p, j, &(ld.o));
210 
211  prun(d, d->n >= N);
212  /* prun(d, ld.n+1 >= jd->n); /\**< Recursive call to quickHyperVolume *\/ */
213  }
214 
215  freeDivision(&di);
216 }
217 /* paper: 0 */
218 
219 /* public functions */
220 
221 /* ------------------------------------------------------ */
#define objective(Z, A, O)
Definition: point.h:84
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
division newDivision(point *PS, point *o, point *p, struct spData *sd)
Definition: splitter.c:129
This returns iterators for diferent type. WARNING, these objects are singleton, so new overwrites exi...
void initUnion(int n, struct unionData *ud)
Definition: unionFilter.c:49
This struct is public because of splitter. Do not use direct access.
Definition: tdata.h:48
double InExClusion(point *zero, point *one, int n, int *idx, point *PS, struct iex *ax)
Definition: inexclusion.c:104
void initSplitter(struct spData *sd)
Definition: splitter.c:78
Definition: tdata.h:80
double r
Definition: tdata.h:76
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.
Structure for uniting two sets, without repetition.
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: pointStruct.h:47
int hasNext(division d)
Definition: division.c:63
Definition: tdata.h:72
void destroySplitter(struct spData *sd)
Definition: splitter.c:95
Header: copy HSO.