parQHV
Compute HyperVolumes using threads
 All Data Structures Files Functions Variables Macros
HSO.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 "constants.h"
32 #include "HSO.h"
33 #include "macros.h"
34 
35 /* global variables */
36 
37 /* file scope macro definitions */
38 
39 /* file scope type declarations */
40 
41 /* file scope variables */
42 static int i;
43 static unsigned char p;
44 static unsigned char c[D] __attribute__ ((aligned (CLS)));
47 static double V[D-1] __attribute__ ((aligned (CLS)));
49 static unsigned char S[D][N+2] __attribute__ ((aligned (CLS)));
53 static point P[N+2] __attribute__ ((aligned (CLS)));
54 static double tX[N+2] __attribute__ ((aligned (CLS)));
55 
56 /* file scope functions declarations */
57 
63 static sureInline(void) showPoint(int a);
64 
69 static sureInline(void) showS();
70 
74 static sureInline(void) get2D();
75 
79 static sureInline(void) insert();
80 
81 /* file scope functions */
82 
83 static sureInline(void) showPoint(int a)
84 {
85  int t;
86 
87  t = 0;
88  printf("(");
89  while(t < D) {
90  printf("%.1f ", P[a].x[t]);
91  t++;
92  }
93  printf("), ");
94 }
95 
96 static sureInline(void) showS()
97 {
98  int t;
99  int cc;
100 
101  t = 0;
102  while(t < D-1)
103  {
104  printf("V[%d]=%.1f ", t, V[t]);
105  cc = c[t];
106  while(cc <= N+1)
107  {
108  showPoint(S[t][cc]);
109  cc++;
110  }
111  printf("/\n");
112  t++;
113  }
114 }
115 
116 static sureInline(void) insert()
117 {
118  unsigned char* s;
119  int k, l;
120 
121  if (i < D-2) {
122  s = &S[i][c[i]-1];
123  do
124  {
125  s++;
126  *s = *(s+1);
127  }while(P[p].x[i] > P[*s].x[i]);
129  *s = p;
130  c[i]--;
131  S[i][c[i]] = 0;
132 
133  V[i] = 0;
135  c[i+1] = N;
136  S[i+1][c[i+1]] = 0;
137  S[i+1][N+1] = 1;
138  if (i == D-3) {
139  V[i+1] = 0;
140  c[i+2] = N;
141  S[i+2][c[i+2]] = 1;
142  S[i+2][N+1] = 1;
143  }
144  } else {
145 
146  tX[p] = P[p].x[i+1];
147  tX[1] = P[1].x[i+1];
148 
149  k = c[i];
150  S[i][k] = S[i][k+1];
151  S[i+1][k] = S[i+1][k+1];
152 
153  c[i]--;
154  l = c[i];
155  S[i][c[i]] = 0;
156  c[i+1]--;
157  S[i+1][c[i+1]] = 1;
158 
159  while (S[i+1][k] == 0 || P[p].x[i] > P[S[i][k]].x[i]) {
160 
161  if (S[i+1][k] == 1 && tX[p] > tX[S[i][k]]) {
162  V[D-2] += (tX[p] - tX[S[i][k]])
163  * (P[S[i][k]].x[i] - P[S[i][l]].x[i]);
164 
165  tX[S[i][k]] = tX[p];
166  }
167 
168  if (S[i+1][k] == 1) l = k;
169  k++;
170  S[i][k] = S[i][k+1];
171  S[i+1][k] = S[i+1][k+1];
172  }
173 
174  if (S[i+1][k] == 1 && tX[p] > tX[S[i][k]]) {
175  V[D-2] += (tX[p] - tX[S[i][k]])
176  * (P[p].x[i] - P[S[i][l]].x[i]);
177 
178  if (P[p].x[i] == P[S[i][k]].x[i]) {
179  tX[S[i][k]] = tX[p];
180  S[i+1][k+1] = 0;
181  }
182  }
183 
184  if (P[p].x[i] <= P[S[i][k]].x[i] && tX[p] < tX[S[i][k]]) {
185  tX[p] = tX[S[i][k]];
186  S[i+1][k] = 0;
187  } else {
188  S[i+1][k] = 1;
189  }
190 
191  S[i][k] = p;
192  }
193 }
194 
195 static sureInline(void) get2D()
196 {
197  double m;
198 
200  V[D-2] = 0;
201 
202  c[D-1] = N+1;
203  m = P[S[D-2][c[D-1]]].x[D-1];
204  while(c[D-1] > c[D-2])
205  {
206  c[D-1]--;
207  V[D-2] += (m-P[0].x[D-1])*(P[S[D-2][c[D-1]+1]].x[D-2] - P[S[D-2][c[D-1]]].x[D-2]);
208  if(P[S[D-2][c[D-1]]].x[D-1] > m)
209  m = P[S[D-2][c[D-1]]].x[D-1];
210  }
211 }
212 
213 /* public functions */
214 
215 void resetHSO()
216 {
217  i = 0;
218  while(i < D)
219  {
220  S[i][N+1] = 1;
221  c[i] = N;
222  S[i][N] = 0;
223  i++;
224  }
225  S[D-1][N] = 1;
226 }
227 
228 double HSO(point* zero, point* one, int n, int* idx, point* PS)
229 {
230  int t;
231 
232  assert(n <= N);
233 
235  i = 0;
236  V[i] = 0;
237  c[i] = N;
238  S[i][c[i]] = 0;
240  V[D-2] = 0;
241 
242  P[0] = *zero;
243  P[1] = *one;
244  P[1].x[D-1] = P[0].x[D-1];
245  tX[0] = P[0].x[D-1];
246  tX[1] = P[1].x[D-1];
247 
248  t = n;
249  while(t > 0)
250  {
251  t--;
252  p = t+2;
253  intercept(&(P[p]), one, &(PS[idx[t]]));
254  /* project(&(P[p]), to0, &one, 0, &(PS[idx[t]])); */
255  insert();
256  }
257 
258  do {
259  /* printf("Before Insert\n"); */
260  /* showS(); */
261  if(c[i] < c[i+1])
262  {
263  while(i+2 < D) /* Propagate elements down */
264  {
265  i++;
266  do{
267  p = S[i-1][c[i]];
268  insert();
269  }while(c[i-1] < c[i] && equal(&P[p], &P[S[i-1][c[i]]], i-1) );
270  }
271 
272  // get2D(); /// Calculate a 2D volume
273  }
274  else
275  {
276  i--;
277  if(i >= 0)
278  V[i] += V[i+1] * (P[S[i][c[i+1]+1]].x[i] - P[S[i][c[i+1]]].x[i]);
279  }
280  } while(i >= 0);
282  /* printf("End\n"); */
283  /* showS(); */
284 
285  return V[0];
286 }
287 /* ------------------------------------------------------ */
#define D
D is the number of dimensions.
Definition: pointStruct.h:43
double * V
A volume value for every dimension + 1.
Definition: point.h:183
double HSO(point *zero, point *one, int n, int *idx, point *PS)
Definition: HSO.c:228
void resetHSO()
Definition: HSO.c:215
#define equal(A, B, I)
Definition: point.h:75
struct point __attribute__((aligned(16))) point
All points must be aligned for SSE2.
Point is an array of coordinates, in a struct for simple and fast copy.
Definition: pointStruct.h:47
Header: copy HSO.