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 void Crop2Box(boolean *used,unsigned int n,double *p,Tbox *b)
329 {
330  unsigned int i;
331  double l,u;
332 
333  if (n!=b->n)
334  Error("Point and box of different dimensionality in Crop2Box");
335 
336  for(i=0;i<b->n;i++)
337  {
338  if ((used==NULL)||(used[i]))
339  {
340  l=LowerLimit(&(b->is[i]));
341  if (p[i]<l)
342  p[i]=l;
343  else
344  {
345  u=UpperLimit(&(b->is[i]));
346  if (p[i]>u)
347  p[i]=u;
348  }
349  }
350  }
351 }
352 
353 /*
354  * Returns TRUE if point v is in box b
355  */
356 boolean PointInBox(boolean *used,unsigned int n,double *v,double tol,Tbox *b)
357 {
358  unsigned int i;
359  boolean in;
360 
361  if (n!=b->n)
362  Error("Point and box of different dimensionality in PointInBox");
363 
364  in=TRUE;
365  for(i=0;((in)&&(i<n));i++)
366  {
367  if ((used==NULL)||(used[i]))
368  in=IsInside(v[i],tol,&(b->is[i]));
369  }
370 
371  return(in);
372 }
373 
374 boolean PointInBoxTopology(boolean *used,boolean update,
375  unsigned int n,double *v,double tol,unsigned int *tp,Tbox *b)
376 {
377  unsigned int i;
378  boolean in;
379  boolean c;
380  double *nv;
381  double l,u,a,r;
382 
383  if (n!=b->n)
384  Error("Point and box of different dimensionality in PointInBox");
385 
386  in=TRUE;
387 
388  c=FALSE;
389  NEW(nv,n,double);
390 
391  for(i=0;((in)&&(i<n));i++)
392  {
393  nv[i]=v[i];
394  if ((used==NULL)||(used[i]))
395  {
396 
397  l=LowerLimit(&(b->is[i]));
398  u=UpperLimit(&(b->is[i]));
399  r=u-l;
400 
401  if ((tp==NULL)||(tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
402  /* topology real, null range, or range larger than 2pi */
403  in=IsInside(v[i],tol,&(b->is[i]));
404  else
405  {
406  /* range size not larger than 2*pi */
407  if (r<(M_2PI-ANGLE_ACCURACY))
408  {
409  /* range size lower than 2*pi */
410  PI2PI(l);
411  PI2PI(u);
412  }
413  else
414  {
415  /* range size 2*pi */
416  l=-M_PI;
417  u=+M_PI;
418  }
419 
420  a=v[i];
421  PI2PI(a);
422  if (v[i]!=a)
423  {
424  nv[i]=a;
425  c=TRUE;
426  }
427 
428  if (u<l)
429  in=((a<=(u+tol))||((l-tol)<=a));
430  else
431  in=(((l-tol)<=a)&&(a<=(u+tol)));
432  }
433  }
434  }
435 
436  if ((update)&&(c))
437  //if ((update)&&(in)&&(c))
438  memcpy(v,nv,sizeof(double)*n);
439 
440  free(nv);
441 
442  return(in);
443 }
444 
445 unsigned int OutOfBoxTopology(boolean *used,unsigned int n,double *v,
446  unsigned int *tp,signed int *s,Tbox *b)
447 {
448  unsigned int i;
449  double l,u,c,d1,d2,r;
450 
451  *s=0;
452  i=0;
453  while((i<n)&&((*s)==0))
454  {
455  if ((used==NULL)||(used[i]))
456  {
457  l=LowerLimit(&(b->is[i]));
458  u=UpperLimit(&(b->is[i]));
459  r=u-l;
460  c=v[i];
461 
462  if ((tp==NULL)||(tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
463  {
464  /* topology real, null range, or range >2pi */
465 
466  if (c<l) *s=-1;
467  if (c>u) *s=+1;
468  }
469  else
470  {
471  /* range size not larger than 2*pi */
472  if (r<=(M_2PI-ANGLE_ACCURACY))
473  {
474  /* range size lower than 2*pi */
475  PI2PI(l);
476  PI2PI(u);
477  }
478  else
479  {
480  /* range equal to 2*pi */
481  l=-M_PI;
482  u=+M_PI;
483  }
484  PI2PI(c);
485 
486  if (u<l)
487  {
488  if ((u<c)&&(c<l))
489  {
490  d1=c-u;
491  d2=l-c;
492  if (d1<d2)
493  *s=+1;
494  else
495  *s=-1;
496  }
497  }
498  else
499  {
500  /* l<u */
501  if (c<l)
502  {
503  d1=l-c;
504  if (d1>M_PI) d1=M_2PI-d1;
505  d2=u-c;
506  if (d2>M_PI) d2=M_2PI-d2;
507 
508  if (d1<d2)
509  *s=-1;
510  else
511  *s=+1;
512  }
513  else
514  {
515  if (c>u)
516  {
517  d1=c-l;
518  if (d1>M_PI) d1=M_2PI-d1;
519  d2=c-u;
520  if (d2>M_PI) d2=M_2PI-d2;
521 
522  if (d1<d2)
523  *s=-1;
524  else
525  *s=+1;
526  }
527  }
528  }
529  }
530  }
531  if ((*s)==0)
532  i++;
533  }
534 
535  if ((*s)==0)
536  return(NO_UINT);
537  else
538  return(i);
539 }
540 
541 /*
542  'used' has as many elements as ranges in 'b' but 'v' only
543  has as many values as TRUE elements in 'used'
544 */
545 boolean PointInSubBox(boolean *used,Tvector *v,double tol,Tbox *b)
546 {
547  unsigned int i,k;
548  boolean in;
549 
550  in=TRUE;
551  k=0;
552  for(i=0;((in)&&(i<b->n));i++)
553  {
554  if ((used==NULL)||(used[i]))
555  {
556  in=IsInside(*(double *)GetVectorElement(k,v),tol,&(b->is[i]));
557  k++;
558  }
559  }
560 
561  return(in);
562 }
563 
564 /* Computes the distance of a point to the center of a sub-box.
565  The ranges defining the sub-box are defined by "used" */
566 double DistanceToSubBoxCenter(boolean *used,Tvector *v,Tbox *b)
567 {
568  unsigned int i,k;
569  double d,d1;
570 
571  d=0.0;
572  k=0;
573  for(i=0;i<b->n;i++)
574  {
575  if ((used==NULL)||(used[i]))
576  {
577  d1=(*(double *)GetVectorElement(k,v))-IntervalCenter(&(b->is[i]));
578  d+=d1*d1;
579  k++;
580  }
581  }
582 
583  return(sqrt(d));
584 }
585 
586 /*
587  * Returns TRUE if the box is basically a point, i.e., if all
588  * intervals are smaller than 'epsilon'
589  */
590 boolean IsPunctualBox(boolean *used,double epsilon,Tbox *b)
591 {
592  unsigned int i;
593  boolean point;
594 
595  i=0;
596  point=TRUE;
597  while((i<b->n)&&(point))
598  {
599  if ((used==NULL)||(used[i]))
600  point=(IntervalSize(&(b->is[i]))<=epsilon);
601  i++;
602  }
603 
604  return(point);
605 }
606 
607 /*
608  * Returns TRUE if the b1 is fully included in b2
609  */
610 boolean BoxInclusion(boolean *used,Tbox *b1,Tbox *b2)
611 {
612  unsigned int i;
613  boolean included;
614 
615  i=0;
616  included=(b1->n==b2->n);
617 
618  while((i<b1->n)&&(included))
619  {
620  if ((used==NULL)||(used[i]))
621  included=IntervalInclusion(&(b1->is[i]),&(b2->is[i]));
622  i++;
623  }
624 
625  return(included);
626 }
627 
628 /*
629  * Returns the size of box 'b'.
630  */
631 double GetBoxSize(boolean *used,Tbox *b) /*box to be measured*/
632 {
633  if (b->n==0)
634  return(0);
635  else
636  return(IntervalSize(&(b->is[GetBoxMaxDim(used,b)])));
637 }
638 
640 {
641  unsigned int i,n,k;
642  double s,smax;
643 
644  smax=0.0;
645  n=VariableSetSize(vars);
646  for(i=0;i<n;i++)
647  {
648  k=GetVariableN(i,vars);
649  s=IntervalSize(&(b->is[k]));
650  if (s>smax)
651  smax=s;
652  }
653 
654  return(smax);
655 }
656 
658 {
659  unsigned int i,n,k;
660  double s,smin;
661 
662  smin=0.0;
663  n=VariableSetSize(vars);
664  for(i=0;i<n;i++)
665  {
666  k=GetVariableN(i,vars);
667  s=IntervalSize(&(b->is[k]));
668  if ((i==0)||(s<smin))
669  smin=s;
670  }
671 
672  return(smin);
673 }
674 
675 /*
676  * Returns the length of the diagonal of box 'b'.
677  */
678 double GetBoxDiagonal(boolean *used,Tbox *b)
679 {
680  unsigned int i;
681  double d,d1;
682 
683  d=0.0;
684  for(i=0;i<b->n;i++)
685  {
686  if ((used==NULL)||(used[i]))
687  {
688  d1=IntervalSize(&(b->is[i]));
689  d=d+(d1*d1);
690  }
691  }
692 
693  return(sqrt(d));
694 }
695 
696 /*
697  * Returns the level (or depth) of a given box. The level corresponds
698  * to the depth in the search three at which the box is stored
699 */
700 unsigned int GetBoxLevel(Tbox *b)
701 {
702  return(b->level);
703 }
704 
705 
706 void RandomPointInBox(boolean *used,double *c,Tbox *b)
707 {
708  unsigned int i,k;
709 
710  k=0;
711  for(i=0;i<b->n;i++)
712  {
713  if ((used==NULL)||(used[i]))
714  {
715  c[k]=randomInInterval(&(b->is[i]));
716  k++;
717  }
718  }
719 }
720 
721 void GetBoxCenter(boolean *used,double *c,Tbox *b)
722 {
723  unsigned int i,k;
724 
725  k=0;
726  for(i=0;i<b->n;i++)
727  {
728  if ((used==NULL)||(used[i]))
729  {
730  c[k]=IntervalCenter(&(b->is[i]));
731  k++;
732  }
733  }
734 }
735 
736 /*
737  * Returns the distance between the center of two boxes
738  */
739 double GetBoxCenterDistance(boolean *used,Tbox *b1,Tbox *b2)
740 {
741  double d,c1,c2,c;
742  unsigned int i;
743 
744  if (b1->n!=b2->n)
745  Error("Can not compute distance between different size boxes");
746 
747  d=0;
748  for(i=0;i<b1->n;i++)
749  {
750  if ((used==NULL)||(used[i]))
751  {
752  c1=IntervalCenter(&(b1->is[i]));
753  c2=IntervalCenter(&(b2->is[i]));
754  c=c1-c2;
755  d+=(c*c);
756  }
757  }
758 
759  return(sqrt(d));
760 }
761 
762 double SquaredDistancePointToBox(double t,double *p,Tbox *b)
763 {
764  unsigned int i;
765  double d,v;
766 
767  d=0.0;
768  for(i=0;((i<b->n)&&(d<=t));i++)
769  {
770  v=DistanceToInterval(p[i],&(b->is[i]));
771  d+=v*v;
772  }
773 
774  return(d);
775 }
776 
777 double DistancePointToBox(double *p,Tbox *b)
778 {
779  return(sqrt(SquaredDistancePointToBox(INF,p,b)));
780 }
781 
782 double SquaredDistanceToBoxDimensionTopology(unsigned int dim,double p,unsigned int *tp,Tbox *b)
783 {
784  double l,u,d,c,d1,d2,r;
785 
786  l=LowerLimit(&(b->is[dim]));
787  u=UpperLimit(&(b->is[dim]));
788  r=u-l;
789  d=0.0;
790  if ((tp==NULL)||(tp[dim]==TOPOLOGY_R)||(l==u)||(r>(M_2PI+ANGLE_ACCURACY)))
791  {
792  /* topology real, null interval, or range size larger than 2pi */
793  /* This is DistanceToInterval but inlined for efficiency */
794  if (p<l)
795  d=l-p;
796  else
797  {
798  if (p>u)
799  d=p-u;
800  }
801  }
802  else
803  {
804  /* range size not larger than 2*pi */
805  if (r<=(M_2PI-ANGLE_ACCURACY))
806  {
807  /* range size lower than 2*pi */
808  PI2PI(l);
809  PI2PI(u);
810  }
811  else
812  {
813  /* range equal to 2*pi */
814  l=-M_PI;
815  u=+M_PI;
816  }
817  c=p;
818  PI2PI(c);
819 
820  if (u<l)
821  {
822  if ((u<=c)&&(c<=l))
823  {
824  d1=c-u;
825  d2=l-c;
826  d=(d1<d2?d1:d2);
827  }
828  }
829  else
830  {
831  /* l<u */
832  if (c<l)
833  {
834  d1=l-c;
835  if (d1>M_PI) d1=M_2PI-d1;
836  d2=u-c;
837  if (d2>M_PI) d2=M_2PI-d2;
838  d=(d1<d2?d1:d2);
839  }
840  else
841  {
842  if (c>u)
843  {
844  d1=c-l;
845  if (d1>M_PI) d1=M_2PI-d1;
846  d2=c-u;
847  if (d2>M_PI) d2=M_2PI-d2;
848  d=(d1<d2?d1:d2);
849  }
850  }
851  }
852  }
853  return(d*d);
854 }
855 
856 
857 double SquaredDistancePointToBoxTopology(double t2,double *p,unsigned int *tp,Tbox *b)
858 {
859  unsigned int i;
860  double l,u,d,v,c,d1,d2,r;
861 
862  d=0.0;
863  if (tp==NULL)
864  {
865  for(i=0;((i<b->n)&&(d<t2));i++)
866  {
867  l=LowerLimit(&(b->is[i]));
868  u=UpperLimit(&(b->is[i]));
869 
870  /* This is DistanceToInterval but inlined for efficiency */
871  if (p[i]<l)
872  {
873  v=l-p[i];
874  d+=v*v;
875  }
876  else
877  {
878  if (p[i]>u)
879  {
880  v=p[i]-u;
881  d+=v*v;
882  }
883  }
884  }
885  }
886  else
887  {
888  for(i=0;((i<b->n)&&(d<t2));i++)
889  {
890  l=LowerLimit(&(b->is[i]));
891  u=UpperLimit(&(b->is[i]));
892  r=(u-l);
893 
894  if ((tp[i]==TOPOLOGY_R)||(l==u)||(r>M_2PI+ANGLE_ACCURACY))
895  {
896  /* topology real, null range, or range size > 2pi */
897  /* This is DistanceToInterval but inlined for efficiency */
898  if (p[i]<l)
899  {
900  v=l-p[i];
901  d+=v*v;
902  }
903  else
904  {
905  if (p[i]>u)
906  {
907  v=p[i]-u;
908  d+=v*v;
909  }
910  }
911  }
912  else
913  {
914  /* range size not larger than 2*pi */
915  if (r<=(M_2PI-ANGLE_ACCURACY))
916  {
917  /* range size lower than 2*pi */
918  PI2PI(l);
919  PI2PI(u);
920  }
921  else
922  {
923  /* range equal to 2*pi */
924  l=-M_PI;
925  u=+M_PI;
926  }
927  c=p[i];
928  PI2PI(c);
929 
930  if (u<l)
931  {
932  if ((u<=c)&&(c<=l))
933  {
934  d1=c-u;
935  d2=l-c;
936  d=(d1<d2?d1:d2);
937  }
938  }
939  else
940  {
941  /*l<u*/
942  if (c<l)
943  {
944  d1=l-c;
945  if (d1>M_PI) d1=M_2PI-d1;
946  d2=u-c;
947  if (d2>M_PI) d2=M_2PI-d2;
948  v=(d1<d2?d1:d2);
949  d+=v*v;
950  }
951  else
952  {
953  if (c>u)
954  {
955  d1=c-l;
956  if (d1>M_PI) d1=M_2PI-d1;
957  d2=c-u;
958  if (d2>M_PI) d2=M_2PI-d2;
959  v=(d1<d2?d1:d2);
960  d+=v*v;
961  }
962  }
963  }
964  }
965  }
966  }
967 
968  return(d);
969 }
970 
971 double DistancePointToBoxTopology(double *p,unsigned int *tp,Tbox *b)
972 {
973  return(sqrt(SquaredDistancePointToBoxTopology(INF,p,tp,b)));
974 }
975 
976 
977 /*
978  * Returns the normalized volume of a box
979  */
980 double GetBoxVolume(boolean *used,Tbox *b)
981 {
982  double volume;
983  unsigned int i;
984 
985  volume=1.0;
986  for(i=0;i<b->n;i++)
987  {
988  if ((used==NULL)||(used[i]))
989  volume*=(IntervalSize(&(b->is[i])));
990  }
991 
992  if (b->n==0)
993  return(0);
994  else
995  return(volume);
996 }
997 
998 double GetBoxSumSide(boolean *used,Tbox *b)
999 {
1000  double ss;
1001  unsigned int i;
1002 
1003  ss=0.0;
1004  for(i=0;i<b->n;i++)
1005  {
1006  if ((used==NULL)||(used[i]))
1007  ss+=(IntervalSize(&(b->is[i])));
1008  }
1009 
1010  if (b->n==0)
1011  return(0);
1012  else
1013  return(ss);
1014 }
1015 
1016 unsigned int GetBoxNIntervals(Tbox *b)
1017 {
1018  return(b->n);
1019 }
1020 
1021 /*
1022  * Returns the dimension along which the box has its maximal size
1023  */
1024 unsigned int GetBoxMaxDim(boolean *used,Tbox *b)
1025 {
1026  unsigned int i;
1027  unsigned int i_max;
1028  double s;
1029  double s_max;
1030 
1031  i_max=0;
1032  s_max=0.0;
1033  for(i=0;i<b->n;i++)
1034  {
1035  if ((used==NULL)||(used[i]))
1036  {
1037  s=IntervalSize(&(b->is[i]));
1038  if (s>s_max)
1039  {
1040  s_max=s;
1041  i_max=i;
1042  }
1043  }
1044  }
1045  if (b->n==0)
1046  return(NO_UINT);
1047  else
1048  return(i_max);
1049 }
1050 
1051 /*
1052  * Returns a dimension along which the box has to be splitted
1053  */
1054 unsigned int GetBoxSplitDim(boolean *used,Tbox *b)
1055 {
1056 
1057  return(GetBoxMaxDim(used,b));
1058 }
1059 
1060 /*
1061  * Produces two symetrical boxes from 'b' ('b1' and 'b2') that result from
1062  * spliting 'b' along th 'n' dimension.
1063  */
1064 void SplitBox(unsigned int n, /*dimension along which the box is splited*/
1065  double r, /*r in [0,1] where to split*/
1066  Tbox *b1, /*first resulting box*/
1067  Tbox *b2, /*second resulting box*/
1068  Tbox *b /*original box*/
1069  )
1070 {
1071  double lp,up,cp;
1072 
1073  if ((r>1.0)||(r<0.0))
1074  Error("Wrong size to split a box");
1075  if (n<b->n)
1076  {
1077  /*b1,b2 created here*/
1078 
1079  #if (_DEBUG>6)
1080  printf("Splitting box along dimension %u\n",n);
1081  #endif
1082 
1083  b1->n=b->n;
1084  b2->n=b->n;
1085 
1086  NEW(b1->is,b1->n,Tinterval);/* Lower box */
1087  NEW(b2->is,b2->n,Tinterval);/* Upper box */
1088 
1089  memcpy(b1->is,b->is,b1->n*sizeof(Tinterval)); /*the sub-boxes are the same as the original*/
1090  memcpy(b2->is,b->is,b1->n*sizeof(Tinterval)); /*but for the split dimension*/
1091 
1092  lp=LowerLimit(&(b->is[n])); /*lower point*/
1093  up=UpperLimit(&(b->is[n])); /*upper point*/
1094  cp=PointInInterval(r,&(b->is[n])); /*point scaling in between lower and upper */
1095 
1096  NewInterval(lp,cp,&(b1->is[n]));
1097  NewInterval(cp,up,&(b2->is[n]));
1098 
1099  b1->level=b2->level=b->level+1; /* the boxes resulting from a split are of the next level of the search */
1100  }
1101  else
1102  Error("Index out of range in SplitBox");
1103 }
1104 
1105 
1106 /*
1107  * Scales a box taking into account the original ranges for the variables
1108  */
1109 void ScaleBox(double max_upper,Tbox *b)
1110 {
1111  unsigned int i;
1112 
1113  for(i=0;i<b->n;i++)
1114  IntervalScale(&(b->is[i]),max_upper,&(b->is[i]));
1115 }
1116 
1117 void AddMargin2Box(double m,Tbox *b)
1118 {
1119  unsigned int i;
1120  Tinterval *r;
1121 
1122  for(i=0;i<b->n;i++)
1123  {
1124  r=&(b->is[i]);
1125  NewInterval(LowerLimit(r)-m,UpperLimit(r)+m,r);
1126  }
1127 }
1128 
1129 boolean CmpBoxDepthFirst(void *b1,void *b2,void *userData)
1130 {
1131  return(((Tbox *)b1)->level>((Tbox *)b2)->level);
1132 }
1133 
1134 boolean CmpBoxBreadthFirst(void *b1,void *b2,void *userData)
1135 {
1136  return(((Tbox *)b1)->level<((Tbox *)b2)->level);
1137 }
1138 
1139 /*
1140  * Prints box 'b' on file 'f'
1141  */
1142 void PrintBox(FILE *f,Tbox *b)
1143 {
1144  unsigned int i;
1145 
1146  fprintf(f,"{ %u ",b->n);
1147  for(i=0;i<b->n;i++)
1148  {
1149  //fprintf(f," %u:",i);
1150  PrintInterval(f,&(b->is[i]));
1151  fprintf(f," ");
1152  }
1153 
1154  fprintf(f,"}\n");
1155 
1156 }
1157 
1158 /*
1159  * Prints box 'b' on file 'f' for some selected variables.
1160  * This is basically used when printing solutions.
1161  */
1162 void PrintBoxSubset(FILE *f,boolean *used,char **varNames,Tbox *b)
1163 {
1164  unsigned int i,n;
1165 
1166  if (used==NULL)
1167  n=b->n;
1168  else
1169  {
1170  n=0;
1171  for(i=0;i<b->n;i++)
1172  if (used[i]) n++;
1173  }
1174 
1175  fprintf(f,"{ %u ",n);
1176  for(i=0;i<b->n;i++)
1177  {
1178  if ((used==NULL)||(used[i]))
1179  {
1180  if (varNames!=NULL)
1181  {
1182  PRINT_VARIABLE_NAME(f,varNames[i]);
1183  }
1184  PrintInterval(f,&(b->is[i]));
1185  fprintf(f," ");
1186  }
1187  }
1188 
1189  fprintf(f,"}\n");
1190 }
1191 
1192 /*
1193  * Reads a box from an opened file. Returns EOF if the file finishes before
1194  * the box could be read
1195 */
1196 int ReadBox(FILE *f,Tbox *b)
1197 {
1198  int token=~EOF;
1199  Tinterval *is;
1200  double i_min,i_max;
1201  unsigned int i;
1202  unsigned int n;
1203 
1204  do token=fgetc(f); while ((token!=EOF)&&(token!='{')); /* skip everything till the beginning of the box */
1205 
1206  if (token!=EOF)
1207  {
1208  fscanf(f,"%u",&n);
1209 
1210  NEW(is,n,Tinterval);
1211 
1212  /* Check whether we have a box with some intervals or an empty box */
1213  do token=fgetc(f); while ((token!=EOF)&&(token!='[')&&(token!='}'));
1214  if (token=='}')
1215  {
1216  /* We have an empty box (the old type of box files). Skip the box and advance until the
1217  first interval of the next box (or end of file) */
1218  do token=fgetc(f); while ((token!=EOF)&&(token!='['));
1219  }
1220  i=0;
1221  while ((token!=EOF)&&(token!='}')) //while the box is not closed (and there is something in the file)
1222  {
1223  if (token=='[') //if the interval exists
1224  {
1225  //read the extremes of the interval
1226  if (fscanf(f,"%lf",&i_min)!=EOF)
1227  {
1228  do token=fgetc(f); while ((token!=EOF)&&(token!=','));
1229  if (fscanf(f,"%lf",&i_max)!=EOF)
1230  {
1231  //if there was no problem reading the extremes set up a new interval
1232  NewInterval(i_min,i_max,&(is[i++]));
1233 
1234  if (i>n)
1235  Error("Too many intervals in the box");
1236  }
1237  else
1238  token=EOF;
1239  }
1240  }
1241  //go to the begining of next interval (if it exists)
1242  do token=fgetc(f); while ((token!=EOF)&&(token!='[')&&(token!='}'));
1243 
1244  }
1245 
1246  if (i<n)
1247  Error("Too few intervals in the box");
1248 
1249  if (token!=EOF) //if the box was read correctly
1250  InitBox(n,is,b); /*and set the new ones*/
1251  free(is);
1252  }
1253 
1254  return(token);
1255 }
1256 
1257 /*Saves in binary format*/
1258 void SaveBox(FILE *f,Tbox *b)
1259 {
1260  fwrite(&(b->n),sizeof(unsigned int),1,f);
1261  fwrite(&(b->level),sizeof(unsigned int),1,f);
1262  if (b->n>0)
1263  fwrite(b->is,sizeof(Tinterval),b->n,f);
1264 }
1265 
1266 void LoadBox(FILE *f,Tbox *b)
1267 {
1268  fread(&(b->n),sizeof(unsigned int),1,f);
1269  fread(&(b->level),sizeof(unsigned int),1,f);
1270 
1271  if (b->n==0)
1272  b->is=NULL;
1273  else
1274  {
1275  NEW(b->is,b->n,Tinterval);
1276  fread(b->is,sizeof(Tinterval),b->n,f);
1277  }
1278 }
1279 
1280 /*
1281  * Deletes the internal data of a box
1282  */
1283 void DeleteBox(void *b)
1284 {
1285  free(((Tbox *)b)->is);
1286 }
double SquaredDistancePointToBox(double t, double *p, Tbox *b)
Distance from a point to a box.
Definition: box.c:762
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:356
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:857
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:566
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:777
#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:631
void * GetVectorElement(unsigned int i, Tvector *vector)
Returns a pointer to a vector element.
Definition: vector.c:270
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:1024
double GetBoxSumSide(boolean *used, Tbox *b)
Computes the sum of the sides of the box.
Definition: box.c:998
#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:1134
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 Crop2Box(boolean *used, unsigned int n, double *p, Tbox *b)
Forces a point to be inside a box.
Definition: box.c:328
void AddMargin2Box(double m, Tbox *b)
Adds a margin to all dimensions of a box.
Definition: box.c:1117
void RandomPointInBox(boolean *used, double *c, Tbox *b)
Returns the a random point along the selected dimensions.
Definition: box.c:706
unsigned int GetBoxNIntervals(Tbox *b)
Box dimensionality.
Definition: box.c:1016
unsigned int GetBoxLevel(Tbox *b)
Returns the box level.
Definition: box.c:700
unsigned int GetVariableN(unsigned int n, Tvariable_set *vs)
Gets a variable identifier from a variable set.
Definition: variable_set.c:454
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:1196
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:545
#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:1064
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:139
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:971
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:678
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:610
#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:739
unsigned int VariableSetSize(Tvariable_set *vs)
Gets the number of elements of a variable set.
Definition: variable_set.c:449
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:1258
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1006
void LoadBox(FILE *f, Tbox *b)
Reads a box in binary format.
Definition: box.c:1266
#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:360
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:782
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:1283
void PrintBoxSubset(FILE *f, boolean *used, char **varNames, Tbox *b)
Prints a (sub-)box.
Definition: box.c:1162
boolean IsInside(double p, double tol, Tinterval *i)
Checks if a value is inside an interval.
Definition: interval.c:348
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:721
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:1129
Definition of basic randomization functions.
void PrintBox(FILE *f, Tbox *b)
Prints a box.
Definition: box.c:1142
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:590
double GetBoxMaxSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the size of the box.
Definition: box.c:639
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:1054
double GetBoxVolume(boolean *used, Tbox *b)
Computes the volume of the box.
Definition: box.c:980
double GetBoxMinSizeVarSet(Tvariable_set *vars, Tbox *b)
Computes the minimum size of the box.
Definition: box.c:657
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:445
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:1109
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:374