// #define GINAC_RA_OPENINTERVAL_DEBUG /** * Implementation of the class OpenInterval. * *@author Ulrich Loup *@since 2010-08-03 *@version 2010-09-22 * * Notation is following http://www.possibility.com/Cpp/CppCodingStandard.html. */ #include "OpenInterval.h" #include "operators.h" namespace GiNaC { GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(OpenInterval, basic, print_func(&OpenInterval::do_print)) ////////////////////////// // Con- and destructors // ////////////////////////// OpenInterval::OpenInterval() : mpLeft(new numeric(0)), mpRight(new numeric(0)) { setflag(status_flags::expanded); } OpenInterval::OpenInterval(const numeric& n) : mpLeft(new numeric(n-1)), mpRight(new numeric(n+1)) { setflag(status_flags::expanded); } OpenInterval::OpenInterval(const numeric& l, const numeric& r) throw(invalid_argument) : mpLeft(new numeric(l)), mpRight(new numeric(r)) { if(l > r) throw invalid_argument("OpenInterval::OpenInterval: Specified bounds do not define an interval."); setflag(status_flags::expanded); } OpenInterval::OpenInterval(const OpenInterval& i) : mpLeft(new numeric(i.Left())), mpRight(new numeric(i.Right())) { setflag(status_flags::expanded); } OpenInterval::~OpenInterval() { delete mpLeft; delete mpRight; } /////////////// // Selectors // /////////////// void OpenInterval::setBounds(const numeric& l, const numeric& r) throw(invalid_argument) { if(l > r) throw invalid_argument("OpenInterval::OpenInterval: Specified bounds do not define an interval."); *mpLeft = l; *mpRight = r; } const numeric& OpenInterval::Left() const { return *mpLeft; } const numeric& OpenInterval::Right() const { return *mpRight; } ///////////////////////// // Methods from basic // ///////////////////////// int OpenInterval::compare_same_type(const basic& o) const { const OpenInterval& oi = static_cast(o); if(this->isEqual(oi)) return 0; if(this->isLess(oi)) return -1; // if(this->isGreater(oi)) // last case return 1; } bool OpenInterval::is_equal_same_type(const basic& o) const { const OpenInterval& oi = static_cast(o); return this->isEqual(oi); } void OpenInterval::do_print(const print_context& c, unsigned level) const { c.s << ']' << *mpLeft << ", " << *mpRight << '['; } ex OpenInterval::eval(int level) const { return this->hold(); // set the evaluated flag } /////////////// // Operators // /////////////// const bool OpenInterval::operator==(const OpenInterval& o) const { return this->isEqual(o); } const bool OpenInterval::operator!=(const OpenInterval& o) const { return !this->isEqual(o); } const bool OpenInterval::operator<=(const OpenInterval& o) const { return this->isLess(o); } const bool OpenInterval::operator>=(const OpenInterval& o) const { return this->isGreater(o); } //////////////// // Operations // //////////////// const bool OpenInterval::isZero() const { return *mpLeft == numeric(0) && *mpRight == numeric(0); } const bool OpenInterval::isNormalized() const { return *mpLeft > numeric(0) || *mpRight < numeric(0) || ( *mpLeft == numeric(0) && *mpRight == numeric(0) ); } const bool OpenInterval::contains(const numeric& n) const { return *mpLeft < n && *mpRight > n; } /////////////////////////// // Arithmetic Operations // /////////////////////////// const OpenInterval& OpenInterval::add_dyn(const OpenInterval& o) const { return static_cast((new OpenInterval(*mpLeft + *o.mpLeft, *mpRight + *o.mpRight))->setflag(status_flags::dynallocated)); } const OpenInterval& OpenInterval::minus_dyn() const { return static_cast((new OpenInterval( - *mpRight, - *mpLeft ))->setflag(status_flags::dynallocated)); } const OpenInterval& OpenInterval::mul_dyn(const OpenInterval& o) const { numeric min = *mpLeft * *o.mpLeft; numeric max = min; numeric next = *mpLeft * *o.mpRight; if(next < min) min = next; else if(max != next) max = next; next = *mpRight * *o.mpLeft; if(next < min) min = next; else if(next > max) max = next; next = *mpRight * *o.mpRight; if(next < min) min = next; else if(next > max) max = next; return static_cast((new OpenInterval(min, max))->setflag(status_flags::dynallocated)); } /////////////////////////// // Relational Operations // /////////////////////////// inline const bool OpenInterval::isEqual(const OpenInterval& o) const { return (*mpLeft==*o.mpLeft && *mpRight==*o.mpRight); // exact same bounds } inline const bool OpenInterval::isLess(const OpenInterval& o) const { /* -----]------------[------------ <= * ----------]------------[------- holds. */ return (*mpLeft<=*o.mpLeft); // only compare left bounds } inline const bool OpenInterval::isGreater(const OpenInterval& o) const { /* ----------]------------[------- >= * -----]------------[------------ holds. */ return (*mpRight>=*o.mpRight); // only compare right bounds } } // namespace GiNaC