564 lines
15 KiB
C++
564 lines
15 KiB
C++
#include "mp_interval.hpp"
|
|
|
|
// MACROS FOR MIN AND MAX
|
|
|
|
#define MIN(a,b) (((a) < (b))? (a) : (b))
|
|
#define MAX(a,b) (((a) > (b))? (a) : (b))
|
|
|
|
// DEFAULT CONSTRUCTOR
|
|
MPInterval::MPInterval (double op) {
|
|
mpfr_init_set_d (a, op, MPFR_RNDD);
|
|
mpfr_init_set_d (b, op, MPFR_RNDU);
|
|
}
|
|
// CONSTRUCTOR BY double ELEMENTS
|
|
MPInterval::MPInterval (double op1, double op2) {
|
|
mpfr_init_set_d (a, op1, MPFR_RNDD);
|
|
mpfr_init_set_d (b, op2, MPFR_RNDU);
|
|
}
|
|
// CONSTRUCTOR BY string VALUE
|
|
MPInterval::MPInterval (const char *op) {
|
|
mpfr_init_set_str (a, op, 10, MPFR_RNDD);
|
|
mpfr_init_set_str (b, op, 10, MPFR_RNDU);
|
|
}
|
|
// CONSTRUCTOR BY string PAIR OF VALUES
|
|
MPInterval::MPInterval (const char *op1, const char *op2) {
|
|
mpfr_init_set_str (a, op1, 10, MPFR_RNDD);
|
|
mpfr_init_set_str (b, op2, 10, MPFR_RNDU);
|
|
|
|
}
|
|
// CONSTRUCTOR BY mpfr ELEMENT
|
|
MPInterval::MPInterval (const mpfr_t op) {
|
|
mpfr_init_set (a, op, MPFR_RNDD);
|
|
mpfr_init_set (b, op, MPFR_RNDU);
|
|
}
|
|
// CONSTRUCTOR BY mpfr PAIR OF ELEMENTS
|
|
MPInterval::MPInterval (const mpfr_t op1, const mpfr_t op2) {
|
|
mpfr_init_set (a, op1, MPFR_RNDD);
|
|
mpfr_init_set (b, op2, MPFR_RNDU);
|
|
}
|
|
// CONSTRUCTOR BY double Invterval
|
|
MPInterval::MPInterval (const Interval &op) {
|
|
mpfr_init_set_d (a, op.a, MPFR_RNDD);
|
|
mpfr_init_set_d (b, op.b, MPFR_RNDU);
|
|
}
|
|
// COPY CONSTRUCTOR
|
|
MPInterval::MPInterval (const MPInterval &op) {
|
|
mpfr_init_set (a, op.a, MPFR_RNDD);
|
|
mpfr_init_set (b, op.b, MPFR_RNDU);
|
|
}
|
|
// DESTRUCTOR
|
|
MPInterval::~MPInterval () {
|
|
mpfr_clears (a, b, NULL);
|
|
}
|
|
|
|
|
|
|
|
int MPInterval::operator== (double op) const {
|
|
return (mpfr_cmp_d(this->a, op) == 0) && (mpfr_cmp_d(this->b, op) == 0);
|
|
}
|
|
int MPInterval::operator== (const Interval &op) const {
|
|
return (mpfr_cmp_d (this->a, op.a) == 0) && (mpfr_cmp_d (this->b, op.b) == 0);
|
|
}
|
|
int MPInterval::operator== (const MPInterval &op) const {
|
|
return (mpfr_cmp(this->a, op.a) == 0) && (mpfr_cmp(this->b, op.b) == 0);
|
|
}
|
|
int MPInterval::operator!= (double op) const {
|
|
return (mpfr_cmp_d(this->a, op) != 0) || (mpfr_cmp_d(this->b, op) != 0);
|
|
}
|
|
int MPInterval::operator!= (const Interval &op) const {
|
|
return (mpfr_cmp_d (this->a, op.a) != 0) || (mpfr_cmp_d (this->b, op.b) != 0);
|
|
}
|
|
int MPInterval::operator!= (const MPInterval &op) const {
|
|
return (mpfr_cmp(this->a, op.a) != 0) || (mpfr_cmp(this->a, op.b) != 0);
|
|
}
|
|
|
|
|
|
// ASSIGNMENT
|
|
MPInterval & MPInterval::operator= (const MPInterval &op) {
|
|
// CHECK WHETER WE ARE ASIGNING SOMETHING OVER ITSELF
|
|
if (this == &op) return (*this);
|
|
// UPDATE VALUES
|
|
mpfr_set (this->a, op.a, MPFR_RNDD);
|
|
mpfr_set (this->b, op.b, MPFR_RNDU);
|
|
return *this;
|
|
}
|
|
MPInterval & MPInterval::operator= (const Interval &op) {
|
|
// UPDATE VALUES
|
|
mpfr_set_d (this->a, op.a, MPFR_RNDD);
|
|
mpfr_set_d (this->b, op.b, MPFR_RNDU);
|
|
return *this;
|
|
}
|
|
MPInterval & MPInterval::operator= (const mpfr_t op) {
|
|
// UPDATE VALUES
|
|
mpfr_set (this->a, op, MPFR_RNDD);
|
|
mpfr_set (this->b, op, MPFR_RNDU);
|
|
return *this;
|
|
}
|
|
MPInterval & MPInterval::operator= (double op) {
|
|
// UPDATE VALUES
|
|
mpfr_set_d (this->a, op, MPFR_RNDD);
|
|
mpfr_set_d (this->b, op, MPFR_RNDU);
|
|
return *this;
|
|
}
|
|
|
|
|
|
// ARITHMETIC
|
|
|
|
// [a,b] + [c,d] = [a+c, b+d]
|
|
MPInterval MPInterval::operator+ (const MPInterval &op) const {
|
|
MPInterval rop (*this);
|
|
mpfr_add (rop.a, rop.a, op.a, MPFR_RNDD);
|
|
mpfr_add (rop.b, rop.b, op.b, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] + [c,d] = [a+c, b+d]
|
|
MPInterval MPInterval::operator+ (const Interval &op) const {
|
|
MPInterval rop (*this);
|
|
mpfr_add_d (rop.a, rop.a, op.a, MPFR_RNDD);
|
|
mpfr_add_d (rop.b, rop.b, op.b, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] + c = [a+c, b+c]
|
|
MPInterval MPInterval::operator+ (const mpfr_t op) const {
|
|
MPInterval rop (*this);
|
|
mpfr_add (rop.a, rop.a, op, MPFR_RNDD);
|
|
mpfr_add (rop.b, rop.b, op, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] + c = [a+c, b+c]
|
|
MPInterval MPInterval::operator+ (double op) const {
|
|
MPInterval rop (*this);
|
|
mpfr_add_d (rop.a, rop.a, op, MPFR_RNDD);
|
|
mpfr_add_d (rop.b, rop.b, op, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// CHANGE OF SIGN OF AN INTERVAL
|
|
// -[a,b] = [-b,a]
|
|
MPInterval MPInterval::operator- () const {
|
|
MPInterval rop;
|
|
mpfr_neg (rop.a, this->b, MPFR_RNDD);
|
|
mpfr_neg (rop.b, this->a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] - [c,d] = [a-d, b-c]
|
|
MPInterval MPInterval::operator- (const MPInterval &op) const {
|
|
MPInterval rop(*this);
|
|
mpfr_sub (rop.a, rop.a, op.b, MPFR_RNDD);
|
|
mpfr_sub (rop.b, rop.b, op.a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
// [a,b] - [c,d] = [a-d, b-c]
|
|
MPInterval MPInterval::operator- (const Interval &op) const {
|
|
MPInterval rop(*this);
|
|
mpfr_sub_d (rop.a, rop.a, op.b, MPFR_RNDD);
|
|
mpfr_sub_d (rop.b, rop.b, op.a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] - c = [a-c, b-c]
|
|
MPInterval MPInterval::operator- (const mpfr_t op) const {
|
|
MPInterval rop(*this);
|
|
mpfr_sub (rop.a, rop.a, op, MPFR_RNDD);
|
|
mpfr_sub (rop.b, rop.b, op, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b] - c = [a-c, b-c]
|
|
MPInterval MPInterval::operator- (double op) const {
|
|
MPInterval rop(*this);
|
|
mpfr_sub_d (rop.a, rop.a, op, MPFR_RNDD);
|
|
mpfr_sub_d (rop.b, rop.b, op, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]*[c,d] = [min(a*c,a*d,b*c,b*d), max(a*c,a*d,b*c,b*d)]
|
|
MPInterval MPInterval::operator* (const MPInterval &op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_mul (rop.a, this->a, op.a, MPFR_RNDD);
|
|
mpfr_mul (aux, this->a, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_mul (aux, this->b, op.a, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_mul (aux, this->b, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_mul (rop.b, this->a, op.a, MPFR_RNDU);
|
|
mpfr_mul (aux, this->a, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_mul (aux, this->b, op.a, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_mul (aux, this->b, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
|
|
}
|
|
|
|
// [a,b]*[c,d] = [min(a*c,a*d,b*c,b*d), max(a*c,a*d,b*c,b*d)]
|
|
MPInterval MPInterval::operator* (const Interval &op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_mul_d (rop.a, this->a, op.a, MPFR_RNDD);
|
|
mpfr_mul_d (aux, this->a, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_mul_d (aux, this->b, op.a, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_mul_d (aux, this->b, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_mul_d (rop.b, this->a, op.a, MPFR_RNDU);
|
|
mpfr_mul_d (aux, this->a, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_mul_d (aux, this->b, op.a, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_mul_d (aux, this->b, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
|
|
// [a,b]*c = [min(a*c,b*c), max(a*c,b*c)]
|
|
MPInterval MPInterval::operator* (const mpfr_t op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_mul (rop.a, this->a, op, MPFR_RNDD);
|
|
mpfr_mul (aux, this->b, op, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_mul (rop.b, this->a, op, MPFR_RNDU);
|
|
mpfr_mul (aux, this->b, op, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]*c = [min(a*c,b*c), max(a*c,b*c)]
|
|
MPInterval MPInterval::operator* (double op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_mul_d (rop.a, this->a, op, MPFR_RNDD);
|
|
mpfr_mul_d (aux, this->b, op, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_mul_d (rop.b, this->a, op, MPFR_RNDU);
|
|
mpfr_mul_d (aux, this->b, op, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
|
|
|
|
// [a,b]/[c,d] = [min(a/c,a/d,b/c,b/d), max(a/c,a/d,b/c,b/d)]
|
|
MPInterval MPInterval::operator/ (const MPInterval &op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_div (rop.a, this->a, op.a, MPFR_RNDD);
|
|
mpfr_div (aux, this->a, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_div (aux, this->b, op.a, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_div (aux, this->b, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_div (rop.b, this->a, op.a, MPFR_RNDU);
|
|
mpfr_div (aux, this->a, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_div (aux, this->b, op.a, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_div (aux, this->b, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]/[c,d] = [min(a/c,a/d,b/c,b/d), max(a/c,a/d,b/c,b/d)]
|
|
MPInterval MPInterval::operator/ (const Interval &op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_div_d (rop.a, this->a, op.a, MPFR_RNDD);
|
|
mpfr_div_d (aux, this->a, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_div_d (aux, this->b, op.a, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_div_d (aux, this->b, op.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_div_d (rop.b, this->a, op.a, MPFR_RNDU);
|
|
mpfr_div_d (aux, this->a, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_div_d (aux, this->b, op.a, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_div_d (aux, this->b, op.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]/c = [min(a/c,b/c), max(a/c,b/c)]
|
|
MPInterval MPInterval::operator/ (const mpfr_t op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_div (rop.a, this->a, op, MPFR_RNDD);
|
|
mpfr_div (aux, this->b, op, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_div (rop.b, this->a, op, MPFR_RNDU);
|
|
mpfr_div (aux, this->b, op, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]/c = [min(a/c,b/c), max(a/c,b/c)]
|
|
MPInterval MPInterval::operator/ (double op) const {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_div_d (rop.a, this->a, op, MPFR_RNDD);
|
|
mpfr_div_d (aux, this->b, op, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_div_d (rop.b, this->a, op, MPFR_RNDU);
|
|
mpfr_div_d (aux, this->b, op, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
|
|
|
|
// MISC
|
|
// [a,b] ^ -1 = [1/b, 1/a]
|
|
MPInterval MPInterval::inverse () const {
|
|
MPInterval rop;
|
|
|
|
// CHECK WHETER 0 IS IN THE INTERVAL
|
|
if (this->containsZero ()) {
|
|
mpfr_si_div (rop.a, 1, this->b, MPFR_RNDD);
|
|
mpfr_si_div (rop.b, 1, this->a, MPFR_RNDU);
|
|
} else {
|
|
mpfr_set_nan (rop.a);
|
|
mpfr_set_nan (rop.b);
|
|
}
|
|
|
|
return rop;
|
|
|
|
}
|
|
|
|
// CHECK WHETER 0 IS IN THE INTERVAL
|
|
int MPInterval::containsZero () const {
|
|
if (mpfr_cmp_si (this->a, 0) <= 0 && mpfr_cmp_si (this->b, 0) >= 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
// CHECK WHETER A VALUE IS IN THE INTERVAL
|
|
int MPInterval::contains (double op) const {
|
|
if (mpfr_cmp_d (this->a, op) <= 0 && mpfr_cmp_d (this->b, op) >= 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
// CHECK WHETER A VALUE IS IN THE INTERVAL
|
|
int MPInterval::contains (const mpfr_t op) const {
|
|
if (mpfr_cmp (this->a, op) <= 0 && mpfr_cmp (this->b, op) >= 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
// CHECKS WHETER THE INTERVAL [a,b] IS SUBSET OF ANOTHER [c,d].
|
|
// c<a<b<d
|
|
int MPInterval::subset (const MPInterval &op) const {
|
|
if (mpfr_cmp (this->a, op.a) > 0 && mpfr_cmp (this->b, op.b) < 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
// CHECKS WHETER THE INTERVAL [a,b] IS SUBSET OF ANOTHER [c,d].
|
|
// c<a<b<d
|
|
int MPInterval::subset (const Interval &op) const {
|
|
if (mpfr_cmp_d (this->a, op.a) > 0 && mpfr_cmp_d (this->b, op.b) < 0)
|
|
return 1;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
// EXTERNAL FUNCTIONS
|
|
// OVERLOAD OUTPUT STREAM
|
|
std::ostream & operator<< (std::ostream &output, const MPInterval &op) {
|
|
mpfr_exp_t exponent;
|
|
char *string = mpfr_get_str (NULL, &exponent, 10, 0, op.a, MPFR_RNDD);
|
|
if (mpfr_signbit (op.a) != 0)
|
|
output << "[-" << string[1] << "." << string+2 << "e" << exponent-1 << ", ";
|
|
else
|
|
output << "[" << string[0] << "." << string+1 << "e" << exponent-1 << ", ";
|
|
mpfr_free_str (string);
|
|
|
|
string = mpfr_get_str (NULL, &exponent, 10, 0, op.b, MPFR_RNDU);
|
|
if (mpfr_signbit (op.b) != 0)
|
|
output << "-" << string[1] << "." << string+2 << "e" << exponent-1 << "]";
|
|
else
|
|
output << string[0] << "." << string+1 << "e" << exponent-1 << "]";
|
|
mpfr_free_str (string);
|
|
return output;
|
|
}
|
|
|
|
// c + [a,b] = [a+c, b+c] = [a,b] + c
|
|
MPInterval operator+ (double op1, const MPInterval &op2) {
|
|
return op2 + op1;
|
|
}
|
|
// c + [a,b] = [a+c, b+c] = [a,b] + c
|
|
MPInterval operator+ (const mpfr_t op1, const MPInterval &op2) {
|
|
return op2 + op1;
|
|
}
|
|
// [c,d] + [a,b] = [a+c, b+c] = [a,b] + [c,d]
|
|
MPInterval operator+ (const Interval &op1, const MPInterval &op2) {
|
|
return op2 + op1;
|
|
}
|
|
|
|
// c - [a,b] = [c-b, c-a]
|
|
MPInterval operator- (double op1, const MPInterval &op2) {
|
|
MPInterval rop;
|
|
mpfr_d_sub (rop.a, op1, op2.b, MPFR_RNDD);
|
|
mpfr_d_sub (rop.b, op1, op2.a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// c - [a,b] = [c-b, c-a]
|
|
MPInterval operator- (const mpfr_t op1, const MPInterval &op2) {
|
|
MPInterval rop;
|
|
mpfr_sub (rop.a, op1, op2.b, MPFR_RNDD);
|
|
mpfr_sub (rop.b, op1, op2.a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// [c,d]- [a,b] = [c-b, d-a]
|
|
MPInterval operator- (const Interval &op1, const MPInterval &op2) {
|
|
MPInterval rop;
|
|
mpfr_d_sub (rop.a, op1.a, op2.b, MPFR_RNDD);
|
|
mpfr_d_sub (rop.b, op1.b, op2.a, MPFR_RNDU);
|
|
return rop;
|
|
}
|
|
|
|
// c*[a,b] = [a,b]*c
|
|
MPInterval operator* (double op1, const MPInterval &op2) {
|
|
return op2 * op1;
|
|
}
|
|
|
|
// c*[a,b] = [a,b]*c
|
|
MPInterval operator* (const mpfr_t op1, const MPInterval &op2) {
|
|
return op2 * op1;
|
|
}
|
|
// [c,d] * [a,b] = [a,b] * [c,d]
|
|
MPInterval operator* (const Interval &op1, const MPInterval &op2) {
|
|
return op2 * op1;
|
|
}
|
|
|
|
|
|
// c / [a,b] = [min (c/a, c/b), max (c/a, c/b)]
|
|
MPInterval operator/ (double op1, const MPInterval &op2) {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_d_div (rop.a, op1, op2.a, MPFR_RNDD);
|
|
mpfr_d_div (aux, op1, op2.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_d_div (rop.b, op1, op2.a, MPFR_RNDU);
|
|
mpfr_d_div (aux, op1, op2.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// c / [a,b] = [min (c/a, c/b), max (c/a, c/b)]
|
|
MPInterval operator/ (const mpfr_t op1, const MPInterval &op2) {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_div (rop.a, op1, op2.a, MPFR_RNDD);
|
|
mpfr_div (aux, op1, op2.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_div (rop.b, op1, op2.a, MPFR_RNDU);
|
|
mpfr_div (aux, op1, op2.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
}
|
|
|
|
// [a,b]/[c,d] = [min(a/c,a/d,b/c,b/d), max(a/c,a/d,b/c,b/d)]
|
|
MPInterval operator/ (const Interval &op1, const MPInterval &op2) {
|
|
mpfr_t aux;
|
|
mpfr_init (aux);
|
|
MPInterval rop;
|
|
|
|
mpfr_d_div (rop.a, op1.a, op2.a, MPFR_RNDD);
|
|
mpfr_d_div (aux, op1.a, op2.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_d_div (aux, op1.b, op2.a, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
mpfr_d_div (aux, op1.b, op2.b, MPFR_RNDD);
|
|
mpfr_min (rop.a, rop.a, aux, MPFR_RNDD);
|
|
|
|
|
|
mpfr_d_div (rop.b, op1.a, op2.a, MPFR_RNDU);
|
|
mpfr_d_div (aux, op1.a, op2.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_d_div (aux, op1.b, op2.a, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
mpfr_d_div (aux, op1.b, op2.b, MPFR_RNDU);
|
|
mpfr_max (rop.b, rop.b, aux, MPFR_RNDU);
|
|
|
|
mpfr_clear (aux);
|
|
return rop;
|
|
|
|
}
|