interval.c
Go to the documentation of this file.
1 #include "interval.h"
2 
3 #include "error.h"
4 #include "defines.h"
5 #include "geom.h"
6 
7 #include <math.h>
8 
26 double NormalizeAngle(double a);
27 
28 /*
29  * moves the angle 'a' but in the interval [0,2pi]
30  */
31 double NormalizeAngle(double a)
32 {
33  double new_a;
34 
35  new_a=a;
36  if ((new_a>M_PI)||(new_a<-M_PI))
37  new_a=atan2(sin(new_a),cos(new_a));
38 
39  if (new_a<0.0) new_a+=M_2PI;
40 
41  return(new_a);
42 }
43 
44 /*
45  * Defines a new interval with limits: lower and upper
46  */
47 void NewInterval(double lower, /*lower limit of the new interval*/
48  double upper, /*upper limit of the new interval*/
49  Tinterval *i /*new interval*/
50  )
51 {
52  i->lower_limit=INF_CUT(lower);
53  i->upper_limit=INF_CUT(upper);
54 }
55 
56 /*
57  * Copies i_org into i_dst.
58  */
59 void CopyInterval(Tinterval *i_dst,Tinterval *i_org)
60 {
61  i_dst->lower_limit=i_org->lower_limit;
62  i_dst->upper_limit=i_org->upper_limit;
63 }
64 
65 /*
66  * Returns true if i1 and i2 are exactly the same.
67  * This only works for intervals that are exactly the same (copies, the same
68  * initialization,....)
69  */
71 {
72  return((i1->lower_limit==i2->lower_limit)&&
73  (i1->upper_limit==i2->upper_limit));
74 }
75 
76 /*
77  * Returns the lower limit of interval 'i'.
78  */
79 inline double LowerLimit(Tinterval *i)
80 {
81  return(i->lower_limit);
82 }
83 
84 /*
85  * Returns the upper limit of interval 'i'.
86  */
87 inline double UpperLimit(Tinterval *i)
88 {
89  return(i->upper_limit);
90 }
91 
92 /*
93  * Returns the size of interval 'i'.
94  * NOTE: For empty intervals it can return a negative size
95  */
97 {
98  double s;
99 
100  if (IS_INF(i->lower_limit)||IS_INF(i->upper_limit))
101  s=INF;
102  else
103  {
104  ROUNDUP;
105  s=i->upper_limit-i->lower_limit;
106  ROUNDNEAR;
107  }
108 
109  return(s);
110 }
111 
112 double DistanceToInterval(double p,Tinterval *i)
113 {
114  double d=0.0;
115 
116  if (p<i->lower_limit)
117  d=i->lower_limit-p;
118  else
119  {
120  if (p>i->upper_limit)
121  d=p-i->upper_limit;
122  }
123  return(d);
124 }
125 
126 /*
127  * Returns the center of the interval
128  */
130 {
131  double c;
132 
133  if (i->upper_limit==i->lower_limit)
134  c=i->upper_limit;
135  else
136  {
137  if (IS_INF(i->lower_limit)&&(IS_INF(i->upper_limit)))
138  c=0.0;
139  else
140  {
141  if (IS_INF(i->lower_limit))
142  c=i->upper_limit;
143  else
144  {
145  if (IS_INF(i->upper_limit))
146  c=i->lower_limit;
147  else
148  {
149  c=(i->upper_limit+i->lower_limit)/2.0;
150 
151  /* Conditions below can occur because of roundings */
152  if (c<i->lower_limit) c=i->lower_limit;
153  if (c>i->upper_limit) c=i->upper_limit;
154  }
155  }
156  }
157  }
158  return(c);
159 }
160 
161 /*
162  * Returns the point in the interval by linear interpolation between the extremes.
163  */
164 double PointInInterval(double r,Tinterval *i)
165 {
166  double p;
167 
168  if (i->upper_limit==i->lower_limit)
169  p=i->upper_limit;
170  else
171  {
172  if (IS_INF(i->lower_limit)&&(IS_INF(i->upper_limit)))
173  p=0.0;
174  else
175  {
176  if (IS_INF(i->lower_limit))
177  p=i->upper_limit-1;
178  else
179  {
180  if (IS_INF(i->upper_limit))
181  p=i->lower_limit+1;
182  else
183  {
184  p=i->lower_limit+(i->upper_limit-i->lower_limit)*(r<0?0:(r>1?1:r));
185 
186  /* Conditions below can occur because of roundings */
187  if (p<i->lower_limit) p=i->lower_limit;
188  if (p>i->upper_limit) p=i->upper_limit;
189  }
190  }
191  }
192  }
193  return(p);
194 }
195 
196 void SetLowerLimit(double v,Tinterval *i)
197 {
198  i->lower_limit=INF_CUT(v);
199 }
200 
201 void SetUpperLimit(double v,Tinterval *i)
202 {
203  i->upper_limit=INF_CUT(v);
204 }
205 
206 void EnlargeInterval(double lo,double uo,Tinterval *i)
207 {
208  double v;
209 
210  if (IS_NOT_INF(i->lower_limit))
211  {
212  if (IS_INF(lo))
213  i->lower_limit=lo;
214  else
215  {
216  ROUNDDOWN;
217  v=i->lower_limit+lo;
218  i->lower_limit=INF_CUT(v);
219  }
220  }
221 
222  if (IS_NOT_INF(i->upper_limit))
223  {
224  if (IS_INF(uo))
225  i->upper_limit=uo;
226  else
227  {
228  ROUNDUP;
229  v=i->upper_limit+uo;
230  i->upper_limit=INF_CUT(v);
231  }
232  }
233  ROUNDNEAR;
234 }
235 
236 void ExpandInterval(double v,Tinterval *i)
237 {
238  if (v<i->lower_limit)
239  i->lower_limit=INF_CUT(v);
240  else
241  {
242  if (v>i->upper_limit)
243  i->upper_limit=INF_CUT(v);
244  }
245 }
246 
247 void UpdateLowerLimit(double v,Tinterval *i)
248 {
249  if (v>i->lower_limit)
250  i->lower_limit=INF_CUT(v);
251 }
252 
253 void UpdateUpperLimit(double v,Tinterval *i)
254 {
255  if (v<i->upper_limit)
256  i->upper_limit=INF_CUT(v);
257 }
258 
259 /*
260  * Returns TRUE if i1 is fully included in i2
261  */
263 {
264  return((i2->lower_limit<i1->lower_limit)&&(i1->upper_limit<i2->upper_limit));
265 }
266 
267 /*
268  * Returns TRUE if intervals 'i1' and 'i2' actually intersect.
269  * NOTE: This rutine is only valid for intervals where lower_limit<upper_limit
270  * and thus it fails in the intersection between certain rotational intervals.
271  */
272 boolean Intersect(Tinterval *i1,Tinterval *i2)
273 {
274  Tinterval i3;
275 
276  return(Intersection(i1,i2,&i3));
277 }
278 
279 /*
280  * Returns in 'i_out' the intersection of intervals 'i1' and 'i2'.
281  * NOTE: This rutine is only valid for intervals where lower_limit<upper_limit
282  * and thus it can fail for intersection between certain rotational intervals.
283  * RETURNS true if the intersection is NOT EMPTY
284  */
285 boolean Intersection(Tinterval *i1,Tinterval *i2,Tinterval *i_out)
286 {
287  i_out->lower_limit=(i1->lower_limit>i2->lower_limit?i1->lower_limit:i2->lower_limit);
288  i_out->upper_limit=(i1->upper_limit<i2->upper_limit?i1->upper_limit:i2->upper_limit);
289 
290  return(i_out->lower_limit<=i_out->upper_limit);
291 }
292 
293 /*
294  * Returns in i_out the union of i1 and i2
295  * Returns false if the the input intervals are empty
296 */
297 boolean Union(Tinterval *i1,Tinterval *i2,Tinterval *i_out)
298 {
299  boolean full;
300 
301  full=TRUE;
302 
303  if (i1->lower_limit>i1->upper_limit) /*i1 empty*/
304  {
305  if (i2->lower_limit>i2->upper_limit)/*i2 empty*/
306  full=FALSE;
307  else
308  {
309  i_out->lower_limit=i2->lower_limit;
310  i_out->upper_limit=i2->upper_limit;
311  }
312  }
313  else
314  {
315  if (i2->lower_limit>i2->upper_limit) /*i2 empty*/
316  {
317  i_out->lower_limit=i1->lower_limit;
318  i_out->upper_limit=i1->upper_limit;
319  }
320  else
321  {
322  i_out->lower_limit=(i1->lower_limit<i2->lower_limit?i1->lower_limit:i2->lower_limit);
323  i_out->upper_limit=(i1->upper_limit>i2->upper_limit?i1->upper_limit:i2->upper_limit);
324  }
325  }
326  return(full);
327 }
328 
329 
330 /*
331  * Returns TRUE if interval 'i' is empty
332  * NOTE: This rutine is only valid for intervals where lower_limit<upper_limit
333  * and thus it can return wrong results for certain rotational intervals.
334  */
336 {
337  return(i->lower_limit>i->upper_limit);
338 }
339 
341 {
342  return((fabs(i->lower_limit)<ZERO)&&(fabs(i->upper_limit)<ZERO));
343 }
344 
345 /*
346  * returns true if p is inside the interval i
347  */
348 boolean IsInside(double p,double tol,Tinterval *i)
349 {
350  double v;
351 
352  v=INF_CUT(p);
353  return((v>=(i->lower_limit-tol))&&(v<=(i->upper_limit+tol)));
354 }
355 
356 /*
357  * Products and interval and a scalar
358  * Be carefull i_out can be i1 or i2!!!!!
359  */
360 void IntervalScale(Tinterval *i1,double e,Tinterval *i_out)
361 {
362  double e1,e2;
363 
364  if (e>0)
365  {
366  ROUNDDOWN;
367  e1=INF_SCALE(e,i1->lower_limit);
368  ROUNDUP;
369  e2=INF_SCALE(e,i1->upper_limit);
370  }
371  else
372  {
373  /*The sign is changed: extremes are swap */
374  ROUNDDOWN;
375  e1=INF_SCALE(e,i1->upper_limit);
376  ROUNDUP;
377  e2=INF_SCALE(e,i1->lower_limit);
378  }
379  ROUNDNEAR;
380 
381  i_out->lower_limit=INF_CUT(e1);
382  i_out->upper_limit=INF_CUT(e2);
383 }
384 
385 /*
386  * Product of two intervals
387  * Be carefull i_out can be i1 or i2!!!!!
388  */
390 {
391  double e[3];
392  unsigned int i;
393  double a,b;
394 
395  ROUNDDOWN;
396  e[0]=INF_PROD(i1->lower_limit,i2->upper_limit,TRUE);
397  e[1]=INF_PROD(i1->upper_limit,i2->lower_limit,TRUE);
398  e[2]=INF_PROD(i1->upper_limit,i2->upper_limit,TRUE);
399 
401  for(i=0;i<3;i++)
402  if (e[i]<a) a=e[i];
403 
404  ROUNDUP;
405  e[0]=INF_PROD(i1->lower_limit,i2->upper_limit,FALSE);
406  e[1]=INF_PROD(i1->upper_limit,i2->lower_limit,FALSE);
407  e[2]=INF_PROD(i1->upper_limit,i2->upper_limit,FALSE);
408 
410  for(i=0;i<3;i++)
411  if (e[i]>b) b=e[i];
412 
413  ROUNDNEAR;
414 
415  i_out->lower_limit=INF_CUT(a);
416  i_out->upper_limit=INF_CUT(b);
417 }
418 
419 /*
420  * Additon of two intervals
421  * Be carefull i_out can be i1 or i2!!!!!
422  */
424 {
425  double a,b;
426 
427  ROUNDDOWN;
428  a=INF_ADD(i1->lower_limit,i2->lower_limit,TRUE);
429 
430  ROUNDUP;
432 
433  ROUNDNEAR;
434 
435  i_out->lower_limit=INF_CUT(a);
436  i_out->upper_limit=INF_CUT(b);
437 }
438 
439 /*
440  * i_out=i1-i2;
441  */
443 {
444  double a,b;
445 
446  ROUNDDOWN;
448 
449  ROUNDUP;
451 
452  ROUNDNEAR;
453 
454  i_out->lower_limit=INF_CUT(a);
455  i_out->upper_limit=INF_CUT(b);
456 }
457 
458 /*
459  * Changes the sign of a given interval
460  */
462 {
463  double a,b;
464 
465  a=-i->upper_limit;
466  b=-i->lower_limit;
467 
468  i_out->lower_limit=a;
469  i_out->upper_limit=b;
470 }
471 
472 /*
473  * i_out=exo(i)
474  */
476 {
477  double a,b;
478 
479  ROUNDDOWN;
480  a=INF_EXP(i->lower_limit);
481 
482  ROUNDUP;
483  b=INF_EXP(i->upper_limit);
484 
485  ROUNDNEAR;
486 
487  i_out->lower_limit=INF_CUT(a);
488  i_out->upper_limit=INF_CUT(b);
489 }
490 
491 /*
492  * i_out=i^p
493  */
494 void IntervalPow(Tinterval *i,unsigned int p,Tinterval *i_out)
495 {
496  double a,b,e1,e2;
497 
498  ROUNDDOWN;
499  e1=INF_POW(i->lower_limit,p);
500  e2=INF_POW(i->upper_limit,p);
501 
502  if (e1<e2)
503  a=e1;
504  else
505  a=e2;
506 
507  ROUNDUP;
508  e1=INF_POW(i->lower_limit,p);
509  e2=INF_POW(i->upper_limit,p);
510 
511  if (e1>e2)
512  b=e1;
513  else
514  b=e2;
515 
516  ROUNDNEAR;
517 
518  if (((p%2)==0)&&(IsInside(0,0,i)))
519  a=0; /*x^p with p=2*n always have a minimum at 0 (if included in the input interval)*/
520 
521  i_out->lower_limit=INF_CUT(a);
522  i_out->upper_limit=INF_CUT(b);
523 }
524 
525 
526 
527 /*
528  * Square root
529  */
530 boolean IntervalSqrt(Tinterval *i,Tinterval *i_out)
531 {
532  double a,b;
533 
534  if (i->upper_limit<0.0)
535  return(FALSE);
536  else
537  {
538  ROUNDDOWN;
539  a=INF_SQRT(i->lower_limit);
540 
541  ROUNDUP;
542  b=INF_SQRT(i->upper_limit);
543 
544  ROUNDNEAR;
545 
546  i_out->lower_limit=INF_CUT(a);
547  i_out->upper_limit=INF_CUT(b);
548 
549  return(TRUE);
550  }
551 }
552 
553 /*
554  * i_out = i1/i2
555  */
557 {
558  double a,b;
559 
560  if (IsInside(0,0,i2))
561  {
562  if ((i2->lower_limit==0.0)&&(i2->upper_limit>0.0))
563  {
564  ROUNDDOWN;
565  a=i1->lower_limit/i2->upper_limit;
566  b=i1->upper_limit/i2->upper_limit;
567  a=(a<b?a:b);
568  ROUNDNEAR;
569  i_out->lower_limit=INF_CUT(a);
570 
571  i_out->upper_limit=+INF;
572  }
573  else
574  {
575  if ((i2->lower_limit<0.0)&&(i2->upper_limit==0.0))
576  {
577  i_out->lower_limit=-INF;
578 
579  ROUNDUP;
580  a=i1->lower_limit/i2->lower_limit;
581  b=i1->upper_limit/i2->lower_limit;
582  b=(b>a?b:a);
583  ROUNDNEAR;
584  i_out->upper_limit=INF_CUT(b);
585 
586  }
587  else
588  {
589  i_out->lower_limit=-INF;
590  i_out->upper_limit=+INF;
591  }
592  }
593  }
594  else
595  {
596  double e[3];
597  unsigned int i;
598 
599  ROUNDDOWN;
600  e[0]=i1->lower_limit/i2->upper_limit;
601  e[1]=i1->upper_limit/i2->lower_limit;
602  e[2]=i1->upper_limit/i2->upper_limit;
603 
604  a=i1->lower_limit/i2->lower_limit;
605  for(i=0;i<3;i++)
606  if (e[i]<a) a=e[i];
607 
608  ROUNDUP;
609  e[0]=i1->lower_limit/i2->upper_limit;
610  e[1]=i1->upper_limit/i2->lower_limit;
611  e[2]=i1->upper_limit/i2->upper_limit;
612 
613  b=i1->lower_limit/i2->lower_limit;
614  for(i=0;i<3;i++)
615  if (e[i]>b) b=e[i];
616 
617  ROUNDNEAR;
618 
619  i_out->lower_limit=INF_CUT(a);
620  i_out->upper_limit=INF_CUT(b);
621  }
622 }
623 
624 /*
625  * Shifts a interval
626 */
627 void IntervalOffset(Tinterval *i,double offset,Tinterval *i_out)
628 {
629  double a,b;
630 
631  ROUNDDOWN;
632  a=INF_ADD(i->lower_limit,offset,TRUE);
633 
634  ROUNDUP;
635  b=INF_ADD(i->upper_limit,offset,FALSE);
636 
637  ROUNDNEAR;
638 
639  i_out->lower_limit=INF_CUT(a);
640  i_out->upper_limit=INF_CUT(b);
641 }
642 
643 
644 /*
645  * Computes the sinus of an interval
646  */
648 {
649  double l,u;
650 
651  if (IntervalSize(i)>=M_2PI)
652  NewInterval(-1,1,i_out);
653  else
654  {
657 
658  if (u<l)
659  {
660  Tinterval i_in;
661  Tinterval i_out1,i_out2;
662 
663  i_in.lower_limit=l;
664  i_in.upper_limit=M_2PI;
665 
666  IntervalSine(&i_in,&i_out1);
667 
668  i_in.lower_limit=0.0;
669  i_in.upper_limit=u;
670 
671  IntervalSine(&i_in,&i_out2);
672 
673  i_out->lower_limit=(i_out1.lower_limit<i_out2.lower_limit?i_out1.lower_limit:i_out2.lower_limit);
674  i_out->upper_limit=(i_out1.upper_limit>i_out2.upper_limit?i_out1.upper_limit:i_out2.upper_limit);
675  }
676  else
677  {
678  double a,b;
679 
680  a=sin(l);
681  b=sin(u);
682 
683  if ((l<=M_PI_2)&&(M_PI_2<=u))
684  i_out->upper_limit=1.0;
685  else
686  /* We +/- 1e-6 to compensate for possible errors
687  introduced by the NormalizeAngle and the
688  computation of trigonometric functions. */
689  i_out->upper_limit=(a>b?a:b)+1e-6;
690 
691  if ((l<=(3.0*M_PI_2))&&((3.0*M_PI_2)<=u))
692  i_out->lower_limit=-1.0;
693  else
694  i_out->lower_limit=(a<b?a:b)-1e-6;
695  }
696  }
697 }
698 
699 /*
700  * Computes the cosinus of an interval
701  */
703 {
704  double l,u;
705 
706  if (IntervalSize(i)>=M_2PI)
707  NewInterval(-1,1,i_out);
708  else
709  {
712 
713  if (u<l)
714  {
715  Tinterval i_in;
716  Tinterval i_out1,i_out2;
717 
718  i_in.lower_limit=l;
719  i_in.upper_limit=M_2PI;
720 
721  IntervalCosine(&i_in,&i_out1);
722 
723  i_in.lower_limit=0.0;
724  i_in.upper_limit=u;
725 
726  IntervalCosine(&i_in,&i_out2);
727 
728  i_out->lower_limit=(i_out1.lower_limit<i_out2.lower_limit?i_out1.lower_limit:i_out2.lower_limit);
729  i_out->upper_limit=(i_out1.upper_limit>i_out2.upper_limit?i_out1.upper_limit:i_out2.upper_limit);
730  }
731  else
732  {
733  double a,b;
734 
735  a=cos(l);
736  b=cos(u);
737 
738  if ((l<=0.0)&&(0.0<=u))
739  i_out->upper_limit=1.0;
740  else
741  /* We +/- 1e-6 to compensate for possible errors
742  introduced by the NormalizeAngle and the
743  computation of trigonometric functions. */
744  i_out->upper_limit=(a>b?a:b)+1e-6;
745 
746  if ((l<=M_PI)&&(M_PI<=u))
747  i_out->lower_limit=-1.0;
748  else
749  i_out->lower_limit=(a<b?a:b)-1e-6;
750  }
751  }
752 }
753 
755 {
756  double l,u;
757 
758  if (IntervalSize(i)>=M_2PI)
759  NewInterval(-INF,INF,i_out);
760  else
761  {
764 
765  if (u<l)
766  {
767  Tinterval i_in;
768  Tinterval i_out1,i_out2;
769 
770  i_in.lower_limit=l;
771  i_in.upper_limit=M_2PI;
772 
773  IntervalTangent(&i_in,&i_out1);
774 
775  i_in.lower_limit=0.0;
776  i_in.upper_limit=u;
777 
778  IntervalTangent(&i_in,&i_out2);
779 
780  i_out->lower_limit=(i_out1.lower_limit<i_out2.lower_limit?i_out1.lower_limit:i_out2.lower_limit);
781  i_out->upper_limit=(i_out1.upper_limit>i_out2.upper_limit?i_out1.upper_limit:i_out2.upper_limit);
782  }
783  else
784  {
785  if (((l<=M_PI_2)&&(M_PI_2<=u))||((l<=3*M_PI_2)&&(3*M_PI_2<=u)))
786  {
787  /* If the range includes one of the singular points, check
788  if the range is upper/lower bounded by the singularity */
789  if (u==M_PI_2)
790  {
791  i_out->lower_limit=tan(l)-1e-6;
792  i_out->upper_limit=+INF;
793  }
794  else
795  {
796  if (l==3*M_PI_2)
797  {
798  i_out->lower_limit=-INF;
799  i_out->upper_limit=tan(u)+1e-6;
800  }
801  else
802  {
803  if (l==M_PI_2)
804  {
805  if (u==3*M_PI_2)
806  {
807  i_out->lower_limit=-INF;
808  i_out->upper_limit=+INF;
809  }
810  else
811  {
812  i_out->lower_limit=-INF;
813  i_out->upper_limit=tan(u)+1e-6;
814  }
815  }
816  else
817  {
818  if (u==3*M_PI_2)
819  {
820  i_out->lower_limit=tan(l)-1e-6;
821  i_out->upper_limit=+INF;
822  }
823  else
824  {
825  i_out->lower_limit=-INF;
826  i_out->upper_limit=+INF;
827  }
828  }
829  }
830  }
831  }
832  else
833  {
834  double a,b;
835 
836  a=tan(l);
837  b=tan(u);
838 
839  i_out->lower_limit=(a<b?a:b)-1e-6;
840  i_out->upper_limit=(a>b?a:b)+1e-6;
841  }
842  }
843  }
844 }
845 
847 {
848  Tinterval c,one;
849 
850  NewInterval(1,1,&one);
851  IntervalCosine(i,&c);
852  IntervalPow(&c,2,&c);
853  IntervalDivision(&one,&c,i_out);
854 }
855 
857 {
858  double l,u;
859 
860  if (IntervalSize(i)>=M_2PI)
861  NewInterval(-INF,INF,i_out);
862  else
863  {
866 
867  if (u<l)
868  {
869  Tinterval i_in;
870  Tinterval i_out1,i_out2;
871 
872  i_in.lower_limit=l;
873  i_in.upper_limit=M_2PI;
874 
875  IntervalTangent(&i_in,&i_out1);
876 
877  i_in.lower_limit=0.0;
878  i_in.upper_limit=u;
879 
880  IntervalTangent(&i_in,&i_out2);
881 
882  i_out->lower_limit=(i_out1.lower_limit<i_out2.lower_limit?i_out1.lower_limit:i_out2.lower_limit);
883  i_out->upper_limit=(i_out1.upper_limit>i_out2.upper_limit?i_out1.upper_limit:i_out2.upper_limit);
884  }
885  else
886  {
887  double c;
888 
889  if (((l<=M_PI_2)&&(M_PI_2<=u))||((l<=3*M_PI_2)&&(3*M_PI_2<=u)))
890  {
891  /* If the range includes one of the singular points, check
892  if the range is upper/lower bounded by the singularity */
893  if (u==M_PI_2)
894  {
895  c=cos(l);
896  i_out->lower_limit=tan(l)/(c*c)-1e-6;
897  i_out->upper_limit=+INF;
898  }
899  else
900  {
901  if (l==3*M_PI_2)
902  {
903  c=cos(u);
904  i_out->lower_limit=-INF;
905  i_out->upper_limit=tan(u)/(c*c)+1e-6;
906  }
907  else
908  {
909  if (l==M_PI_2)
910  {
911  if (u==3*M_PI_2)
912  {
913  i_out->lower_limit=-INF;
914  i_out->upper_limit=+INF;
915  }
916  else
917  {
918  c=cos(u);
919  i_out->lower_limit=-INF;
920  i_out->upper_limit=tan(u)/(c*c)+1e-6;
921  }
922  }
923  else
924  {
925  if (u==3*M_PI_2)
926  {
927  c=cos(l);
928  i_out->lower_limit=tan(l)/(c*c)-1e-6;
929  i_out->upper_limit=+INF;
930  }
931  else
932  {
933  i_out->lower_limit=-INF;
934  i_out->upper_limit=+INF;
935  }
936  }
937  }
938  }
939  }
940  else
941  {
942  double a,b;
943 
944  c=cos(l);
945  a=tan(l)/(c*c);
946 
947  c=cos(u);
948  b=tan(u)/(c*c);
949 
950  i_out->lower_limit=(a<b?a:b)-1e-6;
951  i_out->upper_limit=(a>b?a:b)+1e-6;
952  }
953  }
954  }
955 }
956 
958 {
959  double a[4];
960  unsigned int i;
961  double t1,t2;
962 
963  if ((IntervalSize(is)>0.5)||(IntervalSize(ic)>0.5))
964  Error ("Interval atan2 only works for small intervals");
965 
966  a[0]=atan2(is->lower_limit,ic->lower_limit);
967  a[1]=atan2(is->lower_limit,ic->upper_limit);
968  a[2]=atan2(is->upper_limit,ic->lower_limit);
969  a[3]=atan2(is->upper_limit,ic->upper_limit);
970 
971  t1=t2=a[0];
972  for(i=1;i<4;i++)
973  {
974  if (a[i]<t1) t1=a[i];
975  else {if (a[i]>t2) t2=a[i];}
976  }
977 
978  i_out->lower_limit=t1;
979  i_out->upper_limit=t2;
980 
981  if ((i_out->upper_limit-i_out->lower_limit)>M_PI)
982  {
983  double d;
984 
985  d=i_out->lower_limit;
986  i_out->lower_limit=i_out->upper_limit;
987  i_out->upper_limit=d+M_2PI;
988  }
989 }
990 
992 {
993  if (EmptyInterval(i))
994  fprintf(f,"(Empty Interval)");
995 
996  fprintf(f,"[");
998  fprintf(f,",");
1000  fprintf(f,"]");
1001 }
1002 
1003 /*
1004  * Prints the contents of interval 'i' on file 'f'.
1005  */
1006 void PrintInterval(FILE *f,Tinterval *i)
1007 {
1008  if (EmptyInterval(i))
1009  fprintf(f,"(Empty Interval)");
1010 
1011  fprintf(f,"[");
1012  INF_PRINT(f,i->lower_limit);
1013  fprintf(f,",");
1014  INF_PRINT(f,i->upper_limit);
1015  fprintf(f,"]");
1016 }
1017 
1018 /*
1019  * Deletes the internal structures of interval 'i'.
1020  */
1022 {
1023 }
void UpdateLowerLimit(double v, Tinterval *i)
Updates the lower limit.
Definition: interval.c:247
boolean Intersect(Tinterval *i1, Tinterval *i2)
Checks is a two intervals intersect.
Definition: interval.c:272
boolean ZeroInterval(Tinterval *i)
Checks if a given interval is zero.
Definition: interval.c:340
Definition of basic functions.
void EnlargeInterval(double lo, double uo, Tinterval *i)
Symmetrically increases the size of an interval.
Definition: interval.c:206
#define FALSE
FALSE.
Definition: boolean.h:30
#define INF_SQRT(a)
Sqrt of a number, possibly +/-inf.
Definition: defines.h:334
double IntervalCenter(Tinterval *i)
Gets the interval center.
Definition: interval.c:129
void CopyInterval(Tinterval *i_dst, Tinterval *i_org)
Copy constructor.
Definition: interval.c:59
void SetUpperLimit(double v, Tinterval *i)
Sets a new upper limit.
Definition: interval.c:201
boolean IntervalInclusion(Tinterval *i1, Tinterval *i2)
Checks is a given interval is fully included into another interval.
Definition: interval.c:262
#define ROUNDDOWN
Sets the floating point operations in rounding down mode.
Definition: defines.h:219
#define INF_PRINT(f, a)
Prints a number (possibly +/-inf) to a file.
Definition: defines.h:344
void IntervalSecant2(Tinterval *i, Tinterval *i_out)
Interval squared secant.
Definition: interval.c:846
boolean CmpIntervals(Tinterval *i1, Tinterval *i2)
Compares two intervals.
Definition: interval.c:70
boolean IntervalSqrt(Tinterval *i, Tinterval *i_out)
Interval square root.
Definition: interval.c:530
boolean Union(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Computes the union of two intervals.
Definition: interval.c:297
#define TRUE
TRUE.
Definition: boolean.h:21
void SetLowerLimit(double v, Tinterval *i)
Sets a new lower limit.
Definition: interval.c:196
void Error(const char *s)
General error function.
Definition: error.c:80
double LowerLimit(Tinterval *i)
Gets the lower limit.
Definition: interval.c:79
#define IS_INF(a)
Identifies +/-inf.
Definition: defines.h:246
boolean EmptyInterval(Tinterval *i)
Checks if a given interval is empty.
Definition: interval.c:335
#define ZERO
Floating point operations giving a value below this constant (in absolute value) are considered 0...
Definition: defines.h:37
void ExpandInterval(double v, Tinterval *i)
Changes the interval limits to include a given point.
Definition: interval.c:236
boolean IsInside(double p, double tol, Tinterval *i)
Checks if a value is inside an interval.
Definition: interval.c:348
Error and warning functions.
#define INF_SCALE(s, a)
Scales a number, possibly inf or -inf.
Definition: defines.h:267
#define INF_PROD(a, b, d)
Product of two numbers, possibly inf or -inf.
Definition: defines.h:289
#define SYMBOL_PRINT(f, a)
Prints a number (possibly +/-PI, +/-PI/2, or +/-inf) to a file.
Definition: defines.h:376
void PrintSymbolInterval(FILE *f, Tinterval *i)
Prints an angular interval.
Definition: interval.c:991
Definitions of constants and macros used in several parts of the cuik library.
#define M_PI_2
Pi/2.
Definition: defines.h:92
double NormalizeAngle(double a)
Normalizes a angular value so that it is included in [0,2Pi].
Definition: interval.c:31
void IntervalTangent(Tinterval *i, Tinterval *i_out)
Interval tangent.
Definition: interval.c:754
void IntervalSecant2Tangent(Tinterval *i, Tinterval *i_out)
Interval squared secant per tangent.
Definition: interval.c:856
#define ROUNDNEAR
Sets the floating point operations in round near mode.
Definition: defines.h:225
#define INF_SUBS(a, b, d)
Substract two numbers, possibly inf or -inf.
Definition: defines.h:315
void IntervalOffset(Tinterval *i, double offset, Tinterval *i_out)
Interval offset.
Definition: interval.c:627
#define INF_ADD(a, b, d)
Adds two numbers, possibly inf or -inf.
Definition: defines.h:302
void IntervalAtan2(Tinterval *is, Tinterval *ic, Tinterval *i_out)
Interval atan2.
Definition: interval.c:957
#define INF_EXP(a)
Exponentional of a number, possibly inf or -inf.
Definition: defines.h:276
boolean Intersection(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Computes the intersection of two intervals.
Definition: interval.c:285
#define M_2PI
2*Pi.
Definition: defines.h:100
#define M_PI
Pi.
Definition: defines.h:83
void IntervalSubstract(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Substraction of two intervals.
Definition: interval.c:442
#define IS_NOT_INF(a)
Identifies not +/-inf.
Definition: defines.h:255
void IntervalScale(Tinterval *i1, double e, Tinterval *i_out)
Scales an interval.
Definition: interval.c:360
void IntervalProduct(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Product of two intervals.
Definition: interval.c:389
void IntervalInvert(Tinterval *i, Tinterval *i_out)
Change of sign of a given interval.
Definition: interval.c:461
void NewInterval(double lower, double upper, Tinterval *i)
Constructor.
Definition: interval.c:47
#define ROUNDUP
Sets the floating point operations in rounding up mode.
Definition: defines.h:213
double upper_limit
Definition: interval.h:36
void IntervalPow(Tinterval *i, unsigned int p, Tinterval *i_out)
Power of a given interval by a integer power factor.
Definition: interval.c:494
double lower_limit
Definition: interval.h:35
#define INF_CUT(a)
Sets a number, without going beyond +/-inf.
Definition: defines.h:237
#define INF
Infinite.
Definition: defines.h:70
double UpperLimit(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:87
double PointInInterval(double r, Tinterval *i)
Gets a point inside the interval.
Definition: interval.c:164
void IntervalSine(Tinterval *i, Tinterval *i_out)
Interval sine.
Definition: interval.c:647
void IntervalExp(Tinterval *i, Tinterval *i_out)
Exponentional of an interval.
Definition: interval.c:475
void IntervalDivision(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Interval division.
Definition: interval.c:556
Defines a interval.
Definition: interval.h:33
void PrintInterval(FILE *f, Tinterval *i)
Prints an interval.
Definition: interval.c:1006
void UpdateUpperLimit(double v, Tinterval *i)
Updates the upper limit.
Definition: interval.c:253
double DistanceToInterval(double p, Tinterval *i)
Distance to an interval.
Definition: interval.c:112
#define INF_POW(a, p)
Power of a number, possibly +/-inf.
Definition: defines.h:325
void DeleteInterval(Tinterval *i)
Destructor.
Definition: interval.c:1021
double IntervalSize(Tinterval *i)
Gets the uppser limit.
Definition: interval.c:96
void IntervalAdd(Tinterval *i1, Tinterval *i2, Tinterval *i_out)
Addition of two intervals.
Definition: interval.c:423
void IntervalCosine(Tinterval *i, Tinterval *i_out)
Interval cosine.
Definition: interval.c:702
Definition of the Tinterval type and the associated functions.