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