box.c
Go to the documentation of this file.
1 #include "box.h"
2 
3 #include "defines.h"
4 #include "error.h"
5 #include "random.h"
6 
7 #include <string.h>
8 #include <stdlib.h>
9 #include <math.h>
10 
11 
20 /*
21  * Inits an empty box in a 'dim' dimensional space
22  */
23 void InitBox(unsigned int dim,Tinterval *is,Tbox *b)
24 {
25  b->level=1; /* Default level */
26  b->n=dim;
27  if (b->n==0)
28  b->is=NULL;
29  else
30  {
31  NEW(b->is,b->n,Tinterval);
32  if (is!=NULL)
33  memcpy(b->is,is,b->n*sizeof(Tinterval));
34  else
35  {
36  unsigned int i;
37  for(i=0;i<dim;i++)
38  NewInterval(0.0,0.0,&(b->is[i]));
39  }
40  }
41 }
42 
43 void InitBoxFromPoint(unsigned int dim,double *p,Tbox *b)
44 {
45  b->level=1; /* Default level */
46  b->n=dim;
47  if (b->n==0)
48  b->is=NULL;
49  else
50  {
51  unsigned int i;
52 
53  NEW(b->is,b->n,Tinterval);
54  for(i=0;i<b->n;i++)
55  NewInterval(p[i],p[i],&(b->is[i]));
56  }
57 }
58 
59 void EnlargeBox(double lo,double uo,Tbox *b)
60 {
61  unsigned int i;
62 
63  for(i=0;i<b->n;i++)
64  EnlargeInterval(lo,uo,&(b->is[i]));
65 }
66 
67 void ExpandBox(double *p,Tbox *b)
68 {
69  unsigned int i;
70 
71  for(i=0;i<b->n;i++)
72  ExpandInterval(p[i],&(b->is[i]));
73 }
74 
75 
76 unsigned int GetBoxBufferSize(Tbox *b)
77 {
78  return(b->n*2+4);
79 }
80 
81 void Box2Buffer(unsigned int c,unsigned int n,double *buffer,Tbox *b)
82 {
83  unsigned int k,i;
84 
85  /* Set the error code (from child to scheduler) */
86  switch(c)
87  {
88  case EMPTY_BOX:
89  buffer[0]=-1.0; /*and in the other direction, the first double is also used to send output messages to the scheduler*/
90  break;
91 
92  case ERROR_IN_PROCESS:
93  buffer[0]=-2.0;
94  break;
95 
97  buffer[0]=1.0;
98  break;
99 
100  case REDUCED_BOX:
101  buffer[0]=0.0;
102  break;
103 
104  default:
105  Error("Unknown reduceBox output in Box2Buffer");
106  break;
107  }
108 
109  /* Set 'n' (this is used to send info from scheduler to childs and back)*/
110  buffer[1]=(double)n;
111 
112  buffer[2]=(double)b->level;
113  buffer[3]=(double)b->n;
114  k=4;
115  for(i=0;i<b->n;i++)
116  {
117  buffer[k++]=LowerLimit(&(b->is[i]));
118  buffer[k++]=UpperLimit(&(b->is[i]));
119  }
120 }
121 
122 void Buffer2Box(unsigned int *c,unsigned int *n,double *buffer,Tbox *b)
123 {
124  unsigned int i,k;
125 
126  if (buffer[0]<-1.5)
127  *c=ERROR_IN_PROCESS;
128  else
129  {
130  if (buffer[0]<-0.5)
131  *c=EMPTY_BOX;
132  else
133  {
134  if (buffer[0]>0.5)
136  else
137  *c=REDUCED_BOX;
138  }
139  }
140 
141  *n=(unsigned int)(buffer[1]);
142 
143  b->level=(unsigned int)(buffer[2]);
144 
145  if ((unsigned int)(buffer[3])!=b->n)
146  Error("Box and buffer have different size");
147 
148  k=4;
149  for(i=0;i<b->n;i++)
150  {
151  NewInterval(buffer[k],buffer[k+1],&(b->is[i]));
152  k+=2;
153  }
154 }
155 
156 /*
157  * Copies b_in into b_out
158  * b_out is supposed initiallized
159  */
160 void CopyBox(void *b_out,void *b_in)
161 {
162  ((Tbox *)b_out)->n=((Tbox *)b_in)->n;
163  ((Tbox *)b_out)->level=((Tbox *)b_in)->level;
164  NEW(((Tbox *)b_out)->is,((Tbox *)b_out)->n,Tinterval);
165  if (((Tbox *)b_out)->n==0)
166  ((Tbox *)b_out)->is=NULL;
167  else
168  memcpy(((Tbox *)b_out)->is,((Tbox *)b_in)->is,((Tbox *)b_out)->n*sizeof(Tinterval));
169 }
170 
171 void MergeBoxes(Tbox *b1,Tbox *b2,Tbox *bout)
172 {
173  if (bout==b1)
174  {
175  MEM_EXPAND(b1->is,b1->n+b2->n,Tinterval);
176  memcpy(&(b1->is[b1->n]),b2->is,b2->n*sizeof(Tinterval));
177  b1->n+=b2->n;
178  }
179  else
180  {
181  if (bout==b2)
182  {
183  Tbox baux;
184 
185  CopyBox(&baux,b2);
186 
187  b2->n+=b1->n;
188  MEM_EXPAND(b2->is,b2->n,Tinterval);
189  memcpy(b2->is,b1->is,b1->n*sizeof(Tinterval));
190  memcpy(&(b2->is[b1->n]),baux.is,baux.n*sizeof(Tinterval));
191 
192  DeleteBox(&baux);
193  }
194  else
195  {
196  bout->n=b1->n+b2->n;
197  bout->level=b1->level;
198  NEW(bout->is,bout->n,Tinterval);
199  memcpy(bout->is,b1->is,b1->n*sizeof(Tinterval));
200  memcpy(&(bout->is[b1->n]),b2->is,b2->n*sizeof(Tinterval));
201  }
202  }
203 
204 }
205 
206 /*
207  * Copies b_in into b_out for some selected variables
208  * b_out is supposed initiallized
209  */
210 void CopyBoxSubset(boolean *used,void *b_out,void *b_in)
211 {
212  unsigned int i,n,k;
213 
214  if (used==NULL)
215  n=((Tbox *)b_in)->n;
216  else
217  {
218  n=0;
219  for(i=0;i<((Tbox *)b_in)->n;i++)
220  if (used[i]) n++;
221  }
222 
223 
224  ((Tbox *)b_out)->n=n;
225  ((Tbox *)b_out)->level=((Tbox *)b_in)->level;
226  NEW(((Tbox *)b_out)->is,n,Tinterval);
227  k=0;
228  for (i=0;i<((Tbox *)b_in)->n;i++)
229  {
230  if ((used==NULL)||(used[i]))
231  {
232  CopyInterval(&(((Tbox *)b_out)->is[k]),&(((Tbox *)b_in)->is[i]));
233  k++;
234  }
235  }
236 }
237 
238 void SetBoxSubset(boolean *used,Tbox *bset,Tbox *b)
239 {
240  unsigned int i,k;
241 
242  k=0;
243  for(i=0;i<b->n;i++)
244  {
245  if ((used==NULL)||(used[i]))
246  {
247  CopyInterval(&(b->is[i]),&(bset->is[k]));
248  k++;
249  }
250  }
251 }
252 
254 {
255  if (b->n>0)
256  memcpy(b->is,is,b->n*sizeof(Tinterval));
257 }
258 
259 void SetBoxInterval(unsigned int n,Tinterval *is,Tbox *b)
260 {
261  if (n<b->n)
262  CopyInterval(&(b->is[n]),is);
263  else
264  Error("Index out of range in SetBoxInterval");
265 }
266 
267 /*
268  * Returns a pointer to the interval number 'n' of box 'b'
269  */
270 Tinterval *GetBoxInterval(unsigned int n, /*number of the interval to be obtained*/
271  Tbox *b /*Box*/
272  )
273 {
274  if (n<b->n)
275  return(&(b->is[n]));
276  else
277  Error("Index out of range in GetBoxInterval");
278  return(NULL);
279 }
280 
281 /*
282  * Returns a pointer to the intervals stored in the box
283 */
285 {
286  return(b->is);
287 }
288 
289 /*
290  * bout will be the intersection of b1 and b2. If the boxes do not
291  * intersect we return FALSE. We assumbe bout to be properly initialized
292  */
293 boolean BoxesIntersection(boolean *used,Tbox *b1,Tbox *b2,Tbox *bout)
294 {
295  unsigned int i;
296  boolean boxes_intersect=TRUE;
297 
298  if (b1->n!=b2->n)
299  Error("Input boxes with different size in BoxIntersection");
300 
301  for(i=0;((boxes_intersect)&&(i<b1->n));i++)
302  {
303  if ((used==NULL)||(used[i]))
304  boxes_intersect=Intersection(&(b1->is[i]),&(b2->is[i]),&(bout->is[i]));
305  }
306 
307  return(boxes_intersect);
308 }
309 
310 /*
311  * Returns a box that fully includes b_out and b.
312  * Like in BoxesIntersection, we assume b_out to be properly initilized
313  */
314 void BoxUnion(boolean *used,Tbox *b1,Tbox *b2,Tbox *b_out)
315 {
316  unsigned int i;
317 
318  if (b1->n!=b2->n)
319  Error("Input boxes with different size in BoxUnion");
320 
321  for(i=0;i<b1->n;i++)
322  {
323  if ((used==NULL)||(used[i]))
324  Union(&(b1->is[i]),&(b2->is[i]),&(b_out->is[i]));
325  }
326 }
327 
328 
329 /*
330  * Returns TRUE if point v is in box b
331  */
332 boolean PointInBox(boolean *used,unsigned int n,double *v,double tol,Tbox *b)
333 {
334  unsigned int i;
335  boolean in;
336 
337  if (n!=b->n)
338  Error("Point and box of different dimensionality in PointInBox");
339 
340  in=TRUE;
341  for(i=0;((in)&&(i<n));i++)
342  {
343  if ((used==NULL)||(used[i]))
344  in=IsInside(v[i],tol,&(b->is[i]));
345  }
346 
347  return(in);
348 }
349 
350 boolean PointInBoxTopology(boolean *used,boolean update,
351  unsigned int n,double *v,double tol,unsigned int *tp,Tbox *b)
352 {
353  unsigned int i;
354  boolean in;
355  boolean c;
356  double *nv;
357  double l,u,a,r;
358 
359  if (n!=b->n)
360  Error("Point and box of different dimensionality in PointInBox");
361 
362  in=TRUE;
363 
364  c=FALSE;
365  NEW(nv,n,double);
366 
367  for(i=0;((in)&&(i<n));i++)
368  {
369  nv[i]=v[i];
370  if ((used==NULL)||(used[i]))
371  {
372 
373  l=LowerLimit(&(b->is[i]));
374  u=UpperLimit(&(b->is[i]));
375  r=u-l;
376 
377  if ((tp==NULL)||(tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
378  /* topology real, null range, or range larger than 2pi */
379  in=IsInside(v[i],tol,&(b->is[i]));
380  else
381  {
382  /* range size not larger than 2*pi */
383  if (r<(M_2PI-ANGLE_ACCURACY))
384  {
385  /* range size lower than 2*pi */
386  PI2PI(l);
387  PI2PI(u);
388  }
389  else
390  {
391  /* range size 2*pi */
392  l=-M_PI;
393  u=+M_PI;
394  }
395 
396  a=v[i];
397  PI2PI(a);
398  if (v[i]!=a)
399  {
400  nv[i]=a;
401  c=TRUE;
402  }
403 
404  if (u<l)
405  in=((a<=(u+tol))||((l-tol)<=a));
406  else
407  in=(((l-tol)<=a)&&(a<=(u+tol)));
408  }
409  }
410  }
411 
412  if ((update)&&(c))
413  //if ((update)&&(in)&&(c))
414  memcpy(v,nv,sizeof(double)*n);
415 
416  free(nv);
417 
418  return(in);
419 }
420 
421 unsigned int OutOfBoxTopology(boolean *used,unsigned int n,double *v,
422  unsigned int *tp,signed int *s,Tbox *b)
423 {
424  unsigned int i;
425  double l,u,c,d1,d2,r;
426 
427  *s=0;
428  i=0;
429  while((i<n)&&((*s)==0))
430  {
431  if ((used==NULL)||(used[i]))
432  {
433  l=LowerLimit(&(b->is[i]));
434  u=UpperLimit(&(b->is[i]));
435  r=u-l;
436  c=v[i];
437 
438  if ((tp==NULL)||(tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
439  {
440  /* topology real, null range, or range >2pi */
441 
442  if (c<l) *s=-1;
443  if (c>u) *s=+1;
444  }
445  else
446  {
447  /* range size not larger than 2*pi */
448  if (r<=(M_2PI-ANGLE_ACCURACY))
449  {
450  /* range size lower than 2*pi */
451  PI2PI(l);
452  PI2PI(u);
453  }
454  else
455  {
456  /* range equal to 2*pi */
457  l=-M_PI;
458  u=+M_PI;
459  }
460  PI2PI(c);
461 
462  if (u<l)
463  {
464  if ((u<c)&&(c<l))
465  {
466  d1=c-u;
467  d2=l-c;
468  if (d1<d2)
469  *s=+1;
470  else
471  *s=-1;
472  }
473  }
474  else
475  {
476  /* l<u */
477  if (c<l)
478  {
479  d1=l-c;
480  if (d1>M_PI) d1=M_2PI-d1;
481  d2=u-c;
482  if (d2>M_PI) d2=M_2PI-d2;
483 
484  if (d1<d2)
485  *s=-1;
486  else
487  *s=+1;
488  }
489  else
490  {
491  if (c>u)
492  {
493  d1=c-l;
494  if (d1>M_PI) d1=M_2PI-d1;
495  d2=c-u;
496  if (d2>M_PI) d2=M_2PI-d2;
497 
498  if (d1<d2)
499  *s=-1;
500  else
501  *s=+1;
502  }
503  }
504  }
505  }
506  }
507  if ((*s)==0)
508  i++;
509  }
510 
511  if ((*s)==0)
512  return(NO_UINT);
513  else
514  return(i);
515 }
516 
517 /*
518  'used' has as many elements as ranges in 'b' but 'v' only
519  has as many values as TRUE elements in 'used'
520 */
521 boolean PointInSubBox(boolean *used,Tvector *v,double tol,Tbox *b)
522 {
523  unsigned int i,k;
524  boolean in;
525 
526  in=TRUE;
527  k=0;
528  for(i=0;((in)&&(i<b->n));i++)
529  {
530  if ((used==NULL)||(used[i]))
531  {
532  in=IsInside(*(double *)GetVectorElement(k,v),tol,&(b->is[i]));
533  k++;
534  }
535  }
536 
537  return(in);
538 }
539 
540 /* Computes the distance of a point to the center of a sub-box.
541  The ranges defining the sub-box are defined by "used" */
542 double DistanceToSubBoxCenter(boolean *used,Tvector *v,Tbox *b)
543 {
544  unsigned int i,k;
545  double d,d1;
546 
547  d=0.0;
548  k=0;
549  for(i=0;i<b->n;i++)
550  {
551  if ((used==NULL)||(used[i]))
552  {
553  d1=(*(double *)GetVectorElement(k,v))-IntervalCenter(&(b->is[i]));
554  d+=d1*d1;
555  k++;
556  }
557  }
558 
559  return(sqrt(d));
560 }
561 
562 /*
563  * Returns TRUE if the box is basically a point, i.e., if all
564  * intervals are smaller than 'epsilon'
565  */
566 boolean IsPunctualBox(boolean *used,double epsilon,Tbox *b)
567 {
568  unsigned int i;
569  boolean point;
570 
571  i=0;
572  point=TRUE;
573  while((i<b->n)&&(point))
574  {
575  if ((used==NULL)||(used[i]))
576  point=(IntervalSize(&(b->is[i]))<=epsilon);
577  i++;
578  }
579 
580  return(point);
581 }
582 
583 /*
584  * Returns TRUE if the b1 is fully included in b2
585  */
586 boolean BoxInclusion(boolean *used,Tbox *b1,Tbox *b2)
587 {
588  unsigned int i;
589  boolean included;
590 
591  i=0;
592  included=(b1->n==b2->n);
593 
594  while((i<b1->n)&&(included))
595  {
596  if ((used==NULL)||(used[i]))
597  included=IntervalInclusion(&(b1->is[i]),&(b2->is[i]));
598  i++;
599  }
600 
601  return(included);
602 }
603 
604 /*
605  * Returns the size of box 'b'.
606  */
607 double GetBoxSize(boolean *used,Tbox *b) /*box to be measured*/
608 {
609  if (b->n==0)
610  return(0);
611  else
612  return(IntervalSize(&(b->is[GetBoxMaxDim(used,b)])));
613 }
614 
616 {
617  unsigned int i,n,k;
618  double s,smax;
619 
620  smax=0.0;
621  n=VariableSetSize(vars);
622  for(i=0;i<n;i++)
623  {
624  k=GetVariableN(i,vars);
625  s=IntervalSize(&(b->is[k]));
626  if (s>smax)
627  smax=s;
628  }
629 
630  return(smax);
631 }
632 
634 {
635  unsigned int i,n,k;
636  double s,smin;
637 
638  smin=0.0;
639  n=VariableSetSize(vars);
640  for(i=0;i<n;i++)
641  {
642  k=GetVariableN(i,vars);
643  s=IntervalSize(&(b->is[k]));
644  if ((i==0)||(s<smin))
645  smin=s;
646  }
647 
648  return(smin);
649 }
650 
651 /*
652  * Returns the length of the diagonal of box 'b'.
653  */
654 double GetBoxDiagonal(boolean *used,Tbox *b)
655 {
656  unsigned int i;
657  double d,d1;
658 
659  d=0.0;
660  for(i=0;i<b->n;i++)
661  {
662  if ((used==NULL)||(used[i]))
663  {
664  d1=IntervalSize(&(b->is[i]));
665  d=d+(d1*d1);
666  }
667  }
668 
669  return(sqrt(d));
670 }
671 
672 /*
673  * Returns the level (or depth) of a given box. The level corresponds
674  * to the depth in the search three at which the box is stored
675 */
676 unsigned int GetBoxLevel(Tbox *b)
677 {
678  return(b->level);
679 }
680 
681 
682 void RandomPointInBox(boolean *used,double *c,Tbox *b)
683 {
684  unsigned int i,k;
685 
686  k=0;
687  for(i=0;i<b->n;i++)
688  {
689  if ((used==NULL)||(used[i]))
690  {
691  c[k]=randomInInterval(&(b->is[i]));
692  k++;
693  }
694  }
695 }
696 
697 void GetBoxCenter(boolean *used,double *c,Tbox *b)
698 {
699  unsigned int i,k;
700 
701  k=0;
702  for(i=0;i<b->n;i++)
703  {
704  if ((used==NULL)||(used[i]))
705  {
706  c[k]=IntervalCenter(&(b->is[i]));
707  k++;
708  }
709  }
710 }
711 
712 /*
713  * Returns the distance between the center of two boxes
714  */
715 double GetBoxCenterDistance(boolean *used,Tbox *b1,Tbox *b2)
716 {
717  double d,c1,c2,c;
718  unsigned int i;
719 
720  if (b1->n!=b2->n)
721  Error("Can not compute distance between different size boxes");
722 
723  d=0;
724  for(i=0;i<b1->n;i++)
725  {
726  if ((used==NULL)||(used[i]))
727  {
728  c1=IntervalCenter(&(b1->is[i]));
729  c2=IntervalCenter(&(b2->is[i]));
730  c=c1-c2;
731  d+=(c*c);
732  }
733  }
734 
735  return(sqrt(d));
736 }
737 
738 double SquaredDistancePointToBox(double t,double *p,Tbox *b)
739 {
740  unsigned int i;
741  double d,v;
742 
743  d=0.0;
744  for(i=0;((i<b->n)&&(d<=t));i++)
745  {
746  v=DistanceToInterval(p[i],&(b->is[i]));
747  d+=v*v;
748  }
749 
750  return(d);
751 }
752 
753 double DistancePointToBox(double *p,Tbox *b)
754 {
755  return(sqrt(SquaredDistancePointToBox(INF,p,b)));
756 }
757 
758 double SquaredDistanceToBoxDimensionTopology(unsigned int dim,double p,unsigned int *tp,Tbox *b)
759 {
760  double l,u,d,c,d1,d2,r;
761 
762  l=LowerLimit(&(b->is[dim]));
763  u=UpperLimit(&(b->is[dim]));
764  r=u-l;
765  d=0.0;
766  if ((tp==NULL)||(tp[dim]==TOPOLOGY_R)||(l==u)||(r>(M_2PI+ANGLE_ACCURACY)))
767  {
768  /* topology real, null interval, or range size larger than 2pi */
769  /* This is DistanceToInterval but inlined for efficiency */
770  if (p<l)
771  d=l-p;
772  else
773  {
774  if (p>u)
775  d=p-u;
776  }
777  }
778  else
779  {
780  /* range size not larger than 2*pi */
781  if (r<=(M_2PI-ANGLE_ACCURACY))
782  {
783  /* range size lower than 2*pi */
784  PI2PI(l);
785  PI2PI(u);
786  }
787  else
788  {
789  /* range equal to 2*pi */
790  l=-M_PI;
791  u=+M_PI;
792  }
793  c=p;
794  PI2PI(c);
795 
796  if (u<l)
797  {
798  if ((u<=c)&&(c<=l))
799  {
800  d1=c-u;
801  d2=l-c;
802  d=(d1<d2?d1:d2);
803  }
804  }
805  else
806  {
807  /* l<u */
808  if (c<l)
809  {
810  d1=l-c;
811  if (d1>M_PI) d1=M_2PI-d1;
812  d2=u-c;
813  if (d2>M_PI) d2=M_2PI-d2;
814  d=(d1<d2?d1:d2);
815  }
816  else
817  {
818  if (c>u)
819  {
820  d1=c-l;
821  if (d1>M_PI) d1=M_2PI-d1;
822  d2=c-u;
823  if (d2>M_PI) d2=M_2PI-d2;
824  d=(d1<d2?d1:d2);
825  }
826  }
827  }
828  }
829  return(d*d);
830 }
831 
832 
833 double SquaredDistancePointToBoxTopology(double t2,double *p,unsigned int *tp,Tbox *b)
834 {
835  unsigned int i;
836  double l,u,d,v,c,d1,d2,r;
837 
838  d=0.0;
839  if (tp==NULL)
840  {
841  for(i=0;((i<b->n)&&(d<t2));i++)
842  {
843  l=LowerLimit(&(b->is[i]));
844  u=UpperLimit(&(b->is[i]));
845 
846  /* This is DistanceToInterval but inlined for efficiency */
847  if (p[i]<l)
848  {
849  v=l-p[i];
850  d+=v*v;
851  }
852  else
853  {
854  if (p[i]>u)
855  {
856  v=p[i]-u;
857  d+=v*v;
858  }
859  }
860  }
861  }
862  else
863  {
864  for(i=0;((i<b->n)&&(d<t2));i++)
865  {
866  l=LowerLimit(&(b->is[i]));
867  u=UpperLimit(&(b->is[i]));
868  r=(u-l);
869 
870  if ((tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
871  {
872  /* topology real, null range, or range size > 2pi */
873  /* This is DistanceToInterval but inlined for efficiency */
874  if (p[i]<l)
875  {
876  v=l-p[i];
877  d+=v*v;
878  }
879  else
880  {
881  if (p[i]>u)
882  {
883  v=p[i]-u;
884  d+=v*v;
885  }
886  }
887  }
888  else
889  {
890  /* range size not larger than 2*pi */
891  if (r<=(M_2PI-ANGLE_ACCURACY))
892  {
893  /* range size lower than 2*pi */
894  PI2PI(l);
895  PI2PI(u);
896  }
897  else
898  {
899  /* range equal to 2*pi */
900  l=-M_PI;
901  u=+M_PI;
902  }
903  c=p[i];
904  PI2PI(c);
905 
906  if (u<l)
907  {
908  if ((u<=c)&&(c<=l))
909  {
910  d1=c-u;
911  d2=l-c;
912  d=(d1<d2?d1:d2);
913  }
914  }
915  else
916  {
917  /*l<u*/
918  if (c<l)
919  {
920  d1=l-c;
921  if (d1>M_PI) d1=M_2PI-d1;
922  d2=u-c;
923  if (d2>M_PI) d2=M_2PI-d2;
924  v=(d1<d2?d1:d2);
925  d+=v*v;
926  }
927  else
928  {
929  if (c>u)
930  {
931  d1=c-l;
932  if (d1>M_PI) d1=M_2PI-d1;
933  d2=c-u;
934  if (d2>M_PI) d2=M_2PI-d2;
935  v=(d1<d2?d1:d2);
936  d+=v*v;
937  }
938  }
939  }
940  }
941  }
942  }
943 
944  return(d);
945 }
946 
947 double DistancePointToBoxTopology(double *p,unsigned int *tp,Tbox *b)
948 {
949  return(sqrt(SquaredDistancePointToBoxTopology(INF,p,tp,b)));
950 }
951 
952 
953 /*
954  * Returns the normalized volume of a box
955  */
956 double GetBoxVolume(boolean *used,Tbox *b)
957 {
958  double volume;
959  unsigned int i;
960 
961  volume=1.0;
962  for(i=0;i<b->n;i++)
963  {
964  if ((used==NULL)||(used[i]))
965  volume*=(IntervalSize(&(b->is[i])));
966  }
967 
968  if (b->n==0)
969  return(0);
970  else
971  return(volume);
972 }
973 
974 double GetBoxSumSide(boolean *used,Tbox *b)
975 {
976  double ss;
977  unsigned int i;
978 
979  ss=0.0;
980  for(i=0;i<b->n;i++)
981  {
982  if ((used==NULL)||(used[i]))
983  ss+=(IntervalSize(&(b->is[i])));
984  }
985 
986  if (b->n==0)
987  return(0);
988  else
989  return(ss);
990 }
991 
992 unsigned int GetBoxNIntervals(Tbox *b)
993 {
994  return(b->n);
995 }
996 
997 /*
998  * Returns the dimension along which the box has its maximal size
999  */
1000 unsigned int GetBoxMaxDim(boolean *used,Tbox *b)
1001 {
1002  unsigned int i;
1003  unsigned int i_max;
1004  double s;
1005  double s_max;
1006 
1007  i_max=0;
1008  s_max=0.0;
1009  for(i=0;i<b->n;i++)
1010  {
1011  if ((used==NULL)||(used[i]))
1012  {
1013  s=IntervalSize(&(b->is[i]));
1014  if (s>s_max)
1015  {
1016  s_max=s;
1017  i_max=i;
1018  }
1019  }
1020  }
1021  if (b->n==0)
1022  return(NO_UINT);
1023  else
1024  return(i_max);
1025 }
1026 
1027 /*
1028  * Returns a dimension along which the box has to be splitted
1029  */
1030 unsigned int GetBoxSplitDim(boolean *used,Tbox *b)
1031 {
1032 
1033  return(GetBoxMaxDim(used,b));
1034 }
1035 
1036 /*
1037  * Produces two symetrical boxes from 'b' ('b1' and 'b2') that result from
1038  * spliting 'b' along th 'n' dimension.
1039  */
1040 void SplitBox(unsigned int n, /*dimension along which the box is splited*/
1041  double r, /*r in [0,1] where to split*/
1042  Tbox *b1, /*first resulting box*/
1043  Tbox *b2, /*second resulting box*/
1044  Tbox *b /*original box*/
1045  )
1046 {
1047  double lp,up,cp;
1048 
1049  if ((r>1.0)||(r<0.0))
1050  Error("Wrong size to split a box");
1051  if (n<b->n)
1052  {
1053  /*b1,b2 created here*/
1054 
1055  #if (_DEBUG>6)
1056  printf("Splitting box along dimension %u\n",n);
1057  #endif
1058 
1059  b1->n=b->n;
1060  b2->n=b->n;
1061 
1062  NEW(b1->is,b1->n,Tinterval);/* Lower box */
1063  NEW(b2->is,b2->n,Tinterval);/* Upper box */
1064 
1065  memcpy(b1->is,b->is,b1->n*sizeof(Tinterval)); /*the sub-boxes are the same as the original*/
1066  memcpy(b2->is,b->is,b1->n*sizeof(Tinterval)); /*but for the split dimension*/
1067 
1068  lp=LowerLimit(&(b->is[n])); /*lower point*/
1069  up=UpperLimit(&(b->is[n])); /*upper point*/
1070  cp=PointInInterval(r,&(b->is[n])); /*point scaling in between lower and upper */
1071 
1072  NewInterval(lp,cp,&(b1->is[n]));
1073  NewInterval(cp,up,&(b2->is[n]));
1074 
1075  b1->level=b2->level=b->level+1; /* the boxes resulting from a split are of the next level of the search */
1076  }
1077  else
1078  Error("Index out of range in SplitBox");
1079 }
1080 
1081 
1082 /*
1083  * Scales a box taking into account the original ranges for the variables
1084  */
1085 void ScaleBox(double max_upper,Tbox *b)
1086 {
1087  unsigned int i;
1088 
1089  for(i=0;i<b->n;i++)
1090  IntervalScale(&(b->is[i]),max_upper,&(b->is[i]));
1091 }
1092 
1093 void AddMargin2Box(double m,Tbox *b)
1094 {
1095  unsigned int i;
1096  Tinterval *r;
1097 
1098  for(i=0;i<b->n;i++)
1099  {
1100  r=&(b->is[i]);
1101  NewInterval(LowerLimit(r)-m,UpperLimit(r)+m,r);
1102  }
1103 }
1104 
1105 boolean CmpBoxDepthFirst(void *b1,void *b2,void *userData)
1106 {
1107  return(((Tbox *)b1)->level>((Tbox *)b2)->level);
1108 }
1109 
1110 boolean CmpBoxBreadthFirst(void *b1,void *b2,void *userData)
1111 {
1112  return(((Tbox *)b1)->level<((Tbox *)b2)->level);
1113 }
1114 
1115 /*
1116  * Prints box 'b' on file 'f'
1117  */
1118 void PrintBox(FILE *f,Tbox *b)
1119 {
1120  unsigned int i;
1121 
1122  fprintf(f,"{ %u ",b->n);
1123  for(i=0;i<b->n;i++)
1124  {
1125  //fprintf(f," %u:",i);
1126  PrintInterval(f,&(b->is[i]));
1127  fprintf(f," ");
1128  }
1129 
1130  fprintf(f,"}\n");
1131 
1132 }
1133 
1134 /*
1135  * Prints box 'b' on file 'f' for some selected variables.
1136  * This is basically used when printing solutions.
1137  */
1138 void PrintBoxSubset(FILE *f,boolean *used,char **varNames,Tbox *b)
1139 {
1140  unsigned int i,n;
1141 
1142  if (used==NULL)
1143  n=b->n;
1144  else
1145  {
1146  n=0;
1147  for(i=0;i<b->n;i++)
1148  if (used[i]) n++;
1149  }
1150 
1151  fprintf(f,"{ %u ",n);
1152  for(i=0;i<b->n;i++)
1153  {
1154  if ((used==NULL)||(used[i]))
1155  {
1156  if (varNames!=NULL)
1157  {
1158  PRINT_VARIABLE_NAME(f,varNames[i]);
1159  }
1160  PrintInterval(f,&(b->is[i]));
1161  fprintf(f," ");
1162  }
1163  }
1164 
1165  fprintf(f,"}\n");
1166 }
1167 
1168 /*
1169  * Reads a box from an opened file. Returns EOF if the file finishes before
1170  * the box could be read
1171 */
1172 int ReadBox(FILE *f,Tbox *b)
1173 {
1174  int token=~EOF;
1175  Tinterval *is;
1176  double i_min,i_max;
1177  unsigned int i;
1178  unsigned int n;
1179 
1180  do token=fgetc(f); while ((token!=EOF)&&(token!='{')); /* skip everything till the beginning of the box */
1181 
1182  if (token!=EOF)
1183  {
1184  fscanf(f,"%u",&n);
1185 
1186  NEW(is,n,Tinterval);
1187 
1188  /* Check whether we have a box with some intervals or an empty box */
1189  do token=fgetc(f); while ((token!=EOF)&&(token!='[')&&(token!='}'));
1190  if (token=='}')
1191  {
1192  /* We have an empty box (the old type of box files). Skip the box and advance until the
1193  first interval of the next box (or end of file) */
1194  do token=fgetc(f); while ((token!=EOF)&&(token!='['));
1195  }
1196  i=0;
1197  while ((token!=EOF)&&(token!='}')) //while the box is not closed (and there is something in the file)
1198  {
1199  if (token=='[') //if the interval exists
1200  {
1201  //read the extremes of the interval
1202  if (fscanf(f,"%lf",&i_min)!=EOF)
1203  {
1204  do token=fgetc(f); while ((token!=EOF)&&(token!=','));
1205  if (fscanf(f,"%lf",&i_max)!=EOF)
1206  {
1207  //if there was no problem reading the extremes set up a new interval
1208  NewInterval(i_min,i_max,&(is[i++]));
1209 
1210  if (i>n)
1211  Error("Too many intervals in the box");
1212  }
1213  else
1214  token=EOF;
1215  }
1216  }
1217  //go to the begining of next interval (if it exists)
1218  do token=fgetc(f); while ((token!=EOF)&&(token!='[')&&(token!='}'));
1219 
1220  }
1221 
1222  if (i<n)
1223  Error("Too few intervals in the box");
1224 
1225  if (token!=EOF) //if the box was read correctly
1226  InitBox(n,is,b); /*and set the new ones*/
1227  free(is);
1228  }
1229 
1230  return(token);
1231 }
1232 
1233 /*Saves in binary format*/
1234 void SaveBox(FILE *f,Tbox *b)
1235 {
1236  fwrite(&(b->n),sizeof(unsigned int),1,f);
1237  fwrite(&(b->level),sizeof(unsigned int),1,f);
1238  if (b->n>0)
1239  fwrite(b->is,sizeof(Tinterval),b->n,f);
1240 }
1241 
1242 void LoadBox(FILE *f,Tbox *b)
1243 {
1244  fread(&(b->n),sizeof(unsigned int),1,f);
1245  fread(&(b->level),sizeof(unsigned int),1,f);
1246 
1247  if (b->n==0)
1248  b->is=NULL;
1249  else
1250  {
1251  NEW(b->is,b->n,Tinterval);
1252  fread(b->is,sizeof(Tinterval),b->n,f);
1253  }
1254 }
1255 
1256 /*
1257  * Deletes the internal data of a box
1258  */
1259 void DeleteBox(void *b)
1260 {
1261  free(((Tbox *)b)->is);
1262 }
double SquaredDistancePointToBox(double t, double *p, Tbox *b)
Distance from a point to a box.
Definition: box.c:738
boolean PointInBox(boolean *used, unsigned int n, double *v, double tol, Tbox *b)
Checks if a point is included in a(sub-) box.
Definition: box.c:332
void EnlargeInterval(double lo, double uo, Tinterval *i)
Symmetrically increases the size of an interval.
Definition: interval.c:206
boolean Intersection(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Computes the intersection of two intervals.
Definition: interval.c:285
double SquaredDistancePointToBoxTopology(double t2, double *p, unsigned int *tp, Tbox *b)
Squared distance from a point to a box.
Definition: box.c:833
void Box2Buffer(unsigned int c, unsigned int n, double *buffer, Tbox *b)
Converts a box into an array of doubles.
Definition: box.c:81
Tinterval * GetBoxInterval(unsigned int n, Tbox *b)
Returns a pointer to one of the intervals defining the box.
Definition: box.c:270
#define ERROR_IN_PROCESS
One of the possible results of reducing a box.
Definition: box.h:32
double DistanceToSubBoxCenter(boolean *used, Tvector *v, Tbox *b)
Computes the distance from a point to the center of a (sub-)box.
Definition: box.c:542
double DistanceToInterval(double p, Tinterval *i)
Distance to an interval.
Definition: interval.c:112
#define FALSE
FALSE.
Definition: boolean.h:30
double DistancePointToBox(double *p, Tbox *b)
Distance from a point to a box.
Definition: box.c:753
#define NEW(_var, _n, _type)
Allocates memory space.
Definition: defines.h:385
double GetBoxSize(boolean *used, Tbox *b)
Computes the size of the box.
Definition: box.c:607
void * GetVectorElement(unsigned int i, Tvector *vector)
Returns a pointer to a vector element.
Definition: vector.c:269
void SetBoxInterval(unsigned int n, Tinterval *is, Tbox *b)
Replaces a particular interval in a box.
Definition: box.c:259
void CopyBoxSubset(boolean *used, void *b_out, void *b_in)
Creates a box from a sub-set of a given box.
Definition: box.c:210
unsigned int GetBoxMaxDim(boolean *used, Tbox *b)
The dimension of the (sub-)box along which the box has maximum size.
Definition: box.c:1000
double GetBoxSumSide(boolean *used, Tbox *b)
Computes the sum of the sides of the box.
Definition: box.c:974
#define PI2PI(a)
Forces an angle go be in [-pi,pi].
Definition: defines.h:205
#define EMPTY_BOX
One of the possible results of reducing a box.
Definition: box.h:25
void EnlargeBox(double lo, double uo, Tbox *b)
Enlarges all the intervals of a box.
Definition: box.c:59
#define TRUE
TRUE.
Definition: boolean.h:21
boolean CmpBoxBreadthFirst(void *b1, void *b2, void *userData)
Determines which box to explore first in breadth first mode.
Definition: box.c:1110
void InitBox(unsigned int dim, Tinterval *is, Tbox *b)
Initializes a box.
Definition: box.c:23
void Error(const char *s)
General error function.
Definition: error.c:80
#define TOPOLOGY_R
One of the possible topologies.
Definition: defines.h:122
void SetBoxSubset(boolean *used, Tbox *bset, Tbox *b)
Changes a sub-set of ranges in a given box.
Definition: box.c:238
unsigned int n
Definition: box.h:85
unsigned int GetBoxBufferSize(Tbox *b)
Returns the size of a box when converted to an array of doubles.
Definition: box.c:76
void CopyInterval(Tinterval *i_dst, Tinterval *i_org)
Copy constructor.
Definition: interval.c:59
void AddMargin2Box(double m, Tbox *b)
Adds a margin to all dimensions of a box.
Definition: box.c:1093
void RandomPointInBox(boolean *used, double *c, Tbox *b)
Returns the a random point along the selected dimensions.
Definition: box.c:682
unsigned int GetBoxNIntervals(Tbox *b)
Box dimensionality.
Definition: box.c:992
unsigned int GetBoxLevel(Tbox *b)
Returns the box level.
Definition: box.c:676
unsigned int GetVariableN(unsigned int n, Tvariable_set *vs)
Gets a variable identifier from a variable set.
Definition: variable_set.c:447
Error and warning functions.
void ExpandInterval(double v, Tinterval *i)
Changes the interval limits to include a given point.
Definition: interval.c:236
int ReadBox(FILE *f, Tbox *b)
Reads a box from a file.
Definition: box.c:1172
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
boolean PointInSubBox(boolean *used, Tvector *v, double tol, Tbox *b)
Checks if a point is included in a (sub-)box.
Definition: box.c:521
#define ANGLE_ACCURACY
Accuracy for the rounding to +/-PI, +/-PI/2.
Definition: defines.h:352
#define PRINT_VARIABLE_NAME(f, name)
Prints a variable name into a file.
Definition: defines.h:427
Definition of the Tbox type and the associated functions.
Definitions of constants and macros used in several parts of the cuik library.
Tinterval * is
Definition: box.h:86
void SplitBox(unsigned int n, double r, Tbox *b1, Tbox *b2, Tbox *b)
Splits a box.
Definition: box.c:1040
void CopyBox(void *b_out, void *b_in)
Box copy operator.
Definition: box.c:160
A set of variable indexes with powers.
Definition: variable_set.h:131
void Buffer2Box(unsigned int *c, unsigned int *n, double *buffer, Tbox *b)
Converts a buffer of doubles into a box.
Definition: box.c:122
double DistancePointToBoxTopology(double *p, unsigned int *tp, Tbox *b)
Distance from a point to a box.
Definition: box.c:947
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
void SetBoxIntervals(Tinterval *is, Tbox *b)
Replaces the box intervals with a new set.
Definition: box.c:253
double GetBoxDiagonal(boolean *used, Tbox *b)
Computes the diagonal of a (sub-)box.
Definition: box.c:654
A generic vector.
Definition: vector.h:227
boolean BoxInclusion(boolean *used, Tbox *b1, Tbox *b2)
Checks if a (sub-)box is fully included in another box.
Definition: box.c:586
#define M_2PI
2*Pi.
Definition: defines.h:100
#define M_PI
Pi.
Definition: defines.h:83
double GetBoxCenterDistance(boolean *used, Tbox *b1, Tbox *b2)
Computes distance between the center of two (sub-)boxes.
Definition: box.c:715
unsigned int VariableSetSize(Tvariable_set *vs)
Gets the number of elements of a variable set.
Definition: variable_set.c:442
A box.
Definition: box.h:83
boolean Union(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Computes the union of two intervals.
Definition: interval.c:297
void SaveBox(FILE *f, Tbox *b)
Saves a box in binary format.
Definition: box.c:1234
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1001
void LoadBox(FILE *f, Tbox *b)
Reads a box in binary format.
Definition: box.c:1242
#define NO_UINT
Used to denote an identifier that has not been initialized.
Definition: defines.h:435
void InitBoxFromPoint(unsigned int dim, double *p, Tbox *b)
Initializes a box from a point.
Definition: box.c:43
void IntervalScale(Tinterval *i1, double e, Tinterval *i_out)
Scales an interval.
Definition: interval.c:355
double IntervalCenter(Tinterval *i)
Gets the interval center.
Definition: interval.c:129
#define REDUCED_BOX_WITH_SOLUTION
One of the possible results of reducing a box.
Definition: box.h:52
double SquaredDistanceToBoxDimensionTopology(unsigned int dim, double p, unsigned int *tp, Tbox *b)
Squared distance from a value to a given box dimension.
Definition: box.c:758
void BoxUnion(boolean *used, Tbox *b1, Tbox *b2, Tbox *b_out)
Computes the box union of two given boxes.
Definition: box.c:314
void DeleteBox(void *b)
Destructor.
Definition: box.c:1259
void PrintBoxSubset(FILE *f, boolean *used, char **varNames, Tbox *b)
Prints a (sub-)box.
Definition: box.c:1138
boolean IsInside(double p, double tol, Tinterval *i)
Checks if a value is inside an interval.
Definition: interval.c:343
double randomInInterval(Tinterval *t)
Returns a random double in the given interval.
Definition: random.c:67
Tinterval * GetBoxIntervals(Tbox *b)
Returns a pointer to the array of intervals defining the box.
Definition: box.c:284
#define MEM_EXPAND(_var, _n, _type)
Expands a previously allocated memory space.
Definition: defines.h:404
void ExpandBox(double *p, Tbox *b)
Expands a box so that it includes a given point.
Definition: box.c:67
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define INF
Infinite.
Definition: defines.h:70
#define REDUCED_BOX
One of the possible results of reducing a box.
Definition: box.h:38
void GetBoxCenter(boolean *used, double *c, Tbox *b)
Returns the box center along the selected dimensions.
Definition: box.c:697
void MergeBoxes(Tbox *b1, Tbox *b2, Tbox *bout)
Concats two boxes.
Definition: box.c:171
boolean CmpBoxDepthFirst(void *b1, void *b2, void *userData)
Determines which box to explore first in depth first mode.
Definition: box.c:1105
Definition of basic randomization functions.
void PrintBox(FILE *f, Tbox *b)
Prints a box.
Definition: box.c:1118
double PointInInterval(double r, Tinterval *i)
Gets a point inside the interval.
Definition: interval.c:164
Defines a interval.
Definition: interval.h:33
unsigned int level
Definition: box.h:84
boolean IsPunctualBox(boolean *used, double epsilon, Tbox *b)
Checks if a (sub-)box is (almost) punctual.
Definition: box.c:566
double GetBoxMaxSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the size of the box.
Definition: box.c:615
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
unsigned int GetBoxSplitDim(boolean *used, Tbox *b)
Computes the box dimension for which it is better to split the box.
Definition: box.c:1030
double GetBoxVolume(boolean *used, Tbox *b)
Computes the volume of the box.
Definition: box.c:956
double GetBoxMinSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the minimum size of the box.
Definition: box.c:633
unsigned int OutOfBoxTopology(boolean *used, unsigned int n, double *v, unsigned int *tp, signed int *s, Tbox *b)
Determines the violated box limit.
Definition: box.c:421
boolean IntervalInclusion(Tinterval *i1, Tinterval *i2)
Checks is a given interval is fully included into another interval.
Definition: interval.c:262
boolean BoxesIntersection(boolean *used, Tbox *b1, Tbox *b2, Tbox *bout)
Computes the box intersection of two given boxes.
Definition: box.c:293
void ScaleBox(double max_upper, Tbox *b)
Scales a box.
Definition: box.c:1085
boolean PointInBoxTopology(boolean *used, boolean update, unsigned int n, double *v, double tol, unsigned int *tp, Tbox *b)
Checks if a point is included in a(sub-) box.
Definition: box.c:350