111 #ifndef MC__INTERVAL_HPP
112 #define MC__INTERVAL_HPP
118 #include "mcfunc.hpp"
161 friend std::ostream&
operator<<
163 friend bool operator==
165 friend bool operator!=
167 friend bool operator<=
169 friend bool operator>=
171 friend bool operator<
173 friend bool operator>
226 (
const unsigned int,
const Interval*,
const int* );
234 (
const unsigned int,
const Interval* );
236 (
const unsigned int,
const Interval* );
294 c>=0 ? _l*=c, _u*=c : _l=_u*c, _u=t*c;
355 return "mc::Interval\t Division by zero";
357 return "mc::Interval\t Inverse with zero in range";
359 return "mc::Interval\t Log with negative values in range";
361 return "mc::Interval\t Square-root with nonpositive values in range";
363 return "mc::Interval\t Inverse cosine with values outside of [-1,1] range";
365 return "mc::Interval\t Inverse sine with values outside of [-1,1] range";
367 return "mc::Interval\t Tangent with values pi/2+k*pi in range";
369 return "mc::Interval\t Undocumented error";
385 (
const double l,
const double u ):
386 _l(l<u?l:u), _u(l<u?u:l)
399 const double&
l()
const
404 const double&
u()
const
410 void l (
const double lb )
415 void u (
const double ub )
431 Interval::Options Interval::options;
444 Interval I2( -I._u, -I._l );
450 (
const double c,
const Interval&I )
452 Interval I2( c + I._l, c + I._u );
458 (
const Interval&I,
const double c )
460 Interval I2( c + I._l, c + I._u );
466 (
const Interval&I1,
const Interval&I2 )
468 Interval I3( I1._l+I2._l, I1._u+I2._u );
474 (
const double c,
const Interval&I )
476 Interval I2( c - I._u, c - I._l );
482 (
const Interval&I,
const double c )
484 Interval I2( I._l-c, I._u-c );
490 (
const Interval&I1,
const Interval&I2 )
492 Interval I3( I1._l-I2._u, I1._u-I2._l );
498 (
const double c,
const Interval&I )
500 Interval I2( c>=0? c*I._l: c*I._u, c>=0? c*I._u: c*I._l );
506 (
const Interval&I,
const double c )
508 Interval I2( c>=0? c*I._l: c*I._u, c>=0? c*I._u: c*I._l );
514 (
const Interval&I1,
const Interval&I2 )
516 Interval I3( std::min(std::min(I1._l*I2._l,I1._l*I2._u),
517 std::min(I1._u*I2._l,I1._u*I2._u)),
518 std::max(std::max(I1._l*I2._l,I1._l*I2._u),
519 std::max(I1._u*I2._l,I1._u*I2._u)) );
525 (
const Interval &I,
const double c )
533 (
const double c,
const Interval&I )
540 (
const Interval&I1,
const Interval&I2 )
547 (
const Interval &I )
554 (
const Interval &I )
556 return 0.5*(I._u+I._l);
561 (
const Interval &I )
563 return std::max(std::fabs(I._l),std::fabs(I._u));
568 (
const Interval &I )
571 Interval I2( 1./I._u, 1./I._l );
580 Interval I2( mc::sqr( mid(I._l,I._u,0.,imid) ),
581 std::max(mc::sqr(I._l),mc::sqr(I._u)) );
587 (
const Interval &I )
589 Interval I2( std::exp(I._l), std::exp(I._u) );
595 (
const Interval &I,
const double a )
602 (
const Interval &I )
605 Interval I2( std::log(I._l), std::log(I._u) );
615 Interval I2( xlog(mid(I._l,I._u,std::exp(-1.),imid)),
616 std::max(xlog(I._l),xlog(I._u)) );
622 (
const Interval &I )
624 Interval I2( ::erf(I._l), ::erf(I._u) );
630 (
const Interval &I )
632 Interval I2( ::erfc(I._u), ::erfc(I._l) );
641 Interval I2( std::sqrt(I._l), std::sqrt(I._u) );
650 Interval I2( std::fabs(mid(I._l,I._u,0.,imid)),
651 std::max(std::fabs(I._l),std::fabs(I._u)) );
657 (
const Interval&I,
const int n )
665 if( n >= 2 && n%2 == 0 ){
667 Interval I2( std::pow(mid(I._l,I._u,0.,imid),n),
668 std::max(std::pow(I._l,n),std::pow(I._u,n)) );
672 Interval I2( std::pow(I._l,n), std::pow(I._u,n) );
675 return inv( pow( I, -n ) );
680 (
const unsigned int n,
const Interval*I,
const int*k)
686 return pow( I[0], k[0] );
688 return pow( I[0], k[0] ) * monomial( n-1, I+1, k+1 );
693 (
const Interval&I,
const double a )
695 return exp( a * log( I ) );
700 (
const Interval&I1,
const Interval&I2 )
702 return exp( I2 * log( I1 ) );
707 (
const Interval&I1,
const Interval&I2 )
709 Interval I3( std::min( I1._l, I2._l ), std::max( I1._u, I2._u ) );
715 (
const Interval&I1,
const Interval&I2 )
717 Interval I3( std::min( I1._l, I2._l ), std::min( I1._u, I2._u ) );
723 (
const Interval&I1,
const Interval&I2 )
725 Interval I3( std::max( I1._l, I2._l ), std::max( I1._u, I2._u ) );
731 (
const unsigned int n,
const Interval*I )
733 Interval I2( n==0 || !I ? 0.: I[0] );
734 for(
unsigned int i=1; i<n; i++ ) I2 = min( I2, I[i] );
740 (
const unsigned int n,
const Interval*I )
742 Interval I2( n==0 || !I ? 0.: I[0] );
743 for(
unsigned int i=1; i<n; i++ ) I2 = max( I2, I[i] );
751 const int k = std::ceil(-(1.+I._l/PI)/2.);
752 const double l = I._l+2.*PI*k, u = I._u+2.*PI*k;
755 Interval I2( std::cos(l), std::cos(u) );
759 Interval I2( -1., 1. );
762 Interval I2( std::min(std::cos(l), std::cos(u)), 1. );
766 Interval I2( std::cos(u), std::cos(l) );
770 Interval I2( -1., 1. );
773 Interval I2( -1., std::max(std::cos(l), std::cos(u)));
779 (
const Interval &I )
781 return cos( I - PI/2. );
788 const int k = std::ceil(-0.5-I._l/PI);
789 const double l = I._l+PI*k, u = I._u+PI*k;
791 Interval I2( std::tan(l), std::tan(u) );
797 (
const Interval &I )
800 Interval I2( std::acos(I._u), std::acos(I._l) );
806 (
const Interval &I )
809 Interval I2( std::asin(I._l), std::asin(I._u) );
815 (
const Interval &I )
817 Interval I2( std::atan(I._l), std::atan(I._u) );
823 (
const Interval &I )
825 if( I._l >= 0 )
return Interval(1.);
826 else if( I._u < 0 )
return Interval(0.);
827 return Interval(0.,1.);
832 (
const Interval &I )
839 ( std::ostream&out,
const Interval&I)
841 out << std::right << std::scientific << std::setprecision(Interval::options.DISPLAY_DIGITS);
842 out <<
"[ " << std::setw(Interval::options.DISPLAY_DIGITS+7) << I.l()
843 <<
" : " << std::setw(Interval::options.DISPLAY_DIGITS+7) << I.u() <<
" ]";
849 ( Interval &XIY,
const Interval &X,
const Interval &Y )
851 if( X._l > Y._u || Y._l > X._u )
return false;
852 XIY._l = std::max( X._l, Y._l );
853 XIY._u = std::min( X._u, Y._u );
859 (
const Interval&I1,
const Interval&I2 )
861 return( I1._l == I2._l && I1._u == I2._u );
866 (
const Interval&I1,
const Interval&I2 )
868 return( I1._l != I2._l || I1._u != I2._u );
873 (
const Interval&I1,
const Interval&I2 )
875 return( I1._l >= I2._l && I1._u <= I2._u );
880 (
const Interval&I1,
const Interval&I2 )
882 return( I1._l <= I2._l && I1._u >= I2._u );
887 (
const Interval&I1,
const Interval&I2 )
889 return( I1._l > I2._l && I1._u < I2._u );
894 (
const Interval&I1,
const Interval&I2 )
896 return( I1._l < I2._l && I1._u > I2._u );
910 static T point(
const double c ) {
return T(c); }
911 static T zeroone() {
return T(0.,1.); }
912 static void I(
T& x,
const T&y) { x = y; }
913 static double l(
const T& x) {
return x.
l(); }
914 static double u(
const T& x) {
return x.
u(); }
915 static double abs (
const T& x) {
return mc::abs(x); }
916 static double mid (
const T& x) {
return mc::mid(x); }
917 static double diam(
const T& x) {
return mc::diam(x); }
918 static T inv (
const T& x) {
return mc::inv(x); }
919 static T sqr (
const T& x) {
return mc::sqr(x); }
920 static T sqrt(
const T& x) {
return mc::sqrt(x); }
921 static T log (
const T& x) {
return mc::log(x); }
922 static T xlog(
const T& x) {
return mc::xlog(x); }
923 static T fabs(
const T& x) {
return mc::fabs(x); }
924 static T exp (
const T& x) {
return mc::exp(x); }
925 static T sin (
const T& x) {
return mc::sin(x); }
926 static T cos (
const T& x) {
return mc::cos(x); }
927 static T tan (
const T& x) {
return mc::tan(x); }
928 static T asin(
const T& x) {
return mc::asin(x); }
929 static T acos(
const T& x) {
return mc::acos(x); }
930 static T atan(
const T& x) {
return mc::atan(x); }
931 static T erf (
const T& x) {
return mc::erf(x); }
932 static T erfc(
const T& x) {
return mc::erfc(x); }
933 static T fstep(
const T& x) {
return mc::fstep(x); }
934 static T bstep(
const T& x) {
return mc::bstep(x); }
935 static T hull(
const T& x,
const T& y) {
return mc::hull(x,y); }
936 static T min (
const T& x,
const T& y) {
return mc::min(x,y); }
937 static T max (
const T& x,
const T& y) {
return mc::max(x,y); }
938 static T arh (
const T& x,
const double k) {
return mc::arh(x,k); }
939 template <
typename X,
typename Y>
static T pow(
const X& x,
const Y& y) {
return mc::pow(x,y); }
940 static T monomial (
const unsigned int n,
const T* x,
const int* k) {
return mc::monomial(n,x,k); }
941 static bool inter(
T& xIy,
const T& x,
const T& y) {
return mc::inter(xIy,x,y); }
942 static bool eq(
const T& x,
const T& y) {
return x==y; }
943 static bool ne(
const T& x,
const T& y) {
return x!=y; }
944 static bool lt(
const T& x,
const T& y) {
return x<y; }
945 static bool le(
const T& x,
const T& y) {
return x<=y; }
946 static bool gt(
const T& x,
const T& y) {
return x>y; }
947 static bool ge(
const T& x,
const T& y) {
return x>=y; }
int ierr()
Return error flag.
Definition: interval.hpp:350
void u(const double ub)
Set upper bound to ub
Definition: interval.hpp:415
std::string what()
Return error description.
Definition: interval.hpp:352
const double & u() const
Return upper bound.
Definition: interval.hpp:404
Log with negative values in range.
Definition: interval.hpp:341
Inverse cosine with values outside of [-1,1] range.
Definition: interval.hpp:343
~Interval()
Destructor.
Definition: interval.hpp:395
unsigned int DISPLAY_DIGITS
Number of digits displayed with << operator (default=5)
Definition: interval.hpp:330
Square-root with nonpositive values in range.
Definition: interval.hpp:342
Options()
Constructor.
Definition: interval.hpp:326
Interval()
Default constructor (needed for arrays of mc::Interval elements)
Definition: interval.hpp:376
Inverse with zero in range.
Definition: interval.hpp:340
TYPE
Enumeration type for mc::Interval exceptions.
Definition: interval.hpp:338
Exceptions of mc::Interval.
Definition: interval.hpp:334
void l(const double lb)
Set lower bound to lb
Definition: interval.hpp:410
Exceptions(TYPE ierr)
Constructor for error flag ierr
Definition: interval.hpp:348
Inverse sine with values outside of [-1,1] range.
Definition: interval.hpp:344
Tangent with values , with , in range.
Definition: interval.hpp:345
C++ class for (non-verified) interval bounding of factorable function.
Definition: interval.hpp:129
const double & l() const
Return lower bound.
Definition: interval.hpp:399
C++ structure to allow usage of various template parameters in the types mc::McCormick, mc::TModel, mc::TVar, and mc::SpecBnd of MC++ _ Specialization of this structure is required for the template parameters can be found in the header files defining the types mc::McCormick, mc::TModel, mc::TVar, and mc::SpecBnd.
Definition: mcop.hpp:13
Options of mc::Interval.
Definition: interval.hpp:323
Division by zero.
Definition: interval.hpp:339