Loading...
Searching...
No Matches
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 bool is_zero () const =0
 
virtual bool is_one () const =0
 
virtual bool is_minus_one () const =0
 
virtual bool is_negative () const =0
 
virtual bool is_positive () const =0
 
virtual bool is_complex () const =0
 
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.
 
virtual RCP< const Numberadd (const Number &other) const =0
 Addition.
 
virtual RCP< const Numbersub (const Number &other) const
 Subtraction.
 
virtual RCP< const Numberrsub (const Number &other) const
 
virtual RCP< const Numbermul (const Number &other) const =0
 Multiplication.
 
virtual RCP< const Numberdiv (const Number &other) const
 Division.
 
virtual RCP< const Numberrdiv (const Number &other) const
 
virtual RCP< const Numberpow (const Number &other) const =0
 Power.
 
virtual RCP< const Numberrpow (const Number &other) const =0
 
vec_basic get_args () const override
 Returns the list of arguments.
 
virtual bool is_perfect_power (bool is_expected=false) const
 
virtual bool nth_root (const Ptr< RCP< const Number > > &, unsigned long n) const
 
- 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.
 
virtual hash_t __hash__ () const =0
 
hash_t hash () const
 
virtual bool __eq__ (const Basic &o) const =0
 Test equality.
 
bool __neq__ (const Basic &o) const
 true if this is not equal to o.
 
int __cmp__ (const Basic &o) const
 Comparison operator.
 
virtual int compare (const Basic &o) const =0
 
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
 
virtual vec_basic get_args () const =0
 Returns the list of arguments.
 
virtual void accept (Visitor &v) const =0
 
virtual void accept (EvalRealDoubleVisitorFinal &v) const =0
 
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.

Constructor & Destructor Documentation

◆ Rational()

SymEngine::Rational::Rational ( rational_class &&  _i)
inline

Constructor of Rational class.

Definition at line 24 of file rational.h.

24 : i(std::move(_i))
25 {
26 SYMENGINE_ASSIGN_TYPEID()
27 }
rational_class i
i : object of rational_class
Definition: rational.h:19
T move(T... args)

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(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}

◆ accept() [1/2]

void SymEngine::Rational::accept ( EvalRealDoubleVisitorFinal v) const
overridevirtual

Implements SymEngine::Basic.

◆ accept() [2/2]

void SymEngine::Rational::accept ( Visitor v) const
overridevirtual

Implements SymEngine::Basic.

◆ add()

RCP< const Number > SymEngine::Rational::add ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls addrat

Implements SymEngine::Number.

Definition at line 236 of file rational.h.

237 {
238 if (is_a<Rational>(other)) {
239 return addrat(down_cast<const Rational &>(other));
240 } else if (is_a<Integer>(other)) {
241 return addrat(down_cast<const Integer &>(other));
242 } else {
243 return other.add(*this);
244 }
245 };
RCP< const Number > addrat(const Rational &other) const
Definition: rational.h:105

◆ 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 }

◆ as_rational_class()

const rational_class & SymEngine::Rational::as_rational_class ( ) const
inline

Convert to rational_class.

Definition at line 50 of file rational.h.

51 {
52 return this->i;
53 }

◆ 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}

◆ div()

RCP< const Number > SymEngine::Rational::div ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls divrat

Reimplemented from SymEngine::Number.

Definition at line 278 of file rational.h.

279 {
280 if (is_a<Rational>(other)) {
281 return divrat(down_cast<const Rational &>(other));
282 } else if (is_a<Integer>(other)) {
283 return divrat(down_cast<const Integer &>(other));
284 } else {
285 return other.rdiv(*this);
286 }
287 };
RCP< const Number > divrat(const Rational &other) const
Definition: rational.h:151

◆ 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() [1/2]

RCP< const Number > SymEngine::Rational::from_mpq ( const rational_class &  i)
static
Parameters
`i`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}
std::enable_if< std::is_integral< T >::value, RCP< constInteger > >::type integer(T i)
Definition: integer.h:197

◆ from_mpq() [2/2]

RCP< const Number > SymEngine::Rational::from_mpq ( rational_class &&  i)
static

Definition at line 34 of file rational.cpp.

35{
36 // If the result is an Integer, return an Integer:
37 if (SymEngine::get_den(i) == 1) {
38 return integer(SymEngine::get_num(i));
39 } else {
40 return make_rcp<const Rational>(std::move(i));
41 }
42}

◆ from_two_ints() [1/2]

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
69}

◆ from_two_ints() [2/2]

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

Definition at line 71 of file rational.cpp.

72{
73 if (d == 0) {
74 if (n == 0) {
75 return Nan;
76 } else {
77 return ComplexInf;
78 }
79 }
80#if SYMENGINE_INTEGER_CLASS == SYMENGINE_BOOSTMP
81 // workaround https://github.com/boostorg/rational/issues/27
82 if (d < 0) {
83 d *= -1;
84 n *= -1;
85 }
86#endif
87 rational_class q(n, d);
88
89 // This is potentially slow, but has to be done, since 'n/d' might not be
90 // in canonical form.
91 canonicalize(q);
92
93 return Rational::from_mpq(q);
94}

◆ get_den()

RCP< const Integer > SymEngine::Rational::get_den ( ) const
inline

Definition at line 317 of file rational.h.

318 {
319 return integer(SymEngine::get_den(i));
320 }

◆ get_num()

RCP< const Integer > SymEngine::Rational::get_num ( ) const
inline

Definition at line 312 of file rational.h.

313 {
314 return integer(SymEngine::get_num(i));
315 }

◆ 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_perfect_power()

bool SymEngine::Rational::is_perfect_power ( bool  is_expected = false) const
overridevirtual

Reimplemented from SymEngine::Number.

Definition at line 137 of file rational.cpp.

138{
139 const integer_class &num = SymEngine::get_num(i);
140 if (num == 1)
141 return mp_perfect_power_p(SymEngine::get_den(i));
142
143 const integer_class &den = SymEngine::get_den(i);
144 // TODO: fix this
145 if (not is_expected) {
146 if (mp_cmpabs(num, den) > 0) {
147 if (!mp_perfect_power_p(den))
148 return false;
149 } else {
150 if (!mp_perfect_power_p(num))
151 return false;
152 }
153 }
154 integer_class prod = num * den;
155 return mp_perfect_power_p(prod);
156}

◆ 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 }

◆ mul()

RCP< const Number > SymEngine::Rational::mul ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls mulrat

Implements SymEngine::Number.

Definition at line 267 of file rational.h.

268 {
269 if (is_a<Rational>(other)) {
270 return mulrat(down_cast<const Rational &>(other));
271 } else if (is_a<Integer>(other)) {
272 return mulrat(down_cast<const Integer &>(other));
273 } else {
274 return other.mul(*this);
275 }
276 };
RCP< const Number > mulrat(const Rational &other) const
Definition: rational.h:137

◆ 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 }

◆ nth_root()

bool SymEngine::Rational::nth_root ( const Ptr< RCP< const Number > > &  the_rat,
unsigned long  n 
) const
overridevirtual

Reimplemented from SymEngine::Number.

Definition at line 158 of file rational.cpp.

160{
161 if (n == 0)
162 throw SymEngineException("i_nth_root: Can not find Zeroth root");
163
164#if SYMENGINE_INTEGER_CLASS != SYMENGINE_BOOSTMP
165 rational_class r;
166 int ret = mp_root(SymEngine::get_num(r), SymEngine::get_num(i), n);
167 if (ret == 0)
168 return false;
169 ret = mp_root(SymEngine::get_den(r), SymEngine::get_den(i), n);
170 if (ret == 0)
171 return false;
172#else
173 // boost::multiprecision::cpp_rational doesn't provide
174 // non-const get_num and get_den
175 integer_class num, den;
176 int ret = mp_root(num, SymEngine::get_num(i), n);
177 if (ret == 0)
178 return false;
179 ret = mp_root(den, SymEngine::get_den(i), n);
180 if (ret == 0)
181 return false;
182 rational_class r(num, den);
183#endif
184 // No need to canonicalize since `this` is in canonical form
185 *the_rat = make_rcp<const Rational>(std::move(r));
186 return true;
187}

◆ pow()

RCP< const Number > SymEngine::Rational::pow ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls powrat

Implements SymEngine::Number.

Definition at line 298 of file rational.h.

299 {
300 if (is_a<Integer>(other)) {
301 return powrat(down_cast<const Integer &>(other));
302 } else {
303 return other.rpow(*this);
304 }
305 };
RCP< const Number > powrat(const Integer &other) const
Definition: rational.h:193

◆ 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

◆ rdiv()

RCP< const Number > SymEngine::Rational::rdiv ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls rdivrat

Reimplemented from SymEngine::Number.

Definition at line 289 of file rational.h.

290 {
291 if (is_a<Integer>(other)) {
292 return rdivrat(down_cast<const Integer &>(other));
293 } else {
294 throw NotImplementedError("Not Implemented");
295 }
296 };

◆ rdivrat()

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

Definition at line 178 of file rational.h.

179 {
180 if (this->i == 0) {
181 if (other.is_zero()) {
182 return Nan;
183 } else {
184 return ComplexInf;
185 }
186 } else {
187 return from_mpq(other.as_integer_class() / this->i);
188 }
189 }

◆ rpow()

RCP< const Number > SymEngine::Rational::rpow ( const Number other) const
inlineoverridevirtual

Implements SymEngine::Number.

Definition at line 307 of file rational.h.

308 {
309 throw NotImplementedError("Not Implemented");
310 };

◆ 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 (not(mp_fits_ulong_p(SymEngine::get_den(i))))
198 throw SymEngineException("powrat: den of 'exp' does not fit ulong.");
199 unsigned long exp = mp_get_ui(SymEngine::get_den(i));
200 RCP<const Integer> res;
201 if (other.is_negative()) {
202 if (i_nth_root(outArg(res), *other.neg(), exp)) {
203 if (exp % 2 == 0) {
204 return I->pow(*get_num())->mul(*res->powint(*get_num()));
205 } else {
206 return SymEngine::neg(res->powint(*get_num()));
207 }
208 }
209 } else {
210 if (i_nth_root(outArg(res), other, exp)) {
211 return res->powint(*get_num());
212 }
213 }
214 integer_class q, r;
215 auto num = SymEngine::get_num(i);
216 auto den = SymEngine::get_den(i);
217
218 mp_fdiv_qr(q, r, num, den);
219 // Here we make the exponent postive and a fraction between
220 // 0 and 1. We multiply numerator and denominator appropriately
221 // to achieve this
222 RCP<const Number> coef = other.powint(*integer(q));
223 map_basic_basic surd;
224
225 if ((other.is_negative()) and den == 2) {
226 imulnum(outArg(coef), I);
227 // if other.neg() is one, no need to add it to dict
228 if (other.as_integer_class() != -1)
229 insert(surd, other.neg(),
230 Rational::from_mpq(rational_class(r, den)));
231 } else {
232 insert(surd, other.rcp_from_this(),
233 Rational::from_mpq(rational_class(r, den)));
234 }
235 return Mul::from_dict(coef, std::move(surd));
236}
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
int i_nth_root(const Ptr< RCP< const Integer > > &r, const Integer &a, unsigned long int n)
Integer nth root.
Definition: integer.cpp:128
void insert(T1 &m, const T2 &first, const T3 &second)
Definition: dict.h:83
RCP< const Basic > neg(const RCP< const Basic > &a)
Negation.
Definition: mul.cpp:443

◆ rsub()

RCP< const Number > SymEngine::Rational::rsub ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls rsubrat

Reimplemented from SymEngine::Number.

Definition at line 258 of file rational.h.

259 {
260 if (is_a<Integer>(other)) {
261 return rsubrat(down_cast<const Integer &>(other));
262 } else {
263 throw NotImplementedError("Not Implemented");
264 }
265 };

◆ rsubrat()

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

Definition at line 130 of file rational.h.

131 {
132 return from_mpq(other.as_integer_class() - this->i);
133 }

◆ sub()

RCP< const Number > SymEngine::Rational::sub ( const Number other) const
inlineoverridevirtual

Converts the param other appropriately and then calls subrat

Reimplemented from SymEngine::Number.

Definition at line 247 of file rational.h.

248 {
249 if (is_a<Rational>(other)) {
250 return subrat(down_cast<const Rational &>(other));
251 } else if (is_a<Integer>(other)) {
252 return subrat(down_cast<const Integer &>(other));
253 } else {
254 return other.rsub(*this);
255 }
256 };
RCP< const Number > subrat(const Rational &other) const
Definition: rational.h:119

◆ 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

◆ i

rational_class SymEngine::Rational::i
private

i : object of rational_class

Definition at line 19 of file rational.h.

◆ 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: