Rocstar  1.0
Rocstar multiphysics simulation application
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
vinci_lass.c
Go to the documentation of this file.
1 /****************************************************************************************/
2 /* */
3 /* vinci_lass.c */
4 /* */
5 /****************************************************************************************/
6 /* */
7 /* Authors: Benno Bueeler (bueeler@ifor.math.ethz.ch) */
8 /* and */
9 /* Andreas Enge (enge@ifor.math.ethz.ch) */
10 /* Institute for Operations Research */
11 /* Swiss Federal Institute of Technology Zurich */
12 /* Switzerland */
13 /* */
14 /* Last Changes: October 18, 1997 */
15 /* */
16 /****************************************************************************************/
17 /* */
18 /* Lasserre's volume computation method */
19 /* */
20 /****************************************************************************************/
21 
22 #include "vinci.h"
23 
24 
25 #define MAXIMUM 1.0e150 /* define the maximum used for testing infinity */
26 #define EPSILON_LASS EPSILON /* Numbers smaller than this are treated as zero in rhs*/
27 #define EPS1 EPSILON /* Numbers smaller than this are treated as zero in coefficient */
28 #define EPS_NORM EPSILON /* EPSILON used for constraint normalization*/
29 #define LaShiftLevel 0 /* Shifting is possible if d>=LaShiftLevel */
30 #define LaShift 1 /* shift polytope to make at least d components of
31  the rhs zero if there are less than d-LaShift zeros */
32 /* #define ReverseLass */ /* perform recursion from last to first constraint;
33  if undefined the recursion starts with the first constraint */
34 #define verboseFirstLevel /* output the intermediate volume of the first level */
35 
36 
37 /******************/
38 /*global variables*/
39 /******************/
40 
41 /****************************************************************************************/
42 /* */
43 /* definitions of the global variables */
44 /* */
45 /****************************************************************************************/
46 
47 
48 /****************************************************************************************/
49 
50 int G_d;
51 int G_m;
52 
53 real **G_Hyperplanes = NULL;
56 
57 int G_Precomp = 0;
58 int G_Storage = -1;
59 int G_RandomSeed = 4;
60 
61 boolean G_OutOfMem = TRUE;
62 void *G_MemRes = NULL;
64 
65 /****************************************************************************************/
66 
68 rational *pivotrow; /* copy of pivot row */
69 T_LassInt *All_index; /* All eliminated and superfluous indices (sorted) */
70 T_LassInt *Pivot; /* All substituted variables (sorted) */
71 int **p2c; /* pivot to constraints: which variable is fixed in which constraint;
72  the variable index is given in the leading column, the constraint
73  index in the second */
74 
75 rational * planescopy; /* needed in shift_P in the lasserre-code */
76 static T_Key key, *keyfound; /* key for storing the actually considered face and */
77  /* found key when a volume could be retrieved */
78 static T_Tree *tree_volumes; /* tree for storing intermediate volumes */
79 static T_VertexSet *face;
80  /* face considered at each recursion level */
81 
82 /***************/
83 /*help routines*/
84 /***************/
85 
86 /****************************************************************************************/
87 /* memory allocation */
88 /****************************************************************************************/
89 
90 void *my_malloc (long int size)
91  /* works exactly like malloc, but keeps trace of the used memory in the statistical */
92  /* variables and eventually frees the memory reserve */
93 
94 { void *pointer;
95 
96  pointer = malloc (size);
97 
98  if (pointer == NULL)
99  if (!G_OutOfMem)
100  {
101  fprintf (stderr, "\n***** WARNING: Out of memory; freeing memory reserve\n");
102  free (G_MemRes);
103  G_OutOfMem = TRUE;
104  pointer = my_malloc (size);
105  }
106  else
107  {
108  fprintf (stderr, "\n***** ERROR: Out of memory\n");
109  exit (0);
110  }
111  else
112  {
113 
114  }
115 
116  return pointer;
117 }
118 
119 /****************************************************************************************/
120 
121 void my_free (void *pointer, long int size)
122  /* frees the memory space used by pointer and keeps track of the freed space in the */
123  /* statistical variables */
124 
125 {
126  free (pointer);
127 }
128 
129 /****************************************************************************************/
130 
131 void create_key (T_Key *key, int key_choice)
132  /* creates the dynamic parts of the key; G_d must be set correctly */
133 
134 {
135  switch (key_choice)
136  {
137  case KEY_PLANES:
138  key -> hyperplanes = create_int_vector (G_d + 1);
139  break;
140  case KEY_PLANES_VAR:
141  key -> hypervar.hyperplanes =
142  (T_LassInt *) my_malloc ((G_Storage + 2) * sizeof (T_LassInt));
143  key -> hypervar.variables =
144  (T_LassInt *) my_malloc ((G_Storage + 2) * sizeof (T_LassInt));
145  break;
146  }
147 }
148 
149 /****************************************************************************************/
150 
151 void free_key (T_Key key, int key_choice)
152  /* frees the dynamic parts of the key */
153 
154 {
155  switch (key_choice)
156  {
157  case KEY_PLANES:
158  free_int_vector (key.hyperplanes, G_d + 1);
159  break;
160  case KEY_PLANES_VAR:
161  my_free (key.hypervar.hyperplanes, (G_Storage + 2) * sizeof (T_LassInt));
162  my_free (key.hypervar.variables, (G_Storage + 2) * sizeof (T_LassInt));
163  break;
164  }
165 }
166 /****************************************************************************************/
167 
168 void add_hypervar (T_LassInt hyperplane, T_LassInt variable, T_Key *key)
169  /* adds the specified hyperplane and variable index to the variable "key" maintain- */
170  /* ing the ascending orders; if one index is G_m+1 resp. G_d+1 it is omitted. */
171  /* For the working of the procedure it is necessary that the last array entry is */
172  /* G_m + 1 resp. G_d + 1 and that there is still some space left in the arrays. */
173  /* Attention: Only use this function if you work with the planes and variables as */
174  /* key! */
175 
176 { int i, j;
177 
178  if (hyperplane != G_m+1)
179  {
180  for (i = 0; (*key).hypervar.hyperplanes [i] < hyperplane; i++);
181  if ((*key).hypervar.hyperplanes [i] != hyperplane)
182  { /* insert index */
183  for (j = G_d; j > i; j--)
184  (*key).hypervar.hyperplanes [j] = (*key).hypervar.hyperplanes [j-1];
185  (*key).hypervar.hyperplanes [i] = hyperplane;
186  }
187  }
188 
189  if (variable != G_d+1)
190  {
191  for (i = 0; (*key).hypervar.variables [i] < variable; i++);
192  if ((*key).hypervar.variables [i] != variable)
193  { /* insert index */
194  for (j = G_d; j > i; j--)
195  (*key).hypervar.variables [j] = (*key).hypervar.variables [j-1];
196  (*key).hypervar.variables [i] = variable;
197  }
198  }
199 }
200 
201 
202 /****************************************************************************************/
203 
204 void delete_hypervar (T_LassInt hyperplane, T_LassInt variable, T_Key *key)
205  /* deletes the indices from the variable key; if one index is -1 it is omitted. */
206  /* Attention: Only use this function if you work with the planes and variables as */
207  /* key! */
208 
209 { int i, j;
210 
211  if (hyperplane != G_m+1)
212  {
213  for (i = 0; i <= G_d && (*key).hypervar.hyperplanes [i] != hyperplane; i++);
214  if (i != G_d + 1)
215  { /* index found, delete it */
216  for (j = i; (*key).hypervar.hyperplanes [j] != G_m + 1; j++)
217  (*key).hypervar.hyperplanes [j] = (*key).hypervar.hyperplanes [j+1];
218  }
219  }
220 
221  if (variable != G_d+1)
222  {
223  for (i = 0; i <= G_d && (*key).hypervar.variables [i] != variable; i++);
224  if (i != G_d + 1)
225  { /* index found, delete it */
226  for (j = i; (*key).hypervar.variables [j] != G_d + 1; j++)
227  (*key).hypervar.variables [j] = (*key).hypervar.variables [j+1];
228  }
229  }
230 }
231 
232 /****************************************************************************************/
233 
234 /****************************************************************************************/
235 
237  /* reserves memory space for a vector with n entries */
238 
239 { int *v;
240 
241  v = (int *) my_malloc (n * sizeof (int));
242 
243  return v;
244 }
245 
246 /****************************************************************************************/
247 
248 void free_int_vector (int *v, int n)
249  /* frees the memory space needed by the vector v of length n */
250 
251 {
252  my_free (v, n * sizeof (int));
253 }
254 
255 /****************************************************************************************/
256 
257 
259  T_LassInt * ref_indices)
260 /* insert new index into ref_indices maintaining sorting; if indices!=NULL this index
261  is also inserted into indices. returns the original index base.
262  assumption: red counted in the original systen is not contained in ref_indices */
263 
264 { register int i;
265  T_LassInt xch, base;
266 
267  for (i=0; red>=ref_indices[i]; i++) red++; /* reduced index -> original index */
268  base=red;
269  while (ref_indices[i]<=G_m) {
270  xch=ref_indices[i];
271  ref_indices[i]=red;
272  red=xch;
273  i++;
274  };
275  ref_indices[i]=red;
276  ref_indices[i+1]=G_m+2;
277  if (indices==NULL) return base;
278  red=base;
279  for (i=0; base>indices[i]; i++);
280  while (indices[i]<=G_m) {
281  xch=indices[i];
282  indices[i]=red;
283  red=xch;
284  i++;
285  };
286  indices[i]=red;
287  indices[i+1]=G_m+2;
288  return base;
289 }
290 
291 
292 static void del_original_indices(T_LassInt *indices, T_LassInt *org_indices)
293 /* delete original indices in org_indices maintaining sorting.
294  assumption: all the indices are contained in org_indices.
295  the end of indices is marked by G_m+2 */
296 
297 { register int i, cnt;
298 
299  i=cnt=0;
300  while (org_indices[i]<=G_m) {
301  while ((org_indices[cnt+i]==indices[cnt])&&(indices[cnt]<=G_m)) cnt++;
302  org_indices[i]=org_indices[i+cnt];
303  i++;
304  }
305 }
306 
307 
308 static void del_original(T_LassInt base, T_LassInt * indices)
309 /* delete base in indices maintaining sorting.
310  assumption: base is contained in indices. */
311 
312 { int i;
313 
314  for (i=0; ((base!=indices[i])&&(indices[i]<=G_m)); i++); /* search original index */
315  if (base!=indices[i]) {
316  fprintf(stderr, "ERROR: Deletion index not found!\n");
317  exit(0);
318  };
319  for (;indices[i]<=G_m;i++) indices[i]=indices[i+1];
320 }
321 
322 
324 /* delete baserow in All_index maintaining sorting. */
325 { del_original(baserow, All_index); }
326 
327 
328 static void rm_constraint(rational* A, int *LastPlane_, int d, int rm_index)
329 /* removes the constraints given in rm_index and adjusts *LastPlane */
330 
331 { register rational *p1, *p2;
332  register int i;
333 
334  p1=A+rm_index*(d+1);
335  p2=A+(rm_index+1)*(d+1);
336  for (i=0; i<(((*LastPlane_)-rm_index)*(d+1)); i++) {
337  *p1=*p2;
338  p1++;
339  p2++;
340  };
341  (*LastPlane_)--;
342 }
343 
344 
345 static rational * compact()
346 { register int i, j;
347  register rational *po,*pc;
348 
349  if (!(pc = (rational *) my_malloc (G_m*(G_d+1)*sizeof(rational)))) {
350  fprintf (stderr, "\n***** ERROR: Out of memory in 'compact.*pc'");
351  exit(0);
352  }
353  po=pc;
354  for (i=0; i<G_m; i++) {
355  for (j=0; j<=G_d; j++,pc++) *pc= G_Hyperplanes [i][j];
356  };
357  return po;
358 }
359 
360 
361 /***************/
362 /*Core routines*/
363 /***************/
364 
365 
366 static int notInPivot(int * pivot, int col, int i)
367 { register int h;
368  for (h=0;h<col;h++)
369  if (pivot[h]==i) return FALSE;
370  return TRUE;
371 }
372 
373 
374 static void shift_P(rational *A, int LastPlane_, int d)
375 /* shift one vertex of the polytope into the origin, that
376  is, make at least d components of b equal zero */
377 
378 { register rational *p1, *p2, *p3, d1, d2, d3;
379  register int col, i, j;
380  static int *pivot = NULL;
381  /* contains the pivot row of each column */
382 
383 
384 
385  if (pivot == NULL) pivot = create_int_vector (G_d + 1);
386 
387  p1=A; /* search pivot of first column */
388  pivot[0]=0;
389  d3=fabs(d1=*p1);
390  for (i=0; i<=LastPlane_; i++) {
391  d2=fabs(*p1);
392 #if PIVOTING_LASS == 0
393  if (d2>=MIN_PIVOT_LASS) {pivot[0]=i; d1=*p1; break;};
394 #endif
395  if (d2>d3) { pivot[0]=i; d1=*p1; d3=d2; };
396  p1+=(d+1);
397  }
398  /* copy pivot row into planescopy */
399  p1=A+pivot[0]*(d+1)+1;
400  p2=planescopy+pivot[0]*(d+1)+1;
401  for (i=1,d2=1.0/d1; i<=d; i++,p1++,p2++) *p2 = (*p1)*d2;
402  /* complete first pivoting and copying */
403  p1=A+1;
404  p2=planescopy+1;
405  for (i=0; i<=LastPlane_; i++, p1++, p2++) {
406  if (i==pivot[0]) {
407  p1+=d;
408  p2+=d;
409  continue; /* pivot row already done */
410  }
411  d1=*(p1-1);
412  p3=planescopy+pivot[0]*(d+1)+1;
413  for (j=1; j<=d; j++, p1++, p2++, p3++) (*p2)=(*p1)-d1*(*p3);
414  }
415 
416  /* subsequent elimination below */
417 
418  for (col=1;col<d;col++) {
419  for (i=0;i<=LastPlane_;i++) /* search first row not already used as pivot row*/
420  if (notInPivot(pivot,col,i)) {
421  pivot[col]=i;
422  break;
423  }
424  p1=planescopy+i*(d+1)+col; /* search subsequent pivot row */
425  d3=fabs(d1=*p1);
426  for (; i<=LastPlane_; i++, p1+=(d+1))
427  if (notInPivot(pivot,col,i)) {
428  d2=fabs(*(p1));
429 #if PIVOTING_LASS == 0
430  if (d2>=MIN_PIVOT_LASS) {
431  pivot[col]=i;
432  d1=*p1;
433  break;
434  }
435 #endif
436  if (d2>d3) {
437  pivot[col]=i;
438  d1=*p1;
439  d3=d2;
440  }
441  };
442  /* update pivot row */
443  p1=planescopy+pivot[col]*(d+1)+col+1;
444  d2=1.0/d1;
445  for (j=col+1; j<=d; j++, p1++) (*p1) *= d2;
446  if (col==(d-1)) break; /* the rest is not needed in the last case */
447  /* update rest of rows */
448  p1=planescopy+col+1;
449  p2=planescopy+pivot[col]*(d+1)+col+1;
450  for (i=0; i<=LastPlane_; i++, p1+=(col+1)) {
451  if (!notInPivot(pivot,col+1,i)) {
452  p1+=d-col;
453  continue;
454  }
455  d1=*(p1-1);
456  for (j=col+1; j<=d; j++, p1++, p2++) *p1=(*p1)-d1*(*p2);
457  p2-=d-col;
458  }
459  };
460 
461  /* compute x* by backward substitution; result goes into rhs of planescopy */
462 
463  for (i=d-2; 0<=i; i--){
464  p1=planescopy+pivot[i]*(d+1)+d;
465  p2=p1-d+i+1;
466  for (j=i+1; j<d; j++, p2++)
467  *(p1)-= (*p2)*(*(planescopy+pivot[j]*(d+1)+d));
468  }
469 
470  /* compute shifted b */
471 
472  for (i=0; i<=LastPlane_; i++) {
473  p1=A+i*(d+1);
474  p2=p1+d;
475  if (notInPivot(pivot,d,i))
476  for (j=0; j<d; j++,p1++) {
477  *p2 -= (*p1)*(*(planescopy+pivot[j]*(d+1)+d));
478  }
479  else *p2=0;
480  }
481 }
482 
483 static int norm_and_clean_constraints(rational* A, int *LastPlane_, int d,
484  T_LassInt *Del_index, int Index_needed)
485 /* Other (simpler) implementation of version lasserre-v15.
486  Finally (up to the sign) identical constraints in A are detected. If they are
487  identical the back one is removed, otherwise the system is infeasible. LastPlane_
488  is reduced accordingly to the elimination process as well as insertion of the
489  corresponding original indices into Del_index if Index_needed is true. */
490 
491 { register int i, j, row = 0;
492  register rational r0, *p1, *p2;
493 
494  /* find nonzero[][] and maximal elements and normalize */
495 
496  p1=A; /* begin of first constraint */
497  while (row<=(*LastPlane_)) { /* remove zeros and normalize */
498  r0=0.0; /* norm of vector */
499  for (j=0; j<d; j++,p1++)
500  r0+=(*p1)*(*p1); /* compute euclidean norm */
501  r0=sqrt(r0);
502  if (r0<EPS_NORM) {
503  if ((*p1)<-100000*EPS1){ /* if negative rhs */
504  return 1; /* infeasible constraint */
505  }
506  rm_constraint(A, LastPlane_, d,row);
507  if (Index_needed) add_reduced_index(row, Del_index, All_index);
508  p1-=d;
509  }
510  else {
511  r0=1.0/r0;
512  p1-=d;
513  for (j=0; j<=d; j++,p1++)
514  (*p1)*=r0;
515  row++;
516  }
517  }
518 
519  /* detect identical or reverse constraints */
520 
521  for (row=0; row<(*LastPlane_); row++) {
522  i=row+1;
523  while (i<=*LastPlane_) { /* test all subsequent rows i if equal to row */
524  r0=0.0;
525  p1=A+row*(d+1);
526  p2=A+i*(d+1);
527  for (j=0;j<d;j++,p1++,p2++)
528  r0+=(*p1)*(*p2); /* cosinus of arc among those two vectors */
529  if (r0>0) {
530  /* NEW VERSION of removing constraints */
531  if (fabs(r0-1.0)<EPS_NORM) {
532  if ((*p1)>(*p2)){
533  if (Index_needed) add_reduced_index(row, Del_index, All_index);
534  rm_constraint(A, LastPlane_, d,row);
535  i=row+1;
536  }
537  else {
538  if (Index_needed) add_reduced_index(i, Del_index, All_index);
539  if (i<(*LastPlane_))
540  rm_constraint(A, LastPlane_, d,i);
541  else (*LastPlane_)--;
542  }
543  }
544  else i++;
545 
546  /* OLD VERSION :
547  if ((fabs(r0-1.0)<EPS_NORM) && (fabs((*p1)-(*p2))<EPS1)){
548  if (Index_needed) add_reduced_index(i, Del_index, All_index);
549  if (i<(*LastPlane_))
550  rm_constraint(A, LastPlane_, d,i);
551  else (*LastPlane_)--;
552  }
553  else i++;
554  */
555  }
556  else {
557  if (fabs(r0+1.0)<EPS_NORM){
558  if ((*p1)>0){
559  if ((*p2)<(EPS1-(*p1))) return 1;
560  }
561  else {
562  if ((*p1)<(EPS1-(*p2))) return 1;
563  }
564  }
565  i++;
566  }
567  }
568  }
569  return 0; /* elimination succesful */
570 }
571 
572 static rational lass(rational *A, int LastPlane_, int d)
573 /* A has exact dimension (LastPlane_+1)*(d+1). The function returns
574  the volume; an underscore is appended to LastPlane_ and d */
575 
576 { rational * redA; /* A reduced by one dimension and constraint */
577  int i, j;
578  T_LassInt baserow, basecol, col;
579  int dimdiff, row; /* dimension difference and boolean */
580  int i_balance = FALSE;
581  rational ma, mi, *volume, *realp1, *realp2;
582  int Index_needed; /* Boolean, if index operations are needed */
583  T_LassInt * Del_index; /* contains the indices of the deleted planes */
584 
585  /* test if volume is already known and return it if so */
586 
587  dimdiff = G_d-d;
588  if ((G_Storage > (dimdiff-2)) && (dimdiff >= 2)) {
589  tree_out (&tree_volumes, &i_balance, key, &volume, &keyfound, KEY_PLANES_VAR);
590  if ((*volume)>=0) { /* this volume has already been computed */
591  printf("\nNeed Scale routine!\n");
592  }
593  if (!G_OutOfMem) {
594  (*volume)=0; /* initialize */
595  dimdiff=TRUE;
596  }
597  else dimdiff=FALSE;
598  }
599  else dimdiff=FALSE;
600 
601  /* if d==1 compute the volume and give it back */
602 
603  if (d == 1) {
604  ma=-MAXIMUM;
605  mi= MAXIMUM;
606  for (i=0; i<=LastPlane_; i++,A+=2) {
607  if (*A>EPSILON_LASS) { if ((*(A+1)/ *A)<mi) mi=(*(A+1)/ *A); }
608  else if (*A<-EPSILON_LASS) { if ((*(A+1)/ *A)>ma) ma=*(A+1)/ *A; }
609  else if ((*(A+1))<-(100000*EPSILON_LASS)) return 0;
610  }
611  if ((ma<-.5*MAXIMUM)||(mi>.5*MAXIMUM)) {
612  printf("\nVolume is unbounded!\n");
613  exit(0);
614  }
615  if ((mi-ma)>EPSILON_LASS) {
616  if (dimdiff) (*volume)=mi-ma;
617  return mi-ma;
618  }
619  return 0;
620  }
621 
622  /* if d>1 apply the recursive scheme by fixing constraints. */
623 
624  Index_needed = (G_Storage>(G_d-d-1));
625  if (Index_needed){
626  if (!(Del_index = (T_LassInt *) my_malloc ((LastPlane_ + 2) * sizeof (T_LassInt)))){
627  fprintf (stderr, "\n***** ERROR/WARNING: Out of memory in 'lass'\n");
628  if (G_OutOfMem) exit(0);
629  G_OutOfMem = TRUE;
630  free(G_MemRes);
631  Del_index = (T_LassInt *) malloc ((LastPlane_ + 2) * sizeof (T_LassInt));
632  };
633  Del_index[0]=G_m+2; /* initialize: mark end */
634  }
635  ma=0; /* used to sum up the summands */
636  if (norm_and_clean_constraints(A, &LastPlane_, d, Del_index, Index_needed)!=0)
637  goto label2;
638 
639  /* if appropriate shift polytope */
640 
641  if (d>=LaShiftLevel) {
642  realp1=A+d;
643  realp2=realp1+LastPlane_*(d+1);
644  j=0;
645  while (realp1<=realp2) {
646  if (fabs(*realp1)<EPSILON_LASS) j++;
647  realp1+=d+1;
648  }
649  if (d-j>=LaShift) shift_P(A, LastPlane_, d);
650  }
651 
652 
653  redA = (rational *) my_malloc (LastPlane_* d*sizeof(rational));
654  if (redA == NULL) {
655  fprintf (stderr, "\n***** ERROR/WARNING: Out of memory in 'lass.*redA'\n");
656  if (G_OutOfMem) exit(0);
657  G_OutOfMem = TRUE;
658  free(G_MemRes);
659  redA = (rational *) malloc (LastPlane_* d*sizeof(rational));
660  }
661 #ifdef ReverseLass
662  for (row=LastPlane_; row>=0; row--) {
663 #else
664  for (row=0; row<=LastPlane_; row++) {
665 #endif
666  if (fabs(*(A+row*(d+1)+d))<EPSILON_LASS)
667  continue; /* skip this constraint if b_row == 0 */
668  if (Index_needed)
669  { baserow=add_reduced_index(row, NULL, All_index);
670  p2c[G_d-d][1] = baserow;
671  add_hypervar (baserow, G_d+1, &key);
672  }
673  memcpy(&pivotrow[0], A+row*(d+1), sizeof(rational)*(d+1));
674  col=0; /* search for pivot column */
675  for (i=0; i<d; i++) {
676 #if PIVOTING_LASS == 0
677  if (fabs(pivotrow[i])>=MIN_PIVOT_LASS) {col=i; break;};
678 #endif
679  if (fabs(pivotrow[i])>fabs(pivotrow[col])) col=i;
680  };
681  if (G_Storage>(G_d-d-1))
682  { basecol=add_reduced_index(col, NULL, Pivot);
683  p2c[G_d-d][0] = basecol;
684  add_hypervar (G_m+1, basecol, &key);
685  }
686 
687  /* copy A onto redA and at the same time perform pivoting */
688 
689  mi=1.0/pivotrow[col];
690  for (i=0; i<=d; i++) pivotrow[i]*=mi;
691  realp1=A;
692  realp2=redA;
693  for (i=0; i<=LastPlane_; i++) {
694  if (i==row) {
695  realp1+=d+1;
696  continue;
697  };
698  mi=*(A+(i*(d+1))+col);
699  for (j=0; j<=d; j++) {
700  if (j==col) {
701  realp1++;
702  continue;
703  };
704  *realp2=(*realp1)-pivotrow[j]*mi;
705  realp1++;
706  realp2++;
707  };
708  };
709  ma+= *(A+row*(d+1)+d)/(d*fabs(*(A+row*(d+1)+col)))
710  *lass(redA, LastPlane_-1, d-1);
711  if (Index_needed)
712  { rm_original_inElAll_index(baserow);
713  delete_hypervar (baserow, G_d+1, &key);
714  }
715  if (G_Storage>(G_d-d-1))
716  { del_original(basecol, Pivot);
717  delete_hypervar (G_m+1, basecol, &key);
718  }
719  /*$#ifdef verboseFirstLevel
720  if (d==G_d)
721  printf("\nVolume accumulated to iteration %i is %20.12f",row,ma );
722  #endif$*/
723  };
724  my_free (redA, LastPlane_* d * sizeof (rational));
725  label2:
726  if (Index_needed) {
727  del_original_indices(Del_index, All_index);
728  my_free (Del_index, (LastPlane_ + 2) * sizeof (T_LassInt));
729  };
730  if (dimdiff)(*volume)=ma;
731  return ma;
732 }
733 
734 /****************************************************************************************/
735 
736 #ifndef COG
737 void VOLUME_LASSERRE_FILE ( double planes2[7][4], rational *volume )
738 
739  { int i, j;
740 
741  G_d = 3;
742  G_m = 7;
743  G_Storage = 0;
744 
745  /* reserves memory space for the global variable G_Hyperplanes; G_m and G_d must be */
746  /* set correctly */
747 
748  G_Hyperplanes = (real **) my_malloc (G_m * sizeof (real *));
749 
750  for (i = 0; i < G_m; i++)
751  G_Hyperplanes [i] = (real *) my_malloc ((G_d + 1) * sizeof (real));
752  /* The last entry is needed for the right hand side. */
753 
754  /* Transfer input from Fortran to C array */
755 
756  for( i = 0; i <= G_d; i++)
757  for( j= 0; j < G_m; j++){
758  G_Hyperplanes [j][i] = planes2[j][i];
759  /* printf("\n%10.3e",planes2[j][i]); */
760  }
761 
762 /* fprintf (stderr, "\n****** Hyperplanes are: ******\n"); */
763 /* for (j = 0; j < G_m; j++) */
764 /* { fprintf (stderr, " Hyperplane [%i]: ", j); */
765 /* for (i=0; i < G_d; i++) fprintf (stderr, "%10.3lf", G_Hyperplanes [j] [i]); */
766 /* fprintf (stderr,"\n"); */
767 /* fprintf (stderr, " :%10.3lf", G_Hyperplanes [j] [G_d]); */
768 /* fprintf (stderr,"\n"); */
769 /* } */
770 
771 /* if (G_Storage > G_d - 3) */
772 /* G_Storage = G_d - 3; */
773  /* necessary to prevent memory waste because in the tree arrays of length */
774  /* G_Storage + 2 are allocated */
775 
776  pivotrow = (rational *) my_malloc ((G_d + 1) * sizeof (rational));
777  All_index = (T_LassInt *) my_malloc ((G_m + 1) * sizeof (T_LassInt));
778  Pivot = (T_LassInt *) my_malloc ((G_d + 1) * sizeof (T_LassInt));
779  p2c = (int **) my_malloc (G_d * sizeof (int *));
780  for (i=0; i<G_d; i++){
781  p2c[i] = (int *) my_malloc (2 * sizeof (int));
782  }
784  G_MemRes=malloc(G_d*G_d*G_m*sizeof(rational)); /* memory reserve; */
785 
786  A=compact();
788  tree_volumes = NULL;
789  create_key (&key, KEY_PLANES_VAR);
790  key.hypervar.hyperplanes [0] = G_m + 1;
791  key.hypervar.variables [0] = G_d + 1;
792  All_index[0]=G_m+2; /* initialization (end mark) */
793  Pivot[0]=G_m+2; /* initialization (end mark) */
794  *volume = lass (A, G_m-1, G_d);
795 
796  if (!G_OutOfMem) free (G_MemRes);
797  free_key (key, KEY_PLANES_VAR);
798 }
799 
800 void volume_lasserre_file ( double planes2[7][4], rational *volume ) {
801  VOLUME_LASSERRE_FILE( planes2, volume);
802 }
803 
804 void VOLUME_LASSERRE_FILE_( double planes2[7][4], rational *volume ) {
805  VOLUME_LASSERRE_FILE( planes2, volume);
806 }
807 
808 void volume_lasserre_file_( double planes2[7][4], rational *volume ) {
809  VOLUME_LASSERRE_FILE( planes2, volume);
810 }
811 
812 #endif
813 
814 /****************************************************************************************/
815 /* routines for storing intermediate volumes in balanced trees (avl-trees) */
816 /****************************************************************************************/
817 
818 static int compare_key (T_Key key1, T_Key key2, int key_choice)
819  /* compares key1 with key2; if key1 is smaller, -1 is returned, if key1 is bigger +1 */
820  /* and if both are equal 0. key_choice determines which component of the key is */
821  /* relevant for comparing. */
822 
823 { int i;
824  T_LassInt *p1, *p2;
825 
826  switch (key_choice)
827  {
828  case KEY_PLANES:
829  for (i=0; ; i++)
830  if (key1.hyperplanes [i] < key2.hyperplanes [i]) return -1;
831  else if (key1.hyperplanes [i] > key2.hyperplanes [i]) return 1;
832  else if (key1.hyperplanes [i] > G_m) return 0;
833  break;
834  case KEY_VERTICES:
835  if (key1.vertices.d < key2.vertices.d) return -1;
836  else if (key1.vertices.d > key2.vertices.d) return 1;
837  else /* both volumes are for the same dimension */
838  if (key1.vertices.set.lastel < key2.vertices.set.lastel) return -1;
839  else if (key1.vertices.set.lastel > key2.vertices.set.lastel) return 1;
840  else
841  { /* both sets have the same cardinality */
842  for (i=0; i <= key1.vertices.set.lastel; i++)
843  if (key1.vertices.set.loe [i] -> no < key2.vertices.set.loe [i] -> no)
844  return -1;
845  else if (key1.vertices.set.loe [i] -> no > key2.vertices.set.loe [i] -> no)
846  return 1;
847  }
848  return 0;
849  break;
850  case KEY_PLANES_VAR:
851 /*
852  for (i=0; ; i++)
853  if (key1.hypervar.hyperplanes [i] < key2.hypervar.hyperplanes [i])
854  return -1;
855  else if (key1.hypervar.hyperplanes [i] > key2.hypervar.hyperplanes [i])
856  return 1;
857  else if (key1.hypervar.hyperplanes [i] > G_m) return 0;
858 */
859  for (p1 = key1.hypervar.hyperplanes, p2 = key2.hypervar.hyperplanes;;
860  p1++, p2++)
861  if ((*p1) < (*p2)) return -1;
862  else if ((*p1) > (*p2)) return 1;
863  else if ((*p1) > G_m) return 0;
864  break;
865  }
866 }
867 
868 /****************************************************************************************/
869 
870 void tree_out (T_Tree **ppr , int *pi_balance, T_Key key, rational **volume,
871  T_Key **keyfound, int key_choice)
872  /* looks up the node corresponding to the variable "key" in the specified tree. If */
873  /* it is found the volume is returned via the variable of the same name. */
874  /* At the same time the found key is returned in "foundkey"; this is important for */
875  /* Lasserre, where only a part of the key is compared, but the whole key is needed */
876  /* later. */
877  /* Otherwise the action taken depends on the memory reserves: If G_OutOfMem is FALSE */
878  /* a new node is created and a pointer to its volume part is returned via the varia- */
879  /* ble "volume" so that the computed volume can be inserted by the calling routine. */
880  /* If there is no more memory the volume -1 is returned. */
881  /* As in the previous routine "key_choice" determines the active part of the keys. */
882 
883 { T_Tree *p1, *p2;
884  int cmp;
885 
886  /* Are we grounded? If so, add the node here and set the rebalance flag, then exit. */
887  if (!*ppr)
888  {
889  if (G_OutOfMem)
890  { /* don't allocate if out of memory */
891  *volume = &G_Minus1;
892  }
893  else
894  { (*ppr) = (T_Tree *) my_malloc (sizeof (T_Tree));
895  (*ppr) -> tree_l = NULL;
896  (*ppr) -> tree_r = NULL;
897  (*ppr) -> tree_b = 0;
898  /* copy the key into the new node */
899  create_key (&((*ppr) -> key), key_choice);
900  switch (key_choice)
901  {
902  case KEY_PLANES:
903  memcpy ((*ppr) -> key.hyperplanes, key.hyperplanes,
904  (G_d + 1) * sizeof (int));
905  break;
906  case KEY_VERTICES:
907  (*ppr) -> key.vertices.set = duplicate_set (key.vertices.set);
908  (*ppr) -> key.vertices.d = key.vertices.d;
909  break;
910  case KEY_PLANES_VAR:
911  memcpy ((*ppr) -> key.hypervar.hyperplanes, key.hypervar.hyperplanes,
912  (G_Storage + 2) * sizeof (T_LassInt));
913  memcpy ((*ppr) -> key.hypervar.variables, key.hypervar.variables,
914  (G_Storage + 2) * sizeof (T_LassInt));
915  break;
916  }
917  (*ppr) -> vol = -1; /* to recognise that element is newly created */
918  *volume = &((*ppr) -> vol);
919  *pi_balance = TRUE;
920  }
921  return;
922  }
923 
924  cmp = compare_key ((*ppr) -> key, key, key_choice);
925 
926  /* if LESS, prepare to move to the left. */
927  if (cmp < 0)
928  {
929  tree_out (&((*ppr) -> tree_l), pi_balance, key, volume, keyfound, key_choice);
930  if (*pi_balance)
931  { /* left branch has grown longer */
932  switch ((*ppr) -> tree_b)
933  {
934  case 1: /* right branch WAS longer; balance is ok now */
935  /* LESS: case 1.. balance restored implicitly */
936  (*ppr) -> tree_b = 0;
937  *pi_balance = FALSE;
938  break;
939  case 0: /* balance WAS okay; now left branch longer */
940  /* LESS: case 0.. balance bad but still ok */
941  (*ppr) -> tree_b = -1;
942  break;
943  case -1: /* left branch was already too long. rebalance */
944  p1 = (*ppr) -> tree_l;
945  if (p1 -> tree_b == -1)
946  { /* LESS: single LL */
947  (*ppr) -> tree_l = p1->tree_r;
948  p1 -> tree_r = (*ppr);
949  (*ppr) -> tree_b = 0;
950  (*ppr) = p1;
951  }
952  else
953  { /* LESS: real LR */
954  p2 = p1 -> tree_r;
955  p1 -> tree_r = p2 -> tree_l;
956  p2 -> tree_l = p1;
957  (*ppr) -> tree_l = p2 -> tree_r;
958  p2 -> tree_r = (*ppr);
959  if (p2 -> tree_b == -1)
960  (*ppr) -> tree_b = 1;
961  else (*ppr) -> tree_b = 0;
962  if (p2->tree_b == 1)
963  p1 -> tree_b = -1;
964  else p1 -> tree_b = 0;
965  (*ppr) = p2;
966  }
967  (*ppr) -> tree_b = 0;
968  *pi_balance = FALSE;
969  } /* switch */
970  } /* if */
971  } /* cmp < 0 */
972 
973  /* if MORE, prepare to move to the right. */
974  else if (cmp > 0)
975  {
976  tree_out (&((*ppr) -> tree_r), pi_balance, key, volume, keyfound, key_choice);
977  if (*pi_balance)
978  { /* right branch has grown longer */
979  switch ((*ppr) -> tree_b)
980  {
981  case -1: /* MORE: balance was off, fixed implicitly */
982  (*ppr) -> tree_b = 0;
983  *pi_balance = FALSE;
984  break;
985  case 0: /* MORE: balance was okay, now off but ok */
986  (*ppr)->tree_b = 1;
987  break;
988  case 1: /* MORE: balance was off, need to rebalance */
989  p1 = (*ppr) -> tree_r;
990  if (p1 -> tree_b == 1)
991  { /* MORE: single RR */
992  (*ppr) -> tree_r = p1 -> tree_l;
993  p1 -> tree_l = (*ppr);
994  (*ppr) -> tree_b = 0;
995  (*ppr) = p1;
996  }
997  else
998  { /* MORE: real RL */
999  p2 = p1 -> tree_l;
1000  p1 -> tree_l = p2 -> tree_r;
1001  p2 -> tree_r = p1;
1002  (*ppr) -> tree_r = p2 -> tree_l;
1003  p2 -> tree_l = (*ppr);
1004  if (p2 -> tree_b == 1)
1005  (*ppr) -> tree_b = -1;
1006  else (*ppr) -> tree_b = 0;
1007  if (p2 -> tree_b == -1)
1008  p1 -> tree_b = 1;
1009  else p1 -> tree_b = 0;
1010  (*ppr) = p2;
1011  }
1012  (*ppr) -> tree_b = 0;
1013  *pi_balance = FALSE;
1014  } /* switch */
1015  } /* if */
1016  } /* cmp > 0 */
1017 
1018  /* not less, not more: this is the same key! give volume back! */
1019  else
1020  {
1021  *pi_balance = FALSE;
1022  *volume = &((*ppr) -> vol);
1023  *keyfound = &((*ppr) -> key);
1024  }
1025 }
1026 /****************************************************************************************/
1027 
1029  /* creates a new set with the same elements as s */
1030 
1031 { T_VertexSet newset;
1032 
1033  newset.maxel = s.lastel;
1034  newset.lastel = s.lastel;
1035  newset.loe = (T_Vertex **) my_malloc ((s.lastel + 1) * sizeof (T_Vertex *));
1036  memcpy (newset.loe, s.loe, (s.lastel + 1) * sizeof (T_Vertex *));
1037  return newset;
1038 }
void my_free(void *pointer, long int size)
Definition: vinci_lass.c:121
#define FALSE
Definition: vinci.h:133
if(dy > dx)
real rational
Definition: vinci.h:189
int G_RandomSeed
Definition: vinci_lass.c:59
rational vol
Definition: vinci.h:242
static T_Key * keyfound
Definition: vinci_lass.c:76
rational * pivotrow
Definition: vinci_lass.c:68
T_Vertex ** loe
Definition: vinci.h:204
int G_Precomp
Definition: vinci_lass.c:57
struct T_Tree * tree_r
Definition: vinci.h:239
const NT & d
Definition: vinci.h:238
void delete_hypervar(T_LassInt hyperplane, T_LassInt variable, T_Key *key)
Definition: vinci_lass.c:204
float real
Definition: gridutil.h:70
double s
Definition: blastest.C:80
T_LassInt * All_index
Definition: vinci_lass.c:69
NT p1
int * create_int_vector(int n)
struct T_Key::@39 vertices
#define EPS_NORM
Definition: vinci_lass.c:28
const unsigned int key2
Definition: CImg.h:2686
#define KEY_VERTICES
Definition: vinci.h:160
double sqrt(double d)
Definition: double.h:73
static int norm_and_clean_constraints(rational *A, int *LastPlane_, int d, T_LassInt *Del_index, int Index_needed)
Definition: vinci_lass.c:483
void * my_malloc(long int size)
Definition: vinci_lass.c:90
#define EPS1
Definition: vinci_lass.c:27
#define MAXIMUM
Definition: vinci_lass.c:25
T_LassInt * Pivot
Definition: vinci_lass.c:70
static T_Tree * tree_volumes
Definition: vinci_lass.c:78
static void del_original_indices(T_LassInt *indices, T_LassInt *org_indices)
Definition: vinci_lass.c:292
void free_key(T_Key key, int key_choice)
Definition: vinci_lass.c:151
T_VertexSet * G_Incidence
Definition: vinci_lass.c:54
static void rm_constraint(rational *A, int *LastPlane_, int d, int rm_index)
Definition: vinci_lass.c:328
void tree_out(T_Tree **ppr, int *pi_balance, T_Key key, rational **volume, T_Key **keyfound, int key_choice)
Definition: vinci_lass.c:870
void free_int_vector(int *v, int n)
Definition: vinci_lass.c:248
rational G_Minus1
Definition: vinci_lass.c:63
*********************************************************************Illinois Open Source License ****University of Illinois NCSA **Open Source License University of Illinois All rights reserved ****Developed free of to any person **obtaining a copy of this software and associated documentation to deal with the Software without including without limitation the rights to and or **sell copies of the and to permit persons to whom the **Software is furnished to do subject to the following this list of conditions and the following disclaimers ****Redistributions in binary form must reproduce the above **copyright this list of conditions and the following **disclaimers in the documentation and or other materials **provided with the distribution ****Neither the names of the Center for Simulation of Advanced the University of nor the names of its **contributors may be used to endorse or promote products derived **from this Software without specific prior written permission ****THE SOFTWARE IS PROVIDED AS WITHOUT WARRANTY OF ANY **EXPRESS OR INCLUDING BUT NOT LIMITED TO THE WARRANTIES **OF FITNESS FOR A PARTICULAR PURPOSE AND **NONINFRINGEMENT IN NO EVENT SHALL THE CONTRIBUTORS OR **COPYRIGHT HOLDERS BE LIABLE FOR ANY DAMAGES OR OTHER WHETHER IN AN ACTION OF TORT OR **ARISING OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE **USE OR OTHER DEALINGS WITH THE SOFTWARE v
Definition: roccomf90.h:20
static void del_original(T_LassInt base, T_LassInt *indices)
Definition: vinci_lass.c:308
int G_m
Definition: vinci_lass.c:51
T_VertexSet duplicate_set(T_VertexSet s)
Definition: vinci_lass.c:1028
real ** G_Hyperplanes
Definition: vinci_lass.c:53
rational * A
Definition: vinci_lass.c:67
static void rm_original_inElAll_index(T_LassInt baserow)
Definition: vinci_lass.c:323
int volume(const block *b)
Definition: split.cpp:181
static rational lass(rational *A, int LastPlane_, int d)
Definition: vinci_lass.c:572
#define EPSILON_LASS
Definition: vinci_lass.c:26
void VOLUME_LASSERRE_FILE_(double planes2[7][4], rational *volume)
Definition: vinci_lass.c:804
struct T_Tree * tree_l
Definition: vinci.h:239
int maxel
Definition: vinci.h:201
blockLoc i
Definition: read.cpp:79
boolean G_OutOfMem
Definition: vinci_lass.c:61
T_VertexSet G_Vertices
Definition: vinci_lass.c:55
#define TRUE
Definition: vinci.h:134
struct T_Key::@40 hypervar
const NT & n
#define KEY_PLANES_VAR
Definition: vinci.h:161
static T_LassInt add_reduced_index(T_LassInt red, T_LassInt *indices, T_LassInt *ref_indices)
Definition: vinci_lass.c:258
void create_key(T_Key *key, int key_choice)
Definition: vinci_lass.c:131
#define MIN_PIVOT_LASS
Definition: vinci.h:73
int ** p2c
Definition: vinci_lass.c:71
static void shift_P(rational *A, int LastPlane_, int d)
Definition: vinci_lass.c:374
#define LaShiftLevel
Definition: vinci_lass.c:29
int tree_b
Definition: vinci.h:240
static T_VertexSet * face
Definition: vinci_lass.c:79
#define LaShift
Definition: vinci_lass.c:30
j indices j
Definition: Indexing.h:6
static rational * compact()
Definition: vinci_lass.c:345
void volume_lasserre_file_(double planes2[7][4], rational *volume)
Definition: vinci_lass.c:808
Definition: vinci.h:223
void VOLUME_LASSERRE_FILE(double planes2[7][4], rational *volume)
Definition: vinci_lass.c:737
int d
Definition: vinci.h:228
void add_hypervar(T_LassInt hyperplane, T_LassInt variable, T_Key *key)
Definition: vinci_lass.c:168
int G_Storage
Definition: vinci_lass.c:58
#define KEY_PLANES
Definition: vinci.h:159
static int compare_key(T_Key key1, T_Key key2, int key_choice)
Definition: vinci_lass.c:818
rational * planescopy
Definition: vinci_lass.c:75
int lastel
Definition: vinci.h:202
static int notInPivot(int *pivot, int col, int i)
Definition: vinci_lass.c:366
int G_d
Definition: vinci_lass.c:50
static T_Key key
Definition: vinci_lass.c:76
T_LassInt * variables
Definition: vinci.h:232
int * hyperplanes
Definition: vinci.h:224
T_VertexSet set
Definition: vinci.h:227
void * G_MemRes
Definition: vinci_lass.c:62
unsigned char T_LassInt
Definition: vinci.h:184
const unsigned int key1
Definition: CImg.h:2685
void volume_lasserre_file(double planes2[7][4], rational *volume)
Definition: vinci_lass.c:800