SymEngine::Rational Class Reference

Rational Class. More...

#include <rational.h>

+ Inheritance diagram for SymEngine::Rational:
+ Collaboration diagram for SymEngine::Rational:

Public Member Functions

void accept (Visitor &v) const override
 
void accept (EvalRealDoubleVisitorFinal &v) const override
 
 Rational (rational_class &&_i)
 Constructor of Rational class.
 
hash_t __hash__ () const override
 
bool __eq__ (const Basic &o) const override
 
int compare (const Basic &o) const override
 
bool is_canonical (const rational_class &i) const
 
const rational_class & as_rational_class () const
 Convert to rational_class.
 
bool is_zero () const override
 
bool is_one () const override
 
bool is_minus_one () const override
 
bool is_int () const
 
bool is_positive () const override
 
bool is_negative () const override
 
bool is_complex () const override
 
RCP< const Rationalneg () const
 
bool is_perfect_power (bool is_expected=false) const override
 
bool nth_root (const Ptr< RCP< const Number >> &, unsigned long n) const override
 
RCP< const Numberaddrat (const Rational &other) const
 
RCP< const Numberaddrat (const Integer &other) const
 
RCP< const Numbersubrat (const Rational &other) const
 
RCP< const Numbersubrat (const Integer &other) const
 
RCP< const Numberrsubrat (const Integer &other) const
 
RCP< const Numbermulrat (const Rational &other) const
 
RCP< const Numbermulrat (const Integer &other) const
 
RCP< const Numberdivrat (const Rational &other) const
 
RCP< const Numberdivrat (const Integer &other) const
 
RCP< const Numberrdivrat (const Integer &other) const
 
RCP< const Numberpowrat (const Integer &other) const
 
RCP< const Basicpowrat (const Rational &other) const
 
RCP< const Basicrpowrat (const Integer &other) const
 
RCP< const Numberadd (const Number &other) const override
 Converts the param other appropriately and then calls addrat
 
RCP< const Numbersub (const Number &other) const override
 Converts the param other appropriately and then calls subrat
 
RCP< const Numberrsub (const Number &other) const override
 Converts the param other appropriately and then calls rsubrat
 
RCP< const Numbermul (const Number &other) const override
 Converts the param other appropriately and then calls mulrat
 
RCP< const Numberdiv (const Number &other) const override
 Converts the param other appropriately and then calls divrat
 
RCP< const Numberrdiv (const Number &other) const override
 Converts the param other appropriately and then calls rdivrat
 
RCP< const Numberpow (const Number &other) const override
 Converts the param other appropriately and then calls powrat
 
RCP< const Numberrpow (const Number &other) const override
 
RCP< const Integerget_num () const
 
RCP< const Integerget_den () const
 
- Public Member Functions inherited from SymEngine::Number
virtual RCP< const Basicconjugate () const
 
virtual bool is_exact () const
 return true if the number is an exact representation
 
bool is_exact_zero () const
 
virtual Evaluateget_eval () const
 Get Evaluate singleton to evaluate numerically.
 
vec_basic get_args () const override
 Returns the list of arguments.
 
- Public Member Functions inherited from SymEngine::Basic
TypeID get_type_code () const
 
 Basic ()
 Constructor.
 
 Basic (const Basic &)=delete
 Delete the copy constructor and assignment.
 
Basicoperator= (const Basic &)=delete
 Assignment operator in continuation with above.
 
 Basic (Basic &&)=delete
 Delete the move constructor and assignment.
 
Basicoperator= (Basic &&)=delete
 Assignment operator in continuation with above.
 
hash_t hash () const
 
bool __neq__ (const Basic &o) const
 true if this is not equal to o. More...
 
int __cmp__ (const Basic &o) const
 Comparison operator.
 
std::string __str__ () const
 
std::string dumps () const
 Returns a string of the instance serialized.
 
RCP< const Basicsubs (const map_basic_basic &subs_dict) const
 Substitutes 'subs_dict' into 'self'.
 
RCP< const Basicxreplace (const map_basic_basic &subs_dict) const
 
virtual RCP< const Basicexpand_as_exp () const
 expands the special function in terms of exp function
 
RCP< const Basicdiff (const RCP< const Symbol > &x, bool cache=true) const
 
- Public Member Functions inherited from SymEngine::EnableRCPFromThis< Basic >
RCP< Basicrcp_from_this ()
 Get RCP<T> pointer to self (it will cast the pointer to T)
 
RCP< const Basicrcp_from_this () const
 Get RCP<const T> pointer to self (it will cast the pointer to const T)
 
RCP< const T2 > rcp_from_this_cast () const
 Get RCP<T2> pointer to self (it will cast the pointer to T2)
 
unsigned int use_count () const
 

Static Public Member Functions

static RCP< const Numberfrom_mpq (const rational_class &i)
 
static RCP< const Numberfrom_mpq (rational_class &&i)
 
static RCP< const Numberfrom_two_ints (const Integer &n, const Integer &d)
 
static RCP< const Numberfrom_two_ints (const long n, const long d)
 
- Static Public Member Functions inherited from SymEngine::Basic
static RCP< const Basicloads (const std::string &)
 Creates an instance of a serialized string.
 

Static Public Attributes

static const TypeID type_code_id = SYMENGINE_RATIONAL
 

Private Attributes

rational_class i
 i : object of rational_class
 

Additional Inherited Members

- Data Fields inherited from SymEngine::Basic
TypeID type_code_
 

Detailed Description

Rational Class.

Definition at line 15 of file rational.h.

Member Function Documentation

◆ __eq__()

bool SymEngine::Rational::__eq__ ( const Basic o) const
overridevirtual

Equality comparator

Parameters
o- Object to be compared with
Returns
whether the 2 objects are equal

Implements SymEngine::Basic.

Definition at line 106 of file rational.cpp.

107 {
108  if (is_a<Rational>(o)) {
109  const Rational &s = down_cast<const Rational &>(o);
110  return this->i == s.i;
111  }
112  return false;
113 }
rational_class i
i : object of rational_class
Definition: rational.h:19
Rational(rational_class &&_i)
Constructor of Rational class.
Definition: rational.h:24

◆ __hash__()

hash_t SymEngine::Rational::__hash__ ( ) const
overridevirtual
Returns
size of the hash

Implements SymEngine::Basic.

Definition at line 96 of file rational.cpp.

97 {
98  // only the least significant bits that fit into "signed long int" are
99  // hashed:
100  hash_t seed = SYMENGINE_RATIONAL;
101  hash_combine<long long int>(seed, mp_get_si(SymEngine::get_num(this->i)));
102  hash_combine<long long int>(seed, mp_get_si(SymEngine::get_den(this->i)));
103  return seed;
104 }

◆ addrat() [1/2]

RCP<const Number> SymEngine::Rational::addrat ( const Integer other) const
inline

Add Rationals

Parameters
otherof type Integer

Definition at line 112 of file rational.h.

113  {
114  return from_mpq(this->i + other.as_integer_class());
115  }
static RCP< const Number > from_mpq(const rational_class &i)
Definition: rational.cpp:23

◆ addrat() [2/2]

RCP<const Number> SymEngine::Rational::addrat ( const Rational other) const
inline

Add Rationals

Parameters
otherof type Rational

Definition at line 105 of file rational.h.

106  {
107  return from_mpq(this->i + other.i);
108  }

◆ compare()

int SymEngine::Rational::compare ( const Basic o) const
overridevirtual

Returns -1, 0, 1 for this < o, this == o, this > o. This method is used when you want to sort things like x+y+z into canonical order. This function assumes that o is the same type as this. Use __cmp__ if you want general comparison.

Implements SymEngine::Basic.

Definition at line 115 of file rational.cpp.

116 {
117  if (is_a<Rational>(o)) {
118  const Rational &s = down_cast<const Rational &>(o);
119  if (i == s.i)
120  return 0;
121  return i < s.i ? -1 : 1;
122  }
123  if (is_a<Integer>(o)) {
124  const Integer &s = down_cast<const Integer &>(o);
125  return i < s.as_integer_class() ? -1 : 1;
126  }
127  throw NotImplementedError("unhandled comparison of Rational");
128 }

◆ divrat() [1/2]

RCP<const Number> SymEngine::Rational::divrat ( const Integer other) const
inline

Divide Rationals

Parameters
otherof type Integer

Definition at line 166 of file rational.h.

167  {
168  if (other.as_integer_class() == 0) {
169  if (this->i == 0) {
170  return Nan;
171  } else {
172  return ComplexInf;
173  }
174  } else {
175  return from_mpq(this->i / other.as_integer_class());
176  }
177  }

◆ divrat() [2/2]

RCP<const Number> SymEngine::Rational::divrat ( const Rational other) const
inline

Divide Rationals

Parameters
otherof type Rational

Definition at line 151 of file rational.h.

152  {
153  if (other.i == 0) {
154  if (this->i == 0) {
155  return Nan;
156  } else {
157  return ComplexInf;
158  }
159  } else {
160  return from_mpq(this->i / other.i);
161  }
162  }

◆ from_mpq()

RCP< const Number > SymEngine::Rational::from_mpq ( const rational_class &  i)
static
Parameters
<tt>i</tt>must already be in rational_class canonical form
Returns
Integer or Rational depending on denumerator.

Definition at line 23 of file rational.cpp.

24 {
25  // If the result is an Integer, return an Integer:
26  if (SymEngine::get_den(i) == 1) {
27  return integer(SymEngine::get_num(i));
28  } else {
29  rational_class j(i);
30  return make_rcp<const Rational>(std::move(j));
31  }
32 }
T move(T... args)
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:197

◆ from_two_ints()

RCP< const Number > SymEngine::Rational::from_two_ints ( const Integer n,
const Integer d 
)
static

Constructs Rational as n/d, where n, d can be any Integers. If n/d is an Integer, it will return an Integer instead.

Definition at line 44 of file rational.cpp.

45 {
46  if (d.as_integer_class() == 0) {
47  if (n.as_integer_class() == 0) {
48  return Nan;
49  } else {
50  return ComplexInf;
51  }
52  }
53 #if SYMENGINE_INTEGER_CLASS == SYMENGINE_BOOSTMP
54  // workaround https://github.com/boostorg/rational/issues/27
55  rational_class q;
56  if (d.as_integer_class() < 0) {
57  q = rational_class(-n.as_integer_class(), -d.as_integer_class());
58  } else {
59  q = rational_class(n.as_integer_class(), d.as_integer_class());
60  }
61 #else
62  rational_class q(n.as_integer_class(), d.as_integer_class());
63 #endif
64  // This is potentially slow, but has to be done, since 'n/d' might not be
65  // in canonical form.
66  canonicalize(q);
67 
68  return Rational::from_mpq(std::move(q));
69 }

◆ is_canonical()

bool SymEngine::Rational::is_canonical ( const rational_class &  i) const
Returns
true if canonical

Definition at line 8 of file rational.cpp.

9 {
10  rational_class x = i;
11  canonicalize(x);
12  // If 'x' is an integer, it should not be Rational:
13  if (SymEngine::get_den(x) == 1)
14  return false;
15  // if 'i' is not in canonical form:
16  if (SymEngine::get_num(x) != SymEngine::get_num(i))
17  return false;
18  if (SymEngine::get_den(x) != SymEngine::get_den(i))
19  return false;
20  return true;
21 }

◆ is_complex()

bool SymEngine::Rational::is_complex ( ) const
inlineoverridevirtual
Returns
false

Implements SymEngine::Number.

Definition at line 86 of file rational.h.

87  {
88  return false;
89  }

◆ is_int()

bool SymEngine::Rational::is_int ( ) const
inline
Returns
true if denominator is 1

Definition at line 70 of file rational.h.

71  {
72  return this->i == 1;
73  }

◆ is_minus_one()

bool SymEngine::Rational::is_minus_one ( ) const
inlineoverridevirtual
Returns
true if -1

Implements SymEngine::Number.

Definition at line 65 of file rational.h.

66  {
67  return this->i == -1;
68  }

◆ is_negative()

bool SymEngine::Rational::is_negative ( ) const
inlineoverridevirtual
Returns
true if negative

Implements SymEngine::Number.

Definition at line 80 of file rational.h.

81  {
82  return i < 0;
83  }

◆ is_one()

bool SymEngine::Rational::is_one ( ) const
inlineoverridevirtual
Returns
true if 1

Implements SymEngine::Number.

Definition at line 60 of file rational.h.

61  {
62  return this->i == 1;
63  }

◆ is_positive()

bool SymEngine::Rational::is_positive ( ) const
inlineoverridevirtual
Returns
true if positive

Implements SymEngine::Number.

Definition at line 75 of file rational.h.

76  {
77  return i > 0;
78  }

◆ is_zero()

bool SymEngine::Rational::is_zero ( ) const
inlineoverridevirtual
Returns
true if 0

Implements SymEngine::Number.

Definition at line 55 of file rational.h.

56  {
57  return this->i == 0;
58  }

◆ mulrat() [1/2]

RCP<const Number> SymEngine::Rational::mulrat ( const Integer other) const
inline

Multiply Rationals

Parameters
otherof type Integer

Definition at line 144 of file rational.h.

145  {
146  return from_mpq(this->i * other.as_integer_class());
147  }

◆ mulrat() [2/2]

RCP<const Number> SymEngine::Rational::mulrat ( const Rational other) const
inline

Multiply Rationals

Parameters
otherof type Rational

Definition at line 137 of file rational.h.

138  {
139  return from_mpq(this->i * other.i);
140  }

◆ neg()

RCP<const Rational> SymEngine::Rational::neg ( ) const
inline
Returns
negative of this

Definition at line 92 of file rational.h.

93  {
94  return make_rcp<const Rational>(-i);
95  }

◆ powrat() [1/2]

RCP<const Number> SymEngine::Rational::powrat ( const Integer other) const
inline

Raise Rationals to power other

Parameters
otherpower to be raised

Definition at line 193 of file rational.h.

194  {
195  bool neg = other.is_negative();
196  integer_class exp_ = other.as_integer_class();
197  if (neg)
198  exp_ = -exp_;
199  if (not mp_fits_ulong_p(exp_))
200  throw SymEngineException("powrat: 'exp' does not fit ulong.");
201  unsigned long exp = mp_get_ui(exp_);
202 
203 #if SYMENGINE_INTEGER_CLASS == SYMENGINE_BOOSTMP
204  // boost::multiprecision::cpp_rational doesn't provide
205  // non-const references to num and den
206  integer_class num;
207  integer_class den;
208  mp_pow_ui(num, SymEngine::get_num(i), exp);
209  mp_pow_ui(den, SymEngine::get_den(i), exp);
210  rational_class val(num, den);
211 #else
212  rational_class val;
213  mp_pow_ui(SymEngine::get_num(val), SymEngine::get_num(i), exp);
214  mp_pow_ui(SymEngine::get_den(val), SymEngine::get_den(i), exp);
215 #endif
216 
217  // Since 'this' is in canonical form, so is this**other, so we simply
218  // pass val into the constructor directly without canonicalizing:
219  if (not neg) {
220  return Rational::from_mpq(std::move(val));
221  } else {
222  return Rational::from_mpq(1 / val);
223  }
224  }
RCP< const Rational > neg() const
Definition: rational.h:92
RCP< const Basic > exp(const RCP< const Basic > &x)
Returns the natural exponential function E**x = pow(E, x)
Definition: pow.cpp:271

◆ powrat() [2/2]

RCP< const Basic > SymEngine::Rational::powrat ( const Rational other) const

Raise *this to power other

Parameters
otherexponent

Definition at line 189 of file rational.cpp.

190 {
191  return SymEngine::mul(other.rpowrat(*this->get_num()),
192  other.neg()->rpowrat(*this->get_den()));
193 }
RCP< const Basic > mul(const RCP< const Basic > &a, const RCP< const Basic > &b)
Multiplication.
Definition: mul.cpp:352

◆ rpowrat()

RCP< const Basic > SymEngine::Rational::rpowrat ( const Integer other) const

Reverse powrat Raise 'other' to power *this

Parameters
otherbase

Definition at line 195 of file rational.cpp.

196 {
197  if (other.is_one()) {
198  return one;
199  }
200  RCP<const Integer> res;
201  if (mp_fits_ulong_p(SymEngine::get_den(i))) {
202  unsigned long den = mp_get_ui(SymEngine::get_den(i));
203  if (other.is_negative()) {
204  RCP<const Integer> neg_other = other.neg();
205  if (not other.is_minus_one()
206  and i_nth_root(outArg(res), *neg_other, den)) {
207  return SymEngine::mul(this->rpowrat(*minus_one),
208  res->powint(*get_num()));
209  }
210  } else if (i_nth_root(outArg(res), other, den)) {
211  // res == other**(1/den)
212  // return res**num
213  return res->powint(*get_num());
214  }
215  }
216  integer_class q, r;
217  auto num = SymEngine::get_num(i);
218  auto den = SymEngine::get_den(i);
219 
220  mp_fdiv_qr(q, r, num, den);
221  // Here we make the exponent postive and a fraction between
222  // 0 and 1. We multiply numerator and denominator appropriately
223  // to achieve this
224  RCP<const Number> coef = other.powint(*integer(q));
225  map_basic_basic surd;
226 
227  if ((other.is_negative()) and den == 2) {
228  imulnum(outArg(coef), I);
229  // if other.neg() is one, no need to add it to dict
230  if (not other.is_minus_one())
231  insert(surd, other.neg(),
232  Rational::from_mpq(rational_class(r, den)));
233  } else {
234  insert(surd, other.rcp_from_this(),
235  Rational::from_mpq(rational_class(r, den)));
236  }
237  return Mul::from_dict(coef, std::move(surd));
238 }
static RCP< const Basic > from_dict(const RCP< const Number > &coef, map_basic_basic &&d)
Create a Mul from a dict.
Definition: mul.cpp:115
RCP< const Basic > rpowrat(const Integer &other) const
Definition: rational.cpp:195
void insert(T1 &m, const T2 &first, const T3 &second)
Definition: dict.h:83
int i_nth_root(const Ptr< RCP< const Integer >> &r, const Integer &a, unsigned long int n)
Integer nth root.
Definition: integer.cpp:128

◆ subrat() [1/2]

RCP<const Number> SymEngine::Rational::subrat ( const Integer other) const
inline

Subtract Rationals

Parameters
otherof type Integer

Definition at line 126 of file rational.h.

127  {
128  return from_mpq(this->i - other.as_integer_class());
129  }

◆ subrat() [2/2]

RCP<const Number> SymEngine::Rational::subrat ( const Rational other) const
inline

Subtract Rationals

Parameters
otherof type Rational

Definition at line 119 of file rational.h.

120  {
121  return from_mpq(this->i - other.i);
122  }

Field Documentation

◆ type_code_id

const TypeID SymEngine::Rational::type_code_id = SYMENGINE_RATIONAL
static

Type_code_id shared by all instances

Definition at line 22 of file rational.h.


The documentation for this class was generated from the following files: