From 53cd2b6a5447ae5d59bcd47dc7d7b54087ff4b93 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 8 Apr 2016 11:22:37 +0530 Subject: [PATCH 01/13] Added Infinity class --- .gitignore | 3 ++ symengine/CMakeLists.txt | 3 +- symengine/constants.cpp | 3 ++ symengine/constants.h | 4 ++- symengine/derivative.cpp | 6 ++++ symengine/infinity.cpp | 63 ++++++++++++++++++++++++++++++++++ symengine/infinity.h | 73 ++++++++++++++++++++++++++++++++++++++++ symengine/printer.cpp | 12 +++++++ symengine/printer.h | 1 + symengine/type_codes.inc | 1 + symengine/visitor.h | 1 + 11 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 symengine/infinity.cpp create mode 100644 symengine/infinity.h diff --git a/.gitignore b/.gitignore index a7be0241a5..37cc3569c2 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,9 @@ symengine/symengine_config.h symengine/utilities/teuchos/Teuchos_config.h symengine/python/symengine/lib/config.pxi +# Folder Customisation in Mac +*.DS_Store + # Python build files build* *__pycache__* diff --git a/symengine/CMakeLists.txt b/symengine/CMakeLists.txt index ae6e14f32d..82b733a3d1 100644 --- a/symengine/CMakeLists.txt +++ b/symengine/CMakeLists.txt @@ -43,6 +43,7 @@ set(SRC parser.cpp mp_wrapper.cpp sets.cpp + infinity.cpp ) if (WITH_MPFR) @@ -74,7 +75,7 @@ set(HEADERS visitor.h eval_double.h diophantine.h cwrapper.h printer.h real_double.h eval_mpfr.h eval_arb.h eval_mpc.h complex_double.h series_visitor.h real_mpfr.h complex_mpc.h type_codes.inc lambda_double.h series.h series_piranha.h - basic-methods.inc series_flint.h series_generic.h sets.h + basic-methods.inc series_flint.h series_generic.h sets.h infinity.h ) # Configure SymEngine using our CMake options: diff --git a/symengine/constants.cpp b/symengine/constants.cpp index df0c71e5d1..f4a8b4c564 100644 --- a/symengine/constants.cpp +++ b/symengine/constants.cpp @@ -43,6 +43,9 @@ RCP I = Complex::from_two_nums(*zero, *one); RCP pi = constant("pi"); RCP E = constant("E"); RCP EulerGamma = constant("EulerGamma"); +RCP Infinity = constant("+oo"); +RCP NegativeInfinity = constant("-oo"); +RCP ComplexInfinity = constant("zoo"); // Global variables declared in functions.cpp // Look over https://github.com/sympy/symengine/issues/272 diff --git a/symengine/constants.h b/symengine/constants.h index 2f19bb65c4..3074ea2b6a 100644 --- a/symengine/constants.h +++ b/symengine/constants.h @@ -65,7 +65,9 @@ extern RCP I; extern RCP pi; extern RCP E; extern RCP EulerGamma; - +// extern RCP Infinity; +// extern RCP NegativeInfinity; +// extern RCP ComplexInfinity; } // SymEngine #endif diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 5a9bb5445f..9b17cbaafd 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace SymEngine { @@ -517,6 +518,11 @@ class DiffImplementation return self.diff_impl(x); } + static RCP diff(const Infinity &self, + const RCP &x) { + throw std::runtime_error("Derivative doesn't exist."); + } + static RCP diff(const Beta &self, const RCP &x) { RCP beta_arg0 = self.get_args()[0]; diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp new file mode 100644 index 0000000000..57c30297ab --- /dev/null +++ b/symengine/infinity.cpp @@ -0,0 +1,63 @@ +#include + +namespace SymEngine +{ + +Infinity::Infinity() +{ + _direction = integer(1); +} + +Infinity::Infinity(const RCP &direction) +{ + _direction = direction; + SYMENGINE_ASSERT(is_canonical(_direction)); +} + +Infinity::Infinity(const int val) +{ + _direction = integer(val); + SYMENGINE_ASSERT(is_canonical(_direction)); +} + +RCP Infinity::from_number(const RCP &num) +{ + return make_rcp(num); +} + +RCP Infinity::from_int(const int val) +{ + return make_rcp(val); +} + +bool Infinity::is_canonical(const RCP &num) const +{ + if(is_a(*num) || is_a(*num)) + throw std::runtime_error("Not implemented for all directions"); + + return true; +} + +std::size_t Infinity::__hash__() const +{ + std::size_t seed = INFINITY; + hash_combine(seed, *_direction); + return seed; +} + +bool Infinity::is_unsigned_infinity() const +{ + return _direction->is_zero(); +} + +bool Infinity::is_plus_infinity() const +{ + return _direction->is_positive(); +} + +bool Infinity::is_negative_infinity() const +{ + return _direction->is_negative(); +} + +} //SymEngine diff --git a/symengine/infinity.h b/symengine/infinity.h new file mode 100644 index 0000000000..27b9670d13 --- /dev/null +++ b/symengine/infinity.h @@ -0,0 +1,73 @@ +/** + * \file infinity.h + * + **/ + +#ifndef SYMENGINE_INFINITY_H +#define SYMENGINE_INFINITY_H + +#include +#include +#include +#include + +namespace SymEngine +{ + +/** This class holds "infinity" + * It includes a direction (like -infinity). + **/ +class Infinity : public Basic +{ + RCP _direction; + +public: + IMPLEMENT_TYPEID(INFINITY) + //! Constructors + + //! Default Constructor gives +infinity(direction = +1) + Infinity(); + //! Constructs Infinity using the sign of `_direction` + Infinity(const RCP &direction); + Infinity(const int val); + static RCP from_number(const RCP &num); + //! Constructs Infinity using sign of `val` + static RCP from_int(const int val); + + //! \return true if canonical + bool is_canonical(const RCP &num) const; + //! \return size of the hash + std::size_t __hash__() const; + + /*! Equality comparator + * \param o - Object to be compared with + * \return whether the 2 objects are equal + * */ + // Implement these + bool __eq__(const Basic &o) const{return true;} + int compare(const Basic &o) const{return 0;} + + virtual vec_basic get_args() const + { + return {_direction}; + } + + inline RCP get_direction() const + { + return _direction; + } + + inline RCP infinity() + { + return make_rcp(); + } + bool is_unsigned_infinity() const; + bool is_plus_infinity() const; + bool is_negative_infinity() const; + + // const infinity & operator *= (const Basic& rhs); + // const infinity & operator += (const Basic& rhs); +}; + +} //SymEngine +#endif diff --git a/symengine/printer.cpp b/symengine/printer.cpp index 3fe3b17023..660c5ab7bd 100644 --- a/symengine/printer.cpp +++ b/symengine/printer.cpp @@ -28,6 +28,18 @@ void StrPrinter::bvisit(const Symbol &x) str_ = x.get_name(); } +void StrPrinter::bvisit(const Infinity &x) +{ + std::ostringstream s; + if (x.is_negative()) + s << "-oo"; + else if (x.is_positive()) + s << "+oo"; + else + s << "zoo"; + str_ = s.str(); +} + void StrPrinter::bvisit(const Integer &x) { std::ostringstream s; diff --git a/symengine/printer.h b/symengine/printer.h index a68e617f4a..35110e5c61 100644 --- a/symengine/printer.h +++ b/symengine/printer.h @@ -170,6 +170,7 @@ class StrPrinter : public BaseVisitor void bvisit(const Add &x); void bvisit(const Mul &x); void bvisit(const Pow &x); + void bvisit(const Infinity &x); void bvisit(const UnivariateIntPolynomial &x); void bvisit(const UnivariatePolynomial &x); #ifdef HAVE_SYMENGINE_PIRANHA diff --git a/symengine/type_codes.inc b/symengine/type_codes.inc index 138614df30..8f2fd84cf0 100644 --- a/symengine/type_codes.inc +++ b/symengine/type_codes.inc @@ -26,6 +26,7 @@ SYMENGINE_ENUM(INTERVAL, Interval) SYMENGINE_ENUM(MUL, Mul) SYMENGINE_ENUM(ADD, Add) SYMENGINE_ENUM(POW, Pow) +SYMENGINE_ENUM(INFINITY, Infinity) SYMENGINE_ENUM(UNIVARIATEINTPOLYNOMIAL, UnivariateIntPolynomial) SYMENGINE_ENUM(UNIVARIATEPOLYNOMIAL, UnivariatePolynomial) SYMENGINE_ENUM(UNIVARIATESERIES, UnivariateSeries) diff --git a/symengine/visitor.h b/symengine/visitor.h index 7dba8515ba..f0fc7c7b64 100644 --- a/symengine/visitor.h +++ b/symengine/visitor.h @@ -26,6 +26,7 @@ #include #include #include +#include namespace SymEngine { From 6c899b65b3e12ee7b2b670e709fce9c796431c8d Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 8 Apr 2016 19:46:03 +0530 Subject: [PATCH 02/13] Changed Infinity to Infinit --- symengine/constants.cpp | 6 ++--- symengine/derivative.cpp | 2 +- symengine/infinity.cpp | 47 ++++++++++++++++++++++++++++++---------- symengine/infinity.h | 28 ++++++++++++------------ symengine/printer.cpp | 6 ++--- symengine/printer.h | 2 +- symengine/type_codes.inc | 2 +- 7 files changed, 58 insertions(+), 35 deletions(-) diff --git a/symengine/constants.cpp b/symengine/constants.cpp index f4a8b4c564..9ec5cfa754 100644 --- a/symengine/constants.cpp +++ b/symengine/constants.cpp @@ -43,9 +43,9 @@ RCP I = Complex::from_two_nums(*zero, *one); RCP pi = constant("pi"); RCP E = constant("E"); RCP EulerGamma = constant("EulerGamma"); -RCP Infinity = constant("+oo"); -RCP NegativeInfinity = constant("-oo"); -RCP ComplexInfinity = constant("zoo"); +// RCP Infinity = constant("+oo"); +// RCP NegativeInfinity = constant("-oo"); +// RCP ComplexInfinity = constant("zoo"); // Global variables declared in functions.cpp // Look over https://github.com/sympy/symengine/issues/272 diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 9b17cbaafd..5af1e8a1ac 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -518,7 +518,7 @@ class DiffImplementation return self.diff_impl(x); } - static RCP diff(const Infinity &self, + static RCP diff(const Infinit &self, const RCP &x) { throw std::runtime_error("Derivative doesn't exist."); } diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 57c30297ab..2fbd98b34b 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -1,36 +1,37 @@ #include +#include namespace SymEngine { -Infinity::Infinity() +Infinit::Infinit() { _direction = integer(1); } -Infinity::Infinity(const RCP &direction) +Infinit::Infinit(const RCP &direction) { _direction = direction; SYMENGINE_ASSERT(is_canonical(_direction)); } -Infinity::Infinity(const int val) +Infinit::Infinit(const int val) { _direction = integer(val); SYMENGINE_ASSERT(is_canonical(_direction)); } -RCP Infinity::from_number(const RCP &num) +RCP Infinit::from_number(const RCP &num) { - return make_rcp(num); + return make_rcp(num); } -RCP Infinity::from_int(const int val) +RCP Infinit::from_int(const int val) { - return make_rcp(val); + return make_rcp(val); } -bool Infinity::is_canonical(const RCP &num) const +bool Infinit::is_canonical(const RCP &num) const { if(is_a(*num) || is_a(*num)) throw std::runtime_error("Not implemented for all directions"); @@ -38,24 +39,46 @@ bool Infinity::is_canonical(const RCP &num) const return true; } -std::size_t Infinity::__hash__() const +std::size_t Infinit::__hash__() const { std::size_t seed = INFINITY; hash_combine(seed, *_direction); return seed; } -bool Infinity::is_unsigned_infinity() const +bool Infinit::__eq__(const Basic &o) const +{ + if(eq(*_direction, *zero)) + return false; + + if (is_a(o)) + { + const Infinit &s = static_cast(o); + if(eq(*_direction, *(s.get_direction()))) + return true; + } + + return false; +} + +int Infinit::compare(const Basic &o) const +{ + SYMENGINE_ASSERT(is_a(o)) + const Infinit &s = static_cast(o); + return _direction->compare(*(s.get_direction())); +} + +bool Infinit::is_unsigned_infinity() const { return _direction->is_zero(); } -bool Infinity::is_plus_infinity() const +bool Infinit::is_positive_infinity() const { return _direction->is_positive(); } -bool Infinity::is_negative_infinity() const +bool Infinit::is_negative_infinity() const { return _direction->is_negative(); } diff --git a/symengine/infinity.h b/symengine/infinity.h index 27b9670d13..17fc9fa40e 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -17,22 +17,22 @@ namespace SymEngine /** This class holds "infinity" * It includes a direction (like -infinity). **/ -class Infinity : public Basic +class Infinit : public Basic { RCP _direction; public: - IMPLEMENT_TYPEID(INFINITY) + IMPLEMENT_TYPEID(INFINIT) //! Constructors //! Default Constructor gives +infinity(direction = +1) - Infinity(); - //! Constructs Infinity using the sign of `_direction` - Infinity(const RCP &direction); - Infinity(const int val); - static RCP from_number(const RCP &num); - //! Constructs Infinity using sign of `val` - static RCP from_int(const int val); + Infinit(); + //! Constructs Infinit using the sign of `_direction` + Infinit(const RCP &direction); + Infinit(const int val); + static RCP from_number(const RCP &num); + //! Constructs Infinit using sign of `val` + static RCP from_int(const int val); //! \return true if canonical bool is_canonical(const RCP &num) const; @@ -44,8 +44,8 @@ class Infinity : public Basic * \return whether the 2 objects are equal * */ // Implement these - bool __eq__(const Basic &o) const{return true;} - int compare(const Basic &o) const{return 0;} + bool __eq__(const Basic &o) const; + int compare(const Basic &o) const; virtual vec_basic get_args() const { @@ -57,12 +57,12 @@ class Infinity : public Basic return _direction; } - inline RCP infinity() + inline RCP infinity() { - return make_rcp(); + return make_rcp(1); } bool is_unsigned_infinity() const; - bool is_plus_infinity() const; + bool is_positive_infinity() const; bool is_negative_infinity() const; // const infinity & operator *= (const Basic& rhs); diff --git a/symengine/printer.cpp b/symengine/printer.cpp index 660c5ab7bd..b2c8af625a 100644 --- a/symengine/printer.cpp +++ b/symengine/printer.cpp @@ -28,12 +28,12 @@ void StrPrinter::bvisit(const Symbol &x) str_ = x.get_name(); } -void StrPrinter::bvisit(const Infinity &x) +void StrPrinter::bvisit(const Infinit &x) { std::ostringstream s; - if (x.is_negative()) + if (x.is_negative_infinity()) s << "-oo"; - else if (x.is_positive()) + else if (x.is_positive_infinity()) s << "+oo"; else s << "zoo"; diff --git a/symengine/printer.h b/symengine/printer.h index 35110e5c61..842ab38a84 100644 --- a/symengine/printer.h +++ b/symengine/printer.h @@ -170,7 +170,7 @@ class StrPrinter : public BaseVisitor void bvisit(const Add &x); void bvisit(const Mul &x); void bvisit(const Pow &x); - void bvisit(const Infinity &x); + void bvisit(const Infinit &x); void bvisit(const UnivariateIntPolynomial &x); void bvisit(const UnivariatePolynomial &x); #ifdef HAVE_SYMENGINE_PIRANHA diff --git a/symengine/type_codes.inc b/symengine/type_codes.inc index 8f2fd84cf0..e5f6260dfc 100644 --- a/symengine/type_codes.inc +++ b/symengine/type_codes.inc @@ -26,7 +26,7 @@ SYMENGINE_ENUM(INTERVAL, Interval) SYMENGINE_ENUM(MUL, Mul) SYMENGINE_ENUM(ADD, Add) SYMENGINE_ENUM(POW, Pow) -SYMENGINE_ENUM(INFINITY, Infinity) +SYMENGINE_ENUM(INFINIT, SymEngine::Infinit) SYMENGINE_ENUM(UNIVARIATEINTPOLYNOMIAL, UnivariateIntPolynomial) SYMENGINE_ENUM(UNIVARIATEPOLYNOMIAL, UnivariatePolynomial) SYMENGINE_ENUM(UNIVARIATESERIES, UnivariateSeries) From a3554fb72e9ed8b6b5d43e7f2190fd432eff92f3 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 8 Apr 2016 21:50:30 +0530 Subject: [PATCH 03/13] Added add and mul member functions --- symengine/constants.cpp | 7 ++--- symengine/constants.h | 8 +++--- symengine/derivative.cpp | 2 +- symengine/infinity.cpp | 57 ++++++++++++++++++++++++++++++++++++++-- symengine/infinity.h | 37 +++++++++++++++++++++++--- symengine/type_codes.inc | 2 +- 6 files changed, 99 insertions(+), 14 deletions(-) diff --git a/symengine/constants.cpp b/symengine/constants.cpp index 9ec5cfa754..4643877279 100644 --- a/symengine/constants.cpp +++ b/symengine/constants.cpp @@ -43,9 +43,10 @@ RCP I = Complex::from_two_nums(*zero, *one); RCP pi = constant("pi"); RCP E = constant("E"); RCP EulerGamma = constant("EulerGamma"); -// RCP Infinity = constant("+oo"); -// RCP NegativeInfinity = constant("-oo"); -// RCP ComplexInfinity = constant("zoo"); + +// RCP Inf = Infinit::from_int(1); +// RCP NegInf = Infinit::from_int(-1); +// RCP ComplexInf = Infinit::from_int(0); // Global variables declared in functions.cpp // Look over https://github.com/sympy/symengine/issues/272 diff --git a/symengine/constants.h b/symengine/constants.h index 3074ea2b6a..d353b870a7 100644 --- a/symengine/constants.h +++ b/symengine/constants.h @@ -65,9 +65,11 @@ extern RCP I; extern RCP pi; extern RCP E; extern RCP EulerGamma; -// extern RCP Infinity; -// extern RCP NegativeInfinity; -// extern RCP ComplexInfinity; + +//Infinit +// extern RCP Inf; +// extern RCP NegInf; +// extern RCP ComplexInf; } // SymEngine #endif diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 5af1e8a1ac..31a0d68985 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -520,7 +520,7 @@ class DiffImplementation static RCP diff(const Infinit &self, const RCP &x) { - throw std::runtime_error("Derivative doesn't exist."); + return zero; } static RCP diff(const Beta &self, const RCP &x) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 2fbd98b34b..d8c7dda1ee 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -1,5 +1,4 @@ #include -#include namespace SymEngine { @@ -48,7 +47,7 @@ std::size_t Infinit::__hash__() const bool Infinit::__eq__(const Basic &o) const { - if(eq(*_direction, *zero)) + if(is_unsigned_infinity()) return false; if (is_a(o)) @@ -83,4 +82,58 @@ bool Infinit::is_negative_infinity() const return _direction->is_negative(); } +RCP Infinit::add(const Number &other) const +{ + if (is_unsigned_infinity()) + throw std::runtime_error("NaN not yet implemented."); + + if (is_positive_infinity()) + { + if (is_a(other)) + { + const Infinit &s = static_cast(other); + + if(s.is_positive_infinity()) + return make_rcp(+1); //Think about what to do with direction + else + throw std::runtime_error("NaN not yet implemented."); + } + else + return make_rcp(+1); + } + else + { + if (is_a(other)) + { + const Infinit &s = static_cast(other); + + if (s.is_negative_infinity()) + return make_rcp(-1); //Think about what to do with direction + else + throw std::runtime_error("NaN not yet implemented."); + } + else + return make_rcp(-1); + } +} + +RCP Infinit::mul(const Number &other) const +{ + if(is_a(other)) + { + const Infinit &s = static_cast(other); + + return make_rcp(this->_direction->mul(*(s._direction))); + } + else + { + if(other.is_positive()) + return make_rcp(this->_direction); + else if(other.is_negative()) + return make_rcp(this->_direction->mul(*minus_one)); + else + throw std::runtime_error("NaN not yet implemented."); + } +} + } //SymEngine diff --git a/symengine/infinity.h b/symengine/infinity.h index 17fc9fa40e..a74c4c0574 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -17,7 +17,7 @@ namespace SymEngine /** This class holds "infinity" * It includes a direction (like -infinity). **/ -class Infinit : public Basic +class Infinit : public Number { RCP _direction; @@ -52,21 +52,50 @@ class Infinit : public Basic return {_direction}; } + //! \return `true` if `0` + bool is_zero() const { return false; } + //! \return `true` if `1` + bool is_one() const { return false; } + //! \return `true` if `-1` + bool is_minus_one() const { return false; } + //! \return `true` if integer + bool is_integer() const { return false; } + //! \return `true` if symbol + bool is_symbol() const { return false; } + //! \return `true` if mul + bool is_mul() const { return false; } + //! \return `true` if pow + bool is_pow() const { return false; } + inline RCP get_direction() const { return _direction; } - inline RCP infinity() + inline RCP infinit() { return make_rcp(1); } + bool is_unsigned_infinity() const; bool is_positive_infinity() const; bool is_negative_infinity() const; - // const infinity & operator *= (const Basic& rhs); - // const infinity & operator += (const Basic& rhs); + bool is_positive() const + { + return is_positive_infinity(); + } + + bool is_negative() const + { + return is_negative_infinity(); + } + + // Think about it again + RCP add(const Number &other) const; + RCP mul(const Number &other) const; + RCP pow(const Number &other) const{return zero;} + RCP rpow(const Number &other) const{return zero;} }; } //SymEngine diff --git a/symengine/type_codes.inc b/symengine/type_codes.inc index e5f6260dfc..33cc6d45fb 100644 --- a/symengine/type_codes.inc +++ b/symengine/type_codes.inc @@ -26,7 +26,7 @@ SYMENGINE_ENUM(INTERVAL, Interval) SYMENGINE_ENUM(MUL, Mul) SYMENGINE_ENUM(ADD, Add) SYMENGINE_ENUM(POW, Pow) -SYMENGINE_ENUM(INFINIT, SymEngine::Infinit) +SYMENGINE_ENUM(INFINIT, Infinit) SYMENGINE_ENUM(UNIVARIATEINTPOLYNOMIAL, UnivariateIntPolynomial) SYMENGINE_ENUM(UNIVARIATEPOLYNOMIAL, UnivariatePolynomial) SYMENGINE_ENUM(UNIVARIATESERIES, UnivariateSeries) From 8b20c669accefe1af7d21e2b1d922fc828f96f09 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Tue, 12 Apr 2016 22:54:58 +0530 Subject: [PATCH 04/13] Removed unecessary functions. Refactored add function --- symengine/infinity.cpp | 53 +++++++++++++++++++++--------------------- symengine/infinity.h | 24 ++++++++----------- 2 files changed, 37 insertions(+), 40 deletions(-) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index d8c7dda1ee..932f09f284 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -20,6 +20,12 @@ Infinit::Infinit(const int val) SYMENGINE_ASSERT(is_canonical(_direction)); } +Infinit::Infinit(const Infinit &inf) +{ + _direction = inf.get_direction(); + SYMENGINE_ASSERT(is_canonical(_direction)) +} + RCP Infinit::from_number(const RCP &num) { return make_rcp(num); @@ -27,6 +33,7 @@ RCP Infinit::from_number(const RCP &num) RCP Infinit::from_int(const int val) { + SYMENGINE_ASSERT(val >= -1 && val <= 1) return make_rcp(val); } @@ -84,37 +91,26 @@ bool Infinit::is_negative_infinity() const RCP Infinit::add(const Number &other) const { - if (is_unsigned_infinity()) - throw std::runtime_error("NaN not yet implemented."); + if(not is_a(other)) + return make_rcp(*this); + + const Infinit &s = static_cast(other); - if (is_positive_infinity()) + if(not eq(*s.get_direction(), *_direction)) { - if (is_a(other)) - { - const Infinit &s = static_cast(other); - - if(s.is_positive_infinity()) - return make_rcp(+1); //Think about what to do with direction - else - throw std::runtime_error("NaN not yet implemented."); - } + if (is_unsigned_infinity() or s.is_unsigned_infinity()) + throw std::runtime_error("Indeterminate Expression: `unsigned_infinity +- infinity` encountered"); else - return make_rcp(+1); + throw std::runtime_error("Indeterminate Expression: `infinity +- infinity` encountered. Directions don't match"); } else - { - if (is_a(other)) - { - const Infinit &s = static_cast(other); - - if (s.is_negative_infinity()) - return make_rcp(-1); //Think about what to do with direction - else - throw std::runtime_error("NaN not yet implemented."); - } - else - return make_rcp(-1); - } + return make_rcp(*this); +} + + +RCP Infinit::sub(const Number &other) const +{ + return this->add(*other.mul(*minus_one)); } RCP Infinit::mul(const Number &other) const @@ -136,4 +132,9 @@ RCP Infinit::mul(const Number &other) const } } +// RCP Infinit::pow(const Number &other) const +// { + +// } + } //SymEngine diff --git a/symengine/infinity.h b/symengine/infinity.h index a74c4c0574..2aabf503f9 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -30,6 +30,8 @@ class Infinit : public Number //! Constructs Infinit using the sign of `_direction` Infinit(const RCP &direction); Infinit(const int val); + //! Copy Constructor + Infinit(const Infinit &inf); static RCP from_number(const RCP &num); //! Constructs Infinit using sign of `val` static RCP from_int(const int val); @@ -53,19 +55,11 @@ class Infinit : public Number } //! \return `true` if `0` - bool is_zero() const { return false; } + inline bool is_zero() const { return false; } //! \return `true` if `1` - bool is_one() const { return false; } + inline bool is_one() const { return false; } //! \return `true` if `-1` - bool is_minus_one() const { return false; } - //! \return `true` if integer - bool is_integer() const { return false; } - //! \return `true` if symbol - bool is_symbol() const { return false; } - //! \return `true` if mul - bool is_mul() const { return false; } - //! \return `true` if pow - bool is_pow() const { return false; } + inline bool is_minus_one() const { return false; } inline RCP get_direction() const { @@ -74,26 +68,28 @@ class Infinit : public Number inline RCP infinit() { - return make_rcp(1); + return make_rcp(); } bool is_unsigned_infinity() const; bool is_positive_infinity() const; bool is_negative_infinity() const; - bool is_positive() const + inline bool is_positive() const { return is_positive_infinity(); } - bool is_negative() const + inline bool is_negative() const { return is_negative_infinity(); } // Think about it again RCP add(const Number &other) const; + RCP sub(const Number &other) const; RCP mul(const Number &other) const; + RCP div(const Number &other) const{return zero;} RCP pow(const Number &other) const{return zero;} RCP rpow(const Number &other) const{return zero;} }; From 27ef888fa57e09bd3d44bd55cd7ce15202e4d001 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Tue, 12 Apr 2016 23:37:31 +0530 Subject: [PATCH 05/13] Added constants Inf, NegIng, ComplexInf --- symengine/constants.cpp | 9 +++++---- symengine/constants.h | 3 ++- symengine/infinity.cpp | 9 ++++++++- symengine/infinity.h | 6 +++--- 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/symengine/constants.cpp b/symengine/constants.cpp index 4643877279..e368983874 100644 --- a/symengine/constants.cpp +++ b/symengine/constants.cpp @@ -1,9 +1,10 @@ #include -#include #include +#include #include #include #include +#include namespace SymEngine { @@ -44,9 +45,9 @@ RCP pi = constant("pi"); RCP E = constant("E"); RCP EulerGamma = constant("EulerGamma"); -// RCP Inf = Infinit::from_int(1); -// RCP NegInf = Infinit::from_int(-1); -// RCP ComplexInf = Infinit::from_int(0); +RCP Inf = Infinit::from_int(1); +RCP NegInf = Infinit::from_int(-1); +RCP ComplexInf = Infinit::from_int(0); // Global variables declared in functions.cpp // Look over https://github.com/sympy/symengine/issues/272 diff --git a/symengine/constants.h b/symengine/constants.h index d353b870a7..0d18991fe3 100644 --- a/symengine/constants.h +++ b/symengine/constants.h @@ -9,6 +9,7 @@ #include #include +//#include #include #include @@ -66,7 +67,7 @@ extern RCP pi; extern RCP E; extern RCP EulerGamma; -//Infinit +//Infinity // extern RCP Inf; // extern RCP NegInf; // extern RCP ComplexInf; diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 932f09f284..b67b87996e 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -1,4 +1,5 @@ #include +#include namespace SymEngine { @@ -115,6 +116,9 @@ RCP Infinit::sub(const Number &other) const RCP Infinit::mul(const Number &other) const { + if(is_a(other)) + throw std::runtime_error("Multiplation with Complex not implemented"); + if(is_a(other)) { const Infinit &s = static_cast(other); @@ -128,10 +132,13 @@ RCP Infinit::mul(const Number &other) const else if(other.is_negative()) return make_rcp(this->_direction->mul(*minus_one)); else - throw std::runtime_error("NaN not yet implemented."); + throw std::runtime_error("Indeterminate Expression: `0 * Infinity` encountered"); } } +RCP Infinit::div(const Number &other) const {return zero;} +RCP Infinit::pow(const Number &other) const {return zero;} +RCP Infinit::rpow(const Number &other) const {return zero;} // RCP Infinit::pow(const Number &other) const // { diff --git a/symengine/infinity.h b/symengine/infinity.h index 2aabf503f9..08209a8386 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -89,9 +89,9 @@ class Infinit : public Number RCP add(const Number &other) const; RCP sub(const Number &other) const; RCP mul(const Number &other) const; - RCP div(const Number &other) const{return zero;} - RCP pow(const Number &other) const{return zero;} - RCP rpow(const Number &other) const{return zero;} + RCP div(const Number &other) const; + RCP pow(const Number &other) const; + RCP rpow(const Number &other) const; }; } //SymEngine From cd97ed9898e032442d8462de22ab5f5d3a4b78b1 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 15 Apr 2016 01:44:24 +0530 Subject: [PATCH 06/13] Allow only +1,0,-1 as directions --- symengine/infinity.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index b67b87996e..dd964a2d2c 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -43,7 +43,10 @@ bool Infinit::is_canonical(const RCP &num) const if(is_a(*num) || is_a(*num)) throw std::runtime_error("Not implemented for all directions"); - return true; + if(num->is_one() || num->is_zero() || num->is_minus_one()) + return true; + + return false; } std::size_t Infinit::__hash__() const From 020e9af0d00ad7f308b5b3525138369c15258852 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 15 Apr 2016 03:16:05 +0530 Subject: [PATCH 07/13] Added some tests. Construct infinity function in SymEngine namespace --- .gitignore | 1 + symengine/constants.h | 2 +- symengine/derivative.cpp | 3 +- symengine/infinity.cpp | 151 +++++++++++---------- symengine/infinity.h | 115 +++++++++------- symengine/tests/basic/CMakeLists.txt | 4 + symengine/tests/basic/test_infinity.cpp | 53 ++++++++ symengine/tests/printing/test_printing.cpp | 15 ++ 8 files changed, 220 insertions(+), 124 deletions(-) create mode 100644 symengine/tests/basic/test_infinity.cpp diff --git a/.gitignore b/.gitignore index 37cc3569c2..e16ad8bd60 100644 --- a/.gitignore +++ b/.gitignore @@ -79,6 +79,7 @@ symengine/tests/eval/test_lambda_double symengine/tests/expression/test_expression symengine/tests/basic/test_series_expansion_UP symengine/tests/basic/test_series_expansion_URatP +symengine/tests/basic/test_infinity # Benchmarks executables benchmarks/add1 diff --git a/symengine/constants.h b/symengine/constants.h index 0d18991fe3..8594de1269 100644 --- a/symengine/constants.h +++ b/symengine/constants.h @@ -67,7 +67,7 @@ extern RCP pi; extern RCP E; extern RCP EulerGamma; -//Infinity +// Infinity // extern RCP Inf; // extern RCP NegInf; // extern RCP ComplexInf; diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 31a0d68985..23a0554e67 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -519,7 +519,8 @@ class DiffImplementation } static RCP diff(const Infinit &self, - const RCP &x) { + const RCP &x) + { return zero; } diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index dd964a2d2c..8592a335ef 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -6,145 +6,152 @@ namespace SymEngine Infinit::Infinit() { - _direction = integer(1); + _direction = integer(1); } Infinit::Infinit(const RCP &direction) { - _direction = direction; - SYMENGINE_ASSERT(is_canonical(_direction)); + _direction = direction; + SYMENGINE_ASSERT(is_canonical(_direction)); } Infinit::Infinit(const int val) { - _direction = integer(val); - SYMENGINE_ASSERT(is_canonical(_direction)); + _direction = integer(val); + SYMENGINE_ASSERT(is_canonical(_direction)); } Infinit::Infinit(const Infinit &inf) { - _direction = inf.get_direction(); - SYMENGINE_ASSERT(is_canonical(_direction)) + _direction = inf.get_direction(); + SYMENGINE_ASSERT(is_canonical(_direction)) } -RCP Infinit::from_number(const RCP &num) +RCP Infinit::from_direction(const RCP &direction) { - return make_rcp(num); + return make_rcp(direction); } RCP Infinit::from_int(const int val) { - SYMENGINE_ASSERT(val >= -1 && val <= 1) - return make_rcp(val); + SYMENGINE_ASSERT(val >= -1 && val <= 1) + return make_rcp(val); } bool Infinit::is_canonical(const RCP &num) const { - if(is_a(*num) || is_a(*num)) - throw std::runtime_error("Not implemented for all directions"); + if (is_a(*num) || is_a(*num)) + throw std::runtime_error("Not implemented for all directions"); - if(num->is_one() || num->is_zero() || num->is_minus_one()) - return true; + if (num->is_one() || num->is_zero() || num->is_minus_one()) + return true; - return false; + return false; } std::size_t Infinit::__hash__() const { - std::size_t seed = INFINITY; - hash_combine(seed, *_direction); - return seed; + std::size_t seed = INFINITY; + hash_combine(seed, *_direction); + return seed; } bool Infinit::__eq__(const Basic &o) const { - if(is_unsigned_infinity()) - return false; + if (is_unsigned_infinity()) + return false; - if (is_a(o)) - { - const Infinit &s = static_cast(o); - if(eq(*_direction, *(s.get_direction()))) - return true; - } + if (is_a(o)) { + const Infinit &s = static_cast(o); + if (eq(*_direction, *(s.get_direction()))) + return true; + } - return false; + return false; } int Infinit::compare(const Basic &o) const { - SYMENGINE_ASSERT(is_a(o)) - const Infinit &s = static_cast(o); - return _direction->compare(*(s.get_direction())); + SYMENGINE_ASSERT(is_a(o)) + const Infinit &s = static_cast(o); + return _direction->compare(*(s.get_direction())); } bool Infinit::is_unsigned_infinity() const { - return _direction->is_zero(); + return _direction->is_zero(); } bool Infinit::is_positive_infinity() const { - return _direction->is_positive(); + return _direction->is_positive(); } bool Infinit::is_negative_infinity() const { - return _direction->is_negative(); + return _direction->is_negative(); } RCP Infinit::add(const Number &other) const { - if(not is_a(other)) - return make_rcp(*this); + if (not is_a(other)) + return make_rcp(*this); - const Infinit &s = static_cast(other); + const Infinit &s = static_cast(other); - if(not eq(*s.get_direction(), *_direction)) - { - if (is_unsigned_infinity() or s.is_unsigned_infinity()) - throw std::runtime_error("Indeterminate Expression: `unsigned_infinity +- infinity` encountered"); - else - throw std::runtime_error("Indeterminate Expression: `infinity +- infinity` encountered. Directions don't match"); - } - else - return make_rcp(*this); + if (not eq(*s.get_direction(), *_direction)) { + if (is_unsigned_infinity() or s.is_unsigned_infinity()) + throw std::runtime_error("Indeterminate Expression: " + "`unsigned_infinity +- infinity` " + "encountered"); + else + throw std::runtime_error("Indeterminate Expression: `infinity +- " + "infinity` encountered. Directions don't " + "match"); + } else + return make_rcp(*this); } - RCP Infinit::sub(const Number &other) const { - return this->add(*other.mul(*minus_one)); + return this->add(*other.mul(*minus_one)); } RCP Infinit::mul(const Number &other) const { - if(is_a(other)) - throw std::runtime_error("Multiplation with Complex not implemented"); - - if(is_a(other)) - { - const Infinit &s = static_cast(other); - - return make_rcp(this->_direction->mul(*(s._direction))); - } - else - { - if(other.is_positive()) - return make_rcp(this->_direction); - else if(other.is_negative()) - return make_rcp(this->_direction->mul(*minus_one)); - else - throw std::runtime_error("Indeterminate Expression: `0 * Infinity` encountered"); - } -} - -RCP Infinit::div(const Number &other) const {return zero;} -RCP Infinit::pow(const Number &other) const {return zero;} -RCP Infinit::rpow(const Number &other) const {return zero;} + if (is_a(other)) + throw std::runtime_error("Multiplation with Complex not implemented"); + + if (is_a(other)) { + const Infinit &s = static_cast(other); + + return make_rcp(this->_direction->mul(*(s._direction))); + } else { + if (other.is_positive()) + return make_rcp(this->_direction); + else if (other.is_negative()) + return make_rcp(this->_direction->mul(*minus_one)); + else + throw std::runtime_error( + "Indeterminate Expression: `0 * Infinity` encountered"); + } +} + +RCP Infinit::div(const Number &other) const +{ + return zero; +} +RCP Infinit::pow(const Number &other) const +{ + return zero; +} +RCP Infinit::rpow(const Number &other) const +{ + return zero; +} // RCP Infinit::pow(const Number &other) const // { // } -} //SymEngine +} // SymEngine diff --git a/symengine/infinity.h b/symengine/infinity.h index 08209a8386..590b276afa 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -19,29 +19,30 @@ namespace SymEngine **/ class Infinit : public Number { - RCP _direction; + RCP _direction; public: - IMPLEMENT_TYPEID(INFINIT) - //! Constructors - - //! Default Constructor gives +infinity(direction = +1) - Infinit(); - //! Constructs Infinit using the sign of `_direction` - Infinit(const RCP &direction); - Infinit(const int val); - //! Copy Constructor - Infinit(const Infinit &inf); - static RCP from_number(const RCP &num); - //! Constructs Infinit using sign of `val` - static RCP from_int(const int val); - - //! \return true if canonical - bool is_canonical(const RCP &num) const; - //! \return size of the hash - std::size_t __hash__() const; - - /*! Equality comparator + IMPLEMENT_TYPEID(INFINIT) + //! Constructors + + //! Default Constructor gives +infinity(direction = +1) + Infinit(); + //! Constructs Infinit using the sign of `_direction` + Infinit(const RCP &direction); + Infinit(const int val); + //! Copy Constructor + Infinit(const Infinit &inf); + static RCP + from_direction(const RCP &direction); + //! Constructs Infinit using sign of `val` + static RCP from_int(const int val); + + //! \return true if canonical + bool is_canonical(const RCP &num) const; + //! \return size of the hash + std::size_t __hash__() const; + + /*! Equality comparator * \param o - Object to be compared with * \return whether the 2 objects are equal * */ @@ -51,48 +52,62 @@ class Infinit : public Number virtual vec_basic get_args() const { - return {_direction}; + return {_direction}; } //! \return `true` if `0` - inline bool is_zero() const { return false; } + inline bool is_zero() const + { + return false; + } //! \return `true` if `1` - inline bool is_one() const { return false; } + inline bool is_one() const + { + return false; + } //! \return `true` if `-1` - inline bool is_minus_one() const { return false; } + inline bool is_minus_one() const + { + return false; + } inline RCP get_direction() const { - return _direction; + return _direction; + } + + bool is_unsigned_infinity() const; + bool is_positive_infinity() const; + bool is_negative_infinity() const; + + inline bool is_positive() const + { + return is_positive_infinity(); } - inline RCP infinit() + inline bool is_negative() const { - return make_rcp(); + return is_negative_infinity(); } - bool is_unsigned_infinity() const; - bool is_positive_infinity() const; - bool is_negative_infinity() const; - - inline bool is_positive() const - { - return is_positive_infinity(); - } - - inline bool is_negative() const - { - return is_negative_infinity(); - } - - // Think about it again - RCP add(const Number &other) const; - RCP sub(const Number &other) const; - RCP mul(const Number &other) const; - RCP div(const Number &other) const; - RCP pow(const Number &other) const; - RCP rpow(const Number &other) const; + // Think about it again + RCP add(const Number &other) const; + RCP sub(const Number &other) const; + RCP mul(const Number &other) const; + RCP div(const Number &other) const; + RCP pow(const Number &other) const; + RCP rpow(const Number &other) const; }; -} //SymEngine +inline RCP infinit(const int &n = 1) +{ + return make_rcp(n); +} + +inline RCP infinit(const RCP &direction) +{ + return make_rcp(direction); +} + +} // SymEngine #endif diff --git a/symengine/tests/basic/CMakeLists.txt b/symengine/tests/basic/CMakeLists.txt index 4c35204692..982292f26a 100644 --- a/symengine/tests/basic/CMakeLists.txt +++ b/symengine/tests/basic/CMakeLists.txt @@ -71,3 +71,7 @@ add_test(test_parser ${PROJECT_BINARY_DIR}/test_parser) add_executable(test_sets test_sets.cpp) target_link_libraries(test_sets symengine catch) add_test(test_sets ${PROJECT_BINARY_DIR}/test_sets) + +add_executable(test_infinity test_infinity.cpp) +target_link_libraries(test_infinity symengine catch) +add_test(test_infinity ${PROJECT_BINARY_DIR}/test_infinity) diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp new file mode 100644 index 0000000000..5492e13011 --- /dev/null +++ b/symengine/tests/basic/test_infinity.cpp @@ -0,0 +1,53 @@ +#include "catch.hpp" +#include + +#include +#include +#include + +using SymEngine::Basic; +using SymEngine::Number; +using SymEngine::Integer; +using SymEngine::integer; +using SymEngine::Rational; +using SymEngine::rational; +using SymEngine::one; +using SymEngine::zero; +using SymEngine::minus_one; +using SymEngine::RCP; +using SymEngine::Infinit; +using SymEngine::infinit; +using SymEngine::rcp_dynamic_cast; +using SymEngine::Complex; +using SymEngine::symbol; + +TEST_CASE("Constructors for Infinity", "[Infinity]") +{ + RCP r1 = rational(1, 1); + RCP rm1 = rational(-1, 1); + RCP r0 = rational(0, 1); + + RCP im1 = integer(-1); + RCP i0 = integer(0); + + RCP a = Infinit::from_direction(r1); + RCP b = Infinit::from_direction(rm1); + RCP c = Infinit::from_direction(r0); + + REQUIRE(a->__str__() == "+oo"); + REQUIRE(b->__str__() == "-oo"); + REQUIRE(c->__str__() == "zoo"); + + a = infinit(); + b = infinit(-1); + c = infinit(0); + + REQUIRE(a->__str__() == "+oo"); + REQUIRE(b->__str__() == "-oo"); + REQUIRE(c->__str__() == "zoo"); + + a = Infinit::from_int(1); + b = Infinit::from_direction(im1); + REQUIRE(a->__str__() == "+oo"); + REQUIRE(b->__str__() == "-oo"); +} \ No newline at end of file diff --git a/symengine/tests/printing/test_printing.cpp b/symengine/tests/printing/test_printing.cpp index 091b8c40d9..8f8276d615 100644 --- a/symengine/tests/printing/test_printing.cpp +++ b/symengine/tests/printing/test_printing.cpp @@ -16,6 +16,7 @@ #include #include #include +#include using SymEngine::RCP; using SymEngine::Basic; @@ -47,6 +48,8 @@ using SymEngine::StrPrinter; using SymEngine::Sin; using SymEngine::integer_class; using SymEngine::map_uint_mpz; +using SymEngine::Infinit; +using SymEngine::infinit; using namespace SymEngine::literals; @@ -327,6 +330,18 @@ TEST_CASE("test_univariate_polynomial(): printing", "[printing]") REQUIRE(p->__str__() == "-x**2 - 2*x - 1"); } +TEST_CASE("test_infinity(): printing", "[printing]") +{ + RCP a; + + a = infinit(1); + REQUIRE(a->__str__() == "+oo"); + a = infinit(-1); + REQUIRE(a->__str__() == "-oo"); + a = infinit(0); + REQUIRE(a->__str__() == "zoo"); +} + TEST_CASE("test_floats(): printing", "[printing]") { RCP p; From 2ab21639f9dbc5a2f6e30cb09e43afde81bbdcd4 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 15 Apr 2016 12:16:24 +0530 Subject: [PATCH 08/13] Inf, NegInf, ComplexInf work now. Added tests for same --- symengine/constants.cpp | 6 ++--- symengine/constants.h | 10 ++++---- symengine/derivative.cpp | 22 +++++++++--------- symengine/infinity.cpp | 4 +++- symengine/infinity.h | 2 -- symengine/tests/basic/test_infinity.cpp | 27 ++++++++++++++++++++++ symengine/tests/printing/test_printing.cpp | 18 +++++++-------- symengine/visitor.h | 24 +++++++++---------- 8 files changed, 70 insertions(+), 43 deletions(-) diff --git a/symengine/constants.cpp b/symengine/constants.cpp index e368983874..7871687ebc 100644 --- a/symengine/constants.cpp +++ b/symengine/constants.cpp @@ -1,10 +1,10 @@ +#include +#include #include #include -#include +#include #include -#include #include -#include namespace SymEngine { diff --git a/symengine/constants.h b/symengine/constants.h index 8594de1269..4317b9f181 100644 --- a/symengine/constants.h +++ b/symengine/constants.h @@ -8,9 +8,9 @@ #define SYMENGINE_CONSTANTS_H #include -#include -//#include +#include #include +#include #include namespace SymEngine @@ -68,9 +68,9 @@ extern RCP E; extern RCP EulerGamma; // Infinity -// extern RCP Inf; -// extern RCP NegInf; -// extern RCP ComplexInf; +extern RCP Inf; +extern RCP NegInf; +extern RCP ComplexInf; } // SymEngine #endif diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 23a0554e67..8bb7d405c5 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -1,19 +1,19 @@ -#include -#include #include -#include -#include +#include #include -#include -#include -#include -#include -#include -#include #include #include -#include +#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include namespace SymEngine { diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 8592a335ef..1675495379 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -1,5 +1,7 @@ -#include +#include +#include #include +#include namespace SymEngine { diff --git a/symengine/infinity.h b/symengine/infinity.h index 590b276afa..3ae7fdf32d 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -7,8 +7,6 @@ #define SYMENGINE_INFINITY_H #include -#include -#include #include namespace SymEngine diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index 5492e13011..fc989291dc 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -1,6 +1,7 @@ #include "catch.hpp" #include +#include #include #include #include @@ -20,6 +21,9 @@ using SymEngine::infinit; using SymEngine::rcp_dynamic_cast; using SymEngine::Complex; using SymEngine::symbol; +using SymEngine::Inf; +using SymEngine::NegInf; +using SymEngine::ComplexInf; TEST_CASE("Constructors for Infinity", "[Infinity]") { @@ -50,4 +54,27 @@ TEST_CASE("Constructors for Infinity", "[Infinity]") b = Infinit::from_direction(im1); REQUIRE(a->__str__() == "+oo"); REQUIRE(b->__str__() == "-oo"); + + Infinit inf = Infinit(); + REQUIRE(inf.__str__() == "+oo"); +} + +TEST_CASE("Hash Size for Infinity", "[Infinity]") +{ + RCP a = infinit(1); + RCP b = infinit(0); + + // REQUIRE(a->__hash__() == b->__hash__()); + // REQUIRE(a->__hash__() == infinit(1)->__hash__()); +} + +TEST_CASE("Infinity Constants", "[Infinity]") +{ + RCP a = Inf; + RCP b = NegInf; + RCP c = ComplexInf; + + REQUIRE(a->__str__() == "+oo"); + REQUIRE(b->__str__() == "-oo"); + REQUIRE(c->__str__() == "zoo"); } \ No newline at end of file diff --git a/symengine/tests/printing/test_printing.cpp b/symengine/tests/printing/test_printing.cpp index 8f8276d615..5939bae51d 100644 --- a/symengine/tests/printing/test_printing.cpp +++ b/symengine/tests/printing/test_printing.cpp @@ -1,22 +1,22 @@ #include "catch.hpp" #include +#include #include +#include +#include +#include +#include #include +#include #include -#include #include -#include -#include -#include -#include -#include +#include #include +#include #include -#include #include -#include -#include +#include using SymEngine::RCP; using SymEngine::Basic; diff --git a/symengine/visitor.h b/symengine/visitor.h index f0fc7c7b64..c837fc083e 100644 --- a/symengine/visitor.h +++ b/symengine/visitor.h @@ -6,27 +6,27 @@ #ifndef SYMENGINE_VISITOR_H #define SYMENGINE_VISITOR_H -#include #include -#include -#include -#include +#include +#include +#include +#include +#include #include -#include +#include #include +#include +#include +#include #include -#include -#include #include -#include #include -#include -#include #include -#include #include +#include +#include #include -#include +#include namespace SymEngine { From dc9b6162985eddf285d5ce2d64e4b08822d50301 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 15 Apr 2016 13:43:18 +0530 Subject: [PATCH 09/13] Fixed minor bug in __has__. Added more tests --- symengine/infinity.cpp | 6 ++--- symengine/tests/basic/test_infinity.cpp | 29 +++++++++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 1675495379..6ee5fe5e86 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -40,6 +40,7 @@ RCP Infinit::from_int(const int val) return make_rcp(val); } +//! Canonical when the direction is -1, 0 or 1. bool Infinit::is_canonical(const RCP &num) const { if (is_a(*num) || is_a(*num)) @@ -53,7 +54,7 @@ bool Infinit::is_canonical(const RCP &num) const std::size_t Infinit::__hash__() const { - std::size_t seed = INFINITY; + std::size_t seed = INFINIT; hash_combine(seed, *_direction); return seed; } @@ -65,8 +66,7 @@ bool Infinit::__eq__(const Basic &o) const if (is_a(o)) { const Infinit &s = static_cast(o); - if (eq(*_direction, *(s.get_direction()))) - return true; + return eq(*_direction, *(s.get_direction())); } return false; diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index fc989291dc..ecb50e6e69 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -20,7 +20,6 @@ using SymEngine::Infinit; using SymEngine::infinit; using SymEngine::rcp_dynamic_cast; using SymEngine::Complex; -using SymEngine::symbol; using SymEngine::Inf; using SymEngine::NegInf; using SymEngine::ComplexInf; @@ -64,8 +63,10 @@ TEST_CASE("Hash Size for Infinity", "[Infinity]") RCP a = infinit(1); RCP b = infinit(0); - // REQUIRE(a->__hash__() == b->__hash__()); - // REQUIRE(a->__hash__() == infinit(1)->__hash__()); + REQUIRE(not eq(*a, *b)); + REQUIRE(not(a->__hash__() == b->__hash__())); + REQUIRE(eq(*a, *infinit())); + REQUIRE(a->__hash__() == infinit(1)->__hash__()); } TEST_CASE("Infinity Constants", "[Infinity]") @@ -77,4 +78,24 @@ TEST_CASE("Infinity Constants", "[Infinity]") REQUIRE(a->__str__() == "+oo"); REQUIRE(b->__str__() == "-oo"); REQUIRE(c->__str__() == "zoo"); -} \ No newline at end of file +} + +TEST_CASE("Boolean tests for Infinity", "[Infinity") +{ + RCP a = Inf; + RCP b = NegInf; + RCP c = ComplexInf; + + REQUIRE((not a->is_zero() && not a->is_one() && not a->is_minus_one() + && not a->is_negative_infinity() && a->is_positive_infinity() + && not a->is_unsigned_infinity() && a->is_positive() + && not a->is_negative())); + REQUIRE((not b->is_zero() && not b->is_one() && not b->is_minus_one() + && b->is_negative_infinity() && not b->is_positive_infinity() + && not b->is_unsigned_infinity() && not b->is_positive() + && b->is_negative())); + REQUIRE((not c->is_zero() && not c->is_one() && not c->is_minus_one() + && not c->is_negative_infinity() && not c->is_positive_infinity() + && c->is_unsigned_infinity() && not c->is_positive() + && not c->is_negative())); +} From ea124655b0b6e659422ed755b09d82f0501ddfcc Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Fri, 15 Apr 2016 18:47:24 +0530 Subject: [PATCH 10/13] Added some test for __eq__, compare, get_args, get_direction --- symengine/infinity.cpp | 7 +++--- symengine/infinity.h | 6 ++--- symengine/tests/basic/test_infinity.cpp | 30 +++++++++++++++++-------- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 36e2404a44..75fccc6e2f 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -136,21 +136,20 @@ RCP Infinit::mul(const Number &other) const } } +// TODO RCP Infinit::div(const Number &other) const { return zero; } +// TODO RCP Infinit::pow(const Number &other) const { return zero; } +// TODO RCP Infinit::rpow(const Number &other) const { return zero; } -// RCP Infinit::pow(const Number &other) const -// { - -// } } // SymEngine diff --git a/symengine/infinity.h b/symengine/infinity.h index 12c62d3574..5bb2aa8341 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -92,9 +92,9 @@ class Infinit : public Number RCP add(const Number &other) const; RCP sub(const Number &other) const; RCP mul(const Number &other) const; - RCP div(const Number &other) const; //TODO - RCP pow(const Number &other) const; //TODO - RCP rpow(const Number &other) const; //TODO + RCP div(const Number &other) const; // TODO + RCP pow(const Number &other) const; // TODO + RCP rpow(const Number &other) const; // TODO }; inline RCP infinit(const int &n = 1) diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index ef6ead4607..2e67383169 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -1,13 +1,15 @@ #include "catch.hpp" #include -#include +#include #include #include #include +#include using SymEngine::Basic; using SymEngine::Number; +using SymEngine::is_a; using SymEngine::Integer; using SymEngine::integer; using SymEngine::Rational; @@ -89,15 +91,15 @@ TEST_CASE("Boolean tests for Infinity", "[Infinity]") REQUIRE((not a->is_zero() && not a->is_one() && not a->is_minus_one() && not a->is_negative_infinity() && a->is_positive_infinity() && not a->is_unsigned_infinity() && a->is_positive() - && not a->is_negative())); + && not a->is_negative() && is_a(*a))); REQUIRE((not b->is_zero() && not b->is_one() && not b->is_minus_one() && b->is_negative_infinity() && not b->is_positive_infinity() && not b->is_unsigned_infinity() && not b->is_positive() - && b->is_negative())); + && b->is_negative() && is_a(*b))); REQUIRE((not c->is_zero() && not c->is_one() && not c->is_minus_one() && not c->is_negative_infinity() && not c->is_positive_infinity() && c->is_unsigned_infinity() && not c->is_positive() - && not c->is_negative())); + && not c->is_negative() && is_a(*c))); } TEST_CASE("Comparing Infinitys", "[Infinity]") @@ -106,26 +108,36 @@ TEST_CASE("Comparing Infinitys", "[Infinity]") RCP b = NegInf; RCP c = ComplexInf; - REQUIRE(a.compare(*b) == 1); - REQUIRE(c.compare(*c) == 0); + REQUIRE(a->compare(*b) == 1); + REQUIRE(c->compare(*c) == 0); + REQUIRE(c->compare(*a) == -1); + REQUIRE(a->compare(*c) == 1); + REQUIRE(not c->__eq__(*a)); + REQUIRE(b->__eq__(*b)); } TEST_CASE("Checking arguments returned", "[Infinity]") { + RCP a = Inf; + RCP b = NegInf; + RCP c = ComplexInf; + REQUIRE(eq(*a->get_direction(), *one)); + REQUIRE(eq(*b->get_direction(), *minus_one)); + REQUIRE(eq(*c->get_direction(), *zero)); + REQUIRE(eq(*a->get_args()[0], *one)); + REQUIRE(eq(*b->get_args()[0], *minus_one)); + REQUIRE(eq(*c->get_args()[0], *zero)); } TEST_CASE("Adding to Infinity", "[Infinity]") { - } TEST_CASE("Subtracting from Infinity", "[Infinity]") { - } TEST_CASE("Multiplication with Infinity", "[Infinity]") { - } From 0055de79f6f24d89d8480bfbbe923e9477184da0 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Mon, 18 Apr 2016 19:27:07 +0530 Subject: [PATCH 11/13] Remove redundant derivative code.Added some tests. --- symengine/derivative.cpp | 7 ------- symengine/tests/basic/test_infinity.cpp | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/symengine/derivative.cpp b/symengine/derivative.cpp index 3ec7bb4a8b..cf251d1aba 100644 --- a/symengine/derivative.cpp +++ b/symengine/derivative.cpp @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -520,12 +519,6 @@ class DiffImplementation return self.diff_impl(x); } - static RCP diff(const Infinit &self, - const RCP &x) - { - return zero; - } - static RCP diff(const Beta &self, const RCP &x) { RCP beta_arg0 = self.get_args()[0]; diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index 2e67383169..7c02bd43fd 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -25,6 +25,8 @@ using SymEngine::Complex; using SymEngine::Inf; using SymEngine::NegInf; using SymEngine::ComplexInf; +using SymEngine::Symbol; +using SymEngine::symbol; TEST_CASE("Constructors for Infinity", "[Infinity]") { @@ -58,6 +60,10 @@ TEST_CASE("Constructors for Infinity", "[Infinity]") Infinit inf = Infinit(); REQUIRE(inf.__str__() == "+oo"); + + //! Checking copy constructor + Infinit inf2 = Infinit(*NegInf); + REQUIRE(inf2.__str__() == "-oo"); } TEST_CASE("Hash Size for Infinity", "[Infinity]") @@ -114,6 +120,7 @@ TEST_CASE("Comparing Infinitys", "[Infinity]") REQUIRE(a->compare(*c) == 1); REQUIRE(not c->__eq__(*a)); REQUIRE(b->__eq__(*b)); + REQUIRE(not c->__eq__(*zero)); } TEST_CASE("Checking arguments returned", "[Infinity]") @@ -130,6 +137,13 @@ TEST_CASE("Checking arguments returned", "[Infinity]") REQUIRE(eq(*c->get_args()[0], *zero)); } +TEST_CASE("Check Derivative", "[Infinity]") +{ + RCP x = symbol("x"); + RCP b = NegInf; + REQUIRE(eq(*b->diff(x), *zero)); +} + TEST_CASE("Adding to Infinity", "[Infinity]") { } From 7f0e1a0c8d72bbc23128430b04df956939d15ad9 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Tue, 19 Apr 2016 20:59:33 +0530 Subject: [PATCH 12/13] Removed redundant code.A Another minor change --- symengine/infinity.cpp | 11 +++-------- symengine/infinity.h | 1 - symengine/tests/basic/test_infinity.cpp | 1 + 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 75fccc6e2f..98f69ab5d2 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -94,7 +94,7 @@ bool Infinit::is_negative_infinity() const RCP Infinit::add(const Number &other) const { if (not is_a(other)) - return make_rcp(*this); + return rcp_from_this_cast(); const Infinit &s = static_cast(other); @@ -108,12 +108,7 @@ RCP Infinit::add(const Number &other) const "infinity` encountered. Directions don't " "match"); } else - return make_rcp(*this); -} - -RCP Infinit::sub(const Number &other) const -{ - return this->add(*other.mul(*minus_one)); + return rcp_from_this_cast(); } RCP Infinit::mul(const Number &other) const @@ -127,7 +122,7 @@ RCP Infinit::mul(const Number &other) const return make_rcp(this->_direction->mul(*(s._direction))); } else { if (other.is_positive()) - return make_rcp(this->_direction); + return rcp_from_this_cast(); else if (other.is_negative()) return make_rcp(this->_direction->mul(*minus_one)); else diff --git a/symengine/infinity.h b/symengine/infinity.h index 5bb2aa8341..f399863325 100644 --- a/symengine/infinity.h +++ b/symengine/infinity.h @@ -90,7 +90,6 @@ class Infinit : public Number // Think about it again RCP add(const Number &other) const; - RCP sub(const Number &other) const; RCP mul(const Number &other) const; RCP div(const Number &other) const; // TODO RCP pow(const Number &other) const; // TODO diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index 7c02bd43fd..ccba846a77 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -150,6 +150,7 @@ TEST_CASE("Adding to Infinity", "[Infinity]") TEST_CASE("Subtracting from Infinity", "[Infinity]") { + REQUIRE(eq(*Inf->sub(*NegInf), *Inf)); } TEST_CASE("Multiplication with Infinity", "[Infinity]") From 274808c2f98b8158faf2b7b5282749dfc444bd44 Mon Sep 17 00:00:00 2001 From: Akash Trehan Date: Thu, 21 Apr 2016 15:26:34 +0530 Subject: [PATCH 13/13] Removed bug in add. Added test cases for add and mul --- symengine/infinity.cpp | 4 +++ symengine/tests/basic/test_infinity.cpp | 45 +++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/symengine/infinity.cpp b/symengine/infinity.cpp index 98f69ab5d2..4b1753b8bc 100644 --- a/symengine/infinity.cpp +++ b/symengine/infinity.cpp @@ -107,6 +107,10 @@ RCP Infinit::add(const Number &other) const throw std::runtime_error("Indeterminate Expression: `infinity +- " "infinity` encountered. Directions don't " "match"); + } else if (is_unsigned_infinity()) { + throw std::runtime_error("Indeterminate Expression: " + "`unsigned_infinity +- unsigned infinity` " + "encountered"); } else return rcp_from_this_cast(); } diff --git a/symengine/tests/basic/test_infinity.cpp b/symengine/tests/basic/test_infinity.cpp index ccba846a77..5e27054cf8 100644 --- a/symengine/tests/basic/test_infinity.cpp +++ b/symengine/tests/basic/test_infinity.cpp @@ -27,6 +27,7 @@ using SymEngine::NegInf; using SymEngine::ComplexInf; using SymEngine::Symbol; using SymEngine::symbol; +using SymEngine::Complex; TEST_CASE("Constructors for Infinity", "[Infinity]") { @@ -64,6 +65,9 @@ TEST_CASE("Constructors for Infinity", "[Infinity]") //! Checking copy constructor Infinit inf2 = Infinit(*NegInf); REQUIRE(inf2.__str__() == "-oo"); + + RCP cx = Complex::from_two_nums(*integer(1), *integer(1)); + CHECK_THROWS_AS(Infinit::from_direction(cx), std::runtime_error); } TEST_CASE("Hash Size for Infinity", "[Infinity]") @@ -146,6 +150,19 @@ TEST_CASE("Check Derivative", "[Infinity]") TEST_CASE("Adding to Infinity", "[Infinity]") { + RCP a = Inf; + RCP b = NegInf; + RCP c = ComplexInf; + + RCP n1 = a->add(*one); + REQUIRE(n1->__str__() == "+oo"); + n1 = b->add(*b); + REQUIRE(n1->__str__() == "-oo"); + n1 = c->add(*minus_one); + REQUIRE(n1->__str__() == "zoo"); + CHECK_THROWS_AS(c->add(*c), std::runtime_error); + CHECK_THROWS_AS(c->add(*a), std::runtime_error); + CHECK_THROWS_AS(b->add(*a), std::runtime_error); } TEST_CASE("Subtracting from Infinity", "[Infinity]") @@ -155,4 +172,32 @@ TEST_CASE("Subtracting from Infinity", "[Infinity]") TEST_CASE("Multiplication with Infinity", "[Infinity]") { + RCP a = Inf; + RCP b = NegInf; + RCP c = ComplexInf; + + RCP n1 = b->mul(*integer(-10)); + REQUIRE(n1->__str__() == "+oo"); + n1 = c->mul(*integer(5)); + REQUIRE(n1->__str__() == "zoo"); + n1 = c->mul(*integer(-5)); + REQUIRE(n1->__str__() == "zoo"); + + RCP n2 = a->mul(*a); + REQUIRE(n2->__str__() == "+oo"); + n2 = b->mul(*a); + REQUIRE(n2->__str__() == "-oo"); + n2 = b->mul(*c); + REQUIRE(n2->__str__() == "zoo"); + n2 = b->mul(*b); + REQUIRE(n2->__str__() == "+oo"); + n2 = c->mul(*c); + REQUIRE(n2->__str__() == "zoo"); + + CHECK_THROWS_AS(a->mul(*zero), std::runtime_error); + CHECK_THROWS_AS(b->mul(*zero), std::runtime_error); + CHECK_THROWS_AS(c->mul(*zero), std::runtime_error); + + RCP cx = Complex::from_two_nums(*integer(1), *integer(1)); + CHECK_THROWS_AS(c->mul(*cx), std::runtime_error); }