SymEngine::Complex Class Reference

Complex Class. More...

#include <complex.h>

+ Inheritance diagram for SymEngine::Complex:
+ Collaboration diagram for SymEngine::Complex:

Public Member Functions

virtual void accept (Visitor &v) const
 
virtual void accept (EvalRealDoubleVisitorFinal &v) const
 
 Complex (rational_class real, rational_class imaginary)
 Constructor of Complex class.
 
bool is_canonical (const rational_class &real, const rational_class &imaginary) const
 
virtual hash_t __hash__ () const
 
virtual bool __eq__ (const Basic &o) const
 
virtual int compare (const Basic &o) const
 
virtual RCP< const Numberreal_part () const
 Get the real part of the complex number.
 
virtual RCP< const Numberimaginary_part () const
 Get the imaginary part of the complex number.
 
virtual RCP< const Basicconjugate () const
 Get the conjugate of the complex number.
 
virtual bool is_positive () const
 
virtual bool is_negative () const
 
virtual bool is_complex () const
 
virtual bool is_zero () const
 
virtual bool is_one () const
 
virtual bool is_minus_one () const
 
RCP< const Numberaddcomp (const Complex &other) const
 
RCP< const Numberaddcomp (const Rational &other) const
 
RCP< const Numberaddcomp (const Integer &other) const
 
RCP< const Numbersubcomp (const Complex &other) const
 
RCP< const Numbersubcomp (const Rational &other) const
 
RCP< const Numbersubcomp (const Integer &other) const
 
RCP< const Numberrsubcomp (const Complex &other) const
 
RCP< const Numberrsubcomp (const Rational &other) const
 
RCP< const Numberrsubcomp (const Integer &other) const
 
RCP< const Numbermulcomp (const Complex &other) const
 
RCP< const Numbermulcomp (const Rational &other) const
 
RCP< const Numbermulcomp (const Integer &other) const
 
RCP< const Numberdivcomp (const Complex &other) const
 
RCP< const Numberdivcomp (const Rational &other) const
 
RCP< const Numberdivcomp (const Integer &other) const
 
RCP< const Numberrdivcomp (const Integer &other) const
 
RCP< const Numberpowcomp (const Integer &other) const
 
virtual RCP< const Numberadd (const Number &other) const
 Converts the param other appropriately and then calls addcomp
 
virtual RCP< const Numbersub (const Number &other) const
 Converts the param other appropriately and then calls subcomp
 
virtual RCP< const Numberrsub (const Number &other) const
 Converts the param other appropriately and then calls rsubcomp
 
virtual RCP< const Numbermul (const Number &other) const
 Converts the param other appropriately and then calls mulcomp
 
virtual RCP< const Numberdiv (const Number &other) const
 Converts the param other appropriately and then calls divcomp
 
virtual RCP< const Numberrdiv (const Number &other) const
 Converts the param other appropriately and then calls rdivcomp
 
virtual RCP< const Numberpow (const Number &other) const
 Converts the param other appropriately and then calls powcomp
 
virtual RCP< const Numberrpow (const Number &other) const
 
- Public Member Functions inherited from SymEngine::ComplexBase
bool is_re_zero () const
 
- Public Member Functions inherited from SymEngine::Number
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 vec_basic get_args () const
 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.
 
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
 
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 re, const rational_class im)
 
static RCP< const Numberfrom_two_rats (const Rational &re, const Rational &im)
 
static RCP< const Numberfrom_two_nums (const Number &re, const Number &im)
 

Data Fields

rational_class real_
 
rational_class imaginary_
 
- Data Fields inherited from SymEngine::Basic
TypeID type_code_
 

Static Public Attributes

static const TypeID type_code_id = SYMENGINE_COMPLEX
 

Detailed Description

Complex Class.

Definition at line 32 of file complex.h.

Member Function Documentation

◆ __eq__()

bool SymEngine::Complex::__eq__ ( const Basic o) const
virtual

Equality comparator

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

Implements SymEngine::Basic.

Definition at line 53 of file complex.cpp.

54 {
55  if (is_a<Complex>(o)) {
56  const Complex &s = down_cast<const Complex &>(o);
57  return ((this->real_ == s.real_)
58  and (this->imaginary_ == s.imaginary_));
59  }
60  return false;
61 }
Complex(rational_class real, rational_class imaginary)
Constructor of Complex class.
Definition: complex.cpp:12
rational_class real_
Definition: complex.h:38

◆ __hash__()

hash_t SymEngine::Complex::__hash__ ( ) const
virtual
Returns
size of the hash

Implements SymEngine::Basic.

Definition at line 41 of file complex.cpp.

42 {
43  // only the least significant bits that fit into "signed long int" are
44  // hashed:
45  hash_t seed = SYMENGINE_COMPLEX;
46  hash_combine<long long int>(seed, mp_get_si(get_num(this->real_)));
47  hash_combine<long long int>(seed, mp_get_si(get_den(this->real_)));
48  hash_combine<long long int>(seed, mp_get_si(get_num(this->imaginary_)));
49  hash_combine<long long int>(seed, mp_get_si(get_den(this->imaginary_)));
50  return seed;
51 }

◆ addcomp() [1/3]

RCP<const Number> SymEngine::Complex::addcomp ( const Complex other) const
inline

Add Complex

Parameters
otherof type Complex

Definition at line 117 of file complex.h.

118  {
119  return from_mpq(this->real_ + other.real_,
120  this->imaginary_ + other.imaginary_);
121  }
static RCP< const Number > from_mpq(const rational_class re, const rational_class im)
Definition: complex.cpp:93

◆ addcomp() [2/3]

RCP<const Number> SymEngine::Complex::addcomp ( const Integer other) const
inline

Add Complex

Parameters
otherof type Integer

Definition at line 133 of file complex.h.

134  {
135  return from_mpq(this->real_ + other.as_integer_class(),
136  this->imaginary_);
137  }

◆ addcomp() [3/3]

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

Add Complex

Parameters
otherof type Rational

Definition at line 125 of file complex.h.

126  {
127  return from_mpq(this->real_ + other.as_rational_class(),
128  this->imaginary_);
129  }

◆ compare()

int SymEngine::Complex::compare ( const Basic o) const
virtual

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 63 of file complex.cpp.

64 {
65  SYMENGINE_ASSERT(is_a<Complex>(o))
66  const Complex &s = down_cast<const Complex &>(o);
67  if (real_ == s.real_) {
68  if (imaginary_ == s.imaginary_) {
69  return 0;
70  } else {
71  return imaginary_ < s.imaginary_ ? -1 : 1;
72  }
73  } else {
74  return real_ < s.real_ ? -1 : 1;
75  }
76 }

◆ divcomp() [1/3]

RCP<const Number> SymEngine::Complex::divcomp ( const Complex other) const
inline

Divide Complex

Parameters
otherof type Complex

Definition at line 217 of file complex.h.

218  {
219  rational_class modulus_sq_other
220  = other.real_ * other.real_ + other.imaginary_ * other.imaginary_;
221 
222  if (get_num(modulus_sq_other) == 0) {
223  rational_class modulus_sq_this
224  = this->real_ * this->real_
225  + this->imaginary_ * this->imaginary_;
226  if (get_num(modulus_sq_this) == 0) {
227  return Nan;
228  } else {
229  return ComplexInf;
230  }
231  } else {
232  return from_mpq((this->real_ * other.real_
233  + this->imaginary_ * other.imaginary_)
234  / modulus_sq_other,
235  (-this->real_ * other.imaginary_
236  + this->imaginary_ * other.real_)
237  / modulus_sq_other);
238  }
239  }

◆ divcomp() [2/3]

RCP<const Number> SymEngine::Complex::divcomp ( const Integer other) const
inline

Divide Complex

Parameters
otherof type Integer

Definition at line 263 of file complex.h.

264  {
265  if (other.is_zero()) {
266  rational_class modulus_sq_this
267  = this->real_ * this->real_
268  + this->imaginary_ * this->imaginary_;
269 
270  if (get_num(modulus_sq_this) == 0) {
271  return Nan;
272  } else {
273  return ComplexInf;
274  }
275  } else {
276  return from_mpq(this->real_ / other.as_integer_class(),
277  this->imaginary_ / other.as_integer_class());
278  }
279  }

◆ divcomp() [3/3]

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

Divide Complex

Parameters
otherof type Rational

Definition at line 243 of file complex.h.

244  {
245  if (other.is_zero()) {
246  rational_class modulus_sq_this
247  = this->real_ * this->real_
248  + this->imaginary_ * this->imaginary_;
249 
250  if (get_num(modulus_sq_this) == 0) {
251  return Nan;
252  } else {
253  return ComplexInf;
254  }
255  } else {
256  return from_mpq(this->real_ / other.as_rational_class(),
257  this->imaginary_ / other.as_rational_class());
258  }
259  }

◆ from_mpq()

RCP< const Number > SymEngine::Complex::from_mpq ( const rational_class  re,
const rational_class  im 
)
static

Creates an instance of Complex if imaginary part is non-zero

Parameters
<tt>re</tt>must already be in rational_class canonical form
<tt>im</tt>must already be in rational_class canonical form
Returns
Complex or Rational depending on imaginary part.

Definition at line 93 of file complex.cpp.

95 {
96  // It is assumed that `re` and `im` are already in canonical form.
97  if (get_num(im) == 0) {
98  return Rational::from_mpq(re);
99  } else {
100  return make_rcp<const Complex>(re, im);
101  }
102 }
static RCP< const Number > from_mpq(const rational_class &i)
Definition: rational.cpp:23

◆ from_two_nums()

RCP< const Number > SymEngine::Complex::from_two_nums ( const Number re,
const Number im 
)
static

Constructs Complex from re, im. If im is 0 it will return a Rational instead.

Definition at line 109 of file complex.cpp.

110 {
111  if (is_a<Integer>(re) and is_a<Integer>(im)) {
112  rational_class re_mpq(
113  down_cast<const Integer &>(re).as_integer_class(),
114  down_cast<const Integer &>(*one).as_integer_class());
115  rational_class im_mpq(
116  down_cast<const Integer &>(im).as_integer_class(),
117  down_cast<const Integer &>(*one).as_integer_class());
118  return Complex::from_mpq(re_mpq, im_mpq);
119  } else if (is_a<Rational>(re) and is_a<Integer>(im)) {
120  rational_class re_mpq
121  = down_cast<const Rational &>(re).as_rational_class();
122  rational_class im_mpq(
123  down_cast<const Integer &>(im).as_integer_class(),
124  down_cast<const Integer &>(*one).as_integer_class());
125  return Complex::from_mpq(re_mpq, im_mpq);
126  } else if (is_a<Integer>(re) and is_a<Rational>(im)) {
127  rational_class re_mpq(
128  down_cast<const Integer &>(re).as_integer_class(),
129  down_cast<const Integer &>(*one).as_integer_class());
130  rational_class im_mpq
131  = down_cast<const Rational &>(im).as_rational_class();
132  return Complex::from_mpq(re_mpq, im_mpq);
133  } else if (is_a<Rational>(re) and is_a<Rational>(im)) {
134  rational_class re_mpq
135  = down_cast<const Rational &>(re).as_rational_class();
136  rational_class im_mpq
137  = down_cast<const Rational &>(im).as_rational_class();
138  return Complex::from_mpq(re_mpq, im_mpq);
139  } else {
140  throw SymEngineException(
141  "Invalid Format: Expected Integer or Rational");
142  }
143 }

◆ from_two_rats()

RCP< const Number > SymEngine::Complex::from_two_rats ( const Rational re,
const Rational im 
)
static

Constructs Complex from re, im. If im is 0 it will return a Rational instead.

Definition at line 104 of file complex.cpp.

105 {
106  return Complex::from_mpq(re.as_rational_class(), im.as_rational_class());
107 }

◆ is_canonical()

bool SymEngine::Complex::is_canonical ( const rational_class &  real,
const rational_class &  imaginary 
) const
Returns
true if canonical

Definition at line 19 of file complex.cpp.

21 {
22  rational_class re = real;
23  rational_class im = imaginary;
24  canonicalize(re);
25  canonicalize(im);
26  // If 'im' is 0, it should not be Complex:
27  if (get_num(im) == 0)
28  return false;
29  // if 'real' or `imaginary` are not in canonical form:
30  if (get_num(re) != get_num(real))
31  return false;
32  if (get_den(re) != get_den(real))
33  return false;
34  if (get_num(im) != get_num(imaginary))
35  return false;
36  if (get_den(im) != get_den(imaginary))
37  return false;
38  return true;
39 }

◆ is_complex()

virtual bool SymEngine::Complex::is_complex ( ) const
inlinevirtual
Returns
true

Implements SymEngine::Number.

Definition at line 82 of file complex.h.

83  {
84  return true;
85  }

◆ is_minus_one()

virtual bool SymEngine::Complex::is_minus_one ( ) const
inlinevirtual
Returns
false since imaginary_ cannot be zero

Implements SymEngine::Number.

Definition at line 109 of file complex.h.

110  {
111  return false;
112  }

◆ is_negative()

virtual bool SymEngine::Complex::is_negative ( ) const
inlinevirtual
Returns
false

Implements SymEngine::Number.

Definition at line 77 of file complex.h.

78  {
79  return false;
80  }

◆ is_one()

virtual bool SymEngine::Complex::is_one ( ) const
inlinevirtual
Returns
false since imaginary_ cannot be zero

Implements SymEngine::Number.

Definition at line 104 of file complex.h.

105  {
106  return false;
107  }

◆ is_positive()

virtual bool SymEngine::Complex::is_positive ( ) const
inlinevirtual
Returns
false

Implements SymEngine::Number.

Definition at line 71 of file complex.h.

72  {
73  return false;
74  }

◆ is_zero()

virtual bool SymEngine::Complex::is_zero ( ) const
inlinevirtual
Returns
false since imaginary_ cannot be zero

Implements SymEngine::Number.

Definition at line 99 of file complex.h.

100  {
101  return false;
102  }

◆ mulcomp() [1/3]

RCP<const Number> SymEngine::Complex::mulcomp ( const Complex other) const
inline

Multiply Complex

Parameters
otherof type Complex

Definition at line 191 of file complex.h.

192  {
193  return from_mpq(
194  this->real_ * other.real_ - this->imaginary_ * other.imaginary_,
195  this->real_ * other.imaginary_ + this->imaginary_ * other.real_);
196  }

◆ mulcomp() [2/3]

RCP<const Number> SymEngine::Complex::mulcomp ( const Integer other) const
inline

Multiply Complex

Parameters
otherof type Integer

Definition at line 208 of file complex.h.

209  {
210  return from_mpq(this->real_ * other.as_integer_class(),
211  this->imaginary_ * other.as_integer_class());
212  }

◆ mulcomp() [3/3]

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

Multiply Complex

Parameters
otherof type Rational

Definition at line 200 of file complex.h.

201  {
202  return from_mpq(this->real_ * other.as_rational_class(),
203  this->imaginary_ * other.as_rational_class());
204  }

◆ powcomp()

RCP< const Number > SymEngine::Complex::powcomp ( const Integer other) const

Pow Complex

Parameters
otherof type Integer

Definition at line 175 of file complex.cpp.

176 {
177  if (this->is_re_zero()) {
178  // Imaginary Number raised to an integer power.
179  RCP<const Number> im = Rational::from_mpq(this->imaginary_);
180  long rem = mod_f(other, *integer(4))->as_int();
181  RCP<const Number> res;
182  if (rem == 0) {
183  res = one;
184  } else if (rem == 1) {
185  res = I;
186  } else if (rem == 2) {
187  res = minus_one;
188  } else {
189  res = mulnum(I, minus_one);
190  }
191  return mulnum(im->pow(other), res);
192  } else if (other.is_positive()) {
193  return pow_number(*this, other.as_int());
194  } else {
195  return one->div(*pow_number(*this, -1 * other.as_int()));
196  }
197 }
std::enable_if< std::is_integral< T >::value, RCP< const Integer > >::type integer(T i)
Definition: integer.h:200
RCP< const Number > mulnum(const RCP< const Number > &self, const RCP< const Number > &other)
Multiply self and other
Definition: number.h:93
RCP< const Integer > mod_f(const Integer &n, const Integer &d)
modulo round toward -inf
Definition: ntheory.cpp:84

◆ rdivcomp()

RCP<const Number> SymEngine::Complex::rdivcomp ( const Integer other) const
inline

Divide other by the Complex

Parameters
otherof type Integer

Definition at line 283 of file complex.h.

284  {
285  rational_class modulus_sq_this
286  = this->real_ * this->real_ + this->imaginary_ * this->imaginary_;
287 
288  if (get_num(modulus_sq_this) == 0) {
289  if (other.is_zero()) {
290  return Nan;
291  } else {
292  return ComplexInf;
293  }
294  } else {
295  return from_mpq((this->real_ * other.as_integer_class())
296  / modulus_sq_this,
297  (this->imaginary_ * (-other.as_integer_class()))
298  / modulus_sq_this);
299  }
300  }

◆ rsubcomp() [1/3]

RCP<const Number> SymEngine::Complex::rsubcomp ( const Complex other) const
inline

Subtract Complex from other

Parameters
otherof type Complex

Definition at line 166 of file complex.h.

167  {
168  return from_mpq(other.real_ - this->real_,
169  other.imaginary_ - this->imaginary_);
170  }

◆ rsubcomp() [2/3]

RCP<const Number> SymEngine::Complex::rsubcomp ( const Integer other) const
inline

Subtract Complex from other

Parameters
otherof type Integer

Definition at line 182 of file complex.h.

183  {
184  return from_mpq(other.as_integer_class() - this->real_,
185  -this->imaginary_);
186  }

◆ rsubcomp() [3/3]

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

Subtract Complex from other

Parameters
otherof type Rational

Definition at line 174 of file complex.h.

175  {
176  return from_mpq(other.as_rational_class() - this->real_,
177  -this->imaginary_);
178  }

◆ subcomp() [1/3]

RCP<const Number> SymEngine::Complex::subcomp ( const Complex other) const
inline

Subtract Complex

Parameters
otherof type Complex

Definition at line 142 of file complex.h.

143  {
144  return from_mpq(this->real_ - other.real_,
145  this->imaginary_ - other.imaginary_);
146  }

◆ subcomp() [2/3]

RCP<const Number> SymEngine::Complex::subcomp ( const Integer other) const
inline

Subtract Complex

Parameters
otherof type Integer

Definition at line 158 of file complex.h.

159  {
160  return from_mpq(this->real_ - other.as_integer_class(),
161  this->imaginary_);
162  }

◆ subcomp() [3/3]

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

Subtract Complex

Parameters
otherof type Rational

Definition at line 150 of file complex.h.

151  {
152  return from_mpq(this->real_ - other.as_rational_class(),
153  this->imaginary_);
154  }

Field Documentation

◆ real_

rational_class SymEngine::Complex::real_

real_ : Real part of the complex Number imaginary_ : Imaginary part of the complex Number

Definition at line 38 of file complex.h.

◆ type_code_id

const TypeID SymEngine::Complex::type_code_id = SYMENGINE_COMPLEX
static

Type_code_id shared by all instances

Definition at line 42 of file complex.h.


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