Program Listing for File complex.h¶
↰ Return to documentation for file (symengine/symengine/complex.h
)
#ifndef SYMENGINE_COMPLEX_H
#define SYMENGINE_COMPLEX_H
#include <symengine/rational.h>
#include <symengine/symengine_exception.h>
namespace SymEngine
{
class ComplexBase : public Number
{
public:
virtual RCP<const Number> real_part() const = 0;
virtual RCP<const Number> imaginary_part() const = 0;
bool is_re_zero() const;
};
inline bool is_a_Complex(const Basic &b)
{
return (b.get_type_code() == SYMENGINE_COMPLEX
|| b.get_type_code() == SYMENGINE_COMPLEX_MPC
|| b.get_type_code() == SYMENGINE_COMPLEX_DOUBLE);
}
class Complex : public ComplexBase
{
public:
// Complex Number is of the form `real + i(imaginary)`
rational_class real_;
rational_class imaginary_;
public:
IMPLEMENT_TYPEID(SYMENGINE_COMPLEX)
Complex(rational_class real, rational_class imaginary);
static RCP<const Number> from_mpq(const rational_class re,
const rational_class im);
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 Number> real_part() const;
virtual RCP<const Number> imaginary_part() const;
virtual RCP<const Basic> conjugate() const;
// False is returned because complex cannot be compared with zero
inline virtual bool is_positive() const
{
return false;
}
// False is returned because complex cannot be compared with zero
inline virtual bool is_negative() const
{
return false;
}
inline virtual bool is_complex() const
{
return true;
}
static RCP<const Number> from_two_rats(const Rational &re,
const Rational &im);
static RCP<const Number> from_two_nums(const Number &re, const Number &im);
virtual bool is_zero() const
{
return false;
}
virtual bool is_one() const
{
return false;
}
virtual bool is_minus_one() const
{
return false;
}
inline RCP<const Number> addcomp(const Complex &other) const
{
return from_mpq(this->real_ + other.real_,
this->imaginary_ + other.imaginary_);
}
inline RCP<const Number> addcomp(const Rational &other) const
{
return from_mpq(this->real_ + other.as_rational_class(),
this->imaginary_);
}
inline RCP<const Number> addcomp(const Integer &other) const
{
return from_mpq(this->real_ + other.as_integer_class(),
this->imaginary_);
}
inline RCP<const Number> subcomp(const Complex &other) const
{
return from_mpq(this->real_ - other.real_,
this->imaginary_ - other.imaginary_);
}
inline RCP<const Number> subcomp(const Rational &other) const
{
return from_mpq(this->real_ - other.as_rational_class(),
this->imaginary_);
}
inline RCP<const Number> subcomp(const Integer &other) const
{
return from_mpq(this->real_ - other.as_integer_class(),
this->imaginary_);
}
inline RCP<const Number> rsubcomp(const Complex &other) const
{
return from_mpq(other.real_ - this->real_,
other.imaginary_ - this->imaginary_);
}
inline RCP<const Number> rsubcomp(const Rational &other) const
{
return from_mpq(other.as_rational_class() - this->real_,
-this->imaginary_);
}
inline RCP<const Number> rsubcomp(const Integer &other) const
{
return from_mpq(other.as_integer_class() - this->real_,
-this->imaginary_);
}
inline RCP<const Number> mulcomp(const Complex &other) const
{
return from_mpq(
this->real_ * other.real_ - this->imaginary_ * other.imaginary_,
this->real_ * other.imaginary_ + this->imaginary_ * other.real_);
}
inline RCP<const Number> mulcomp(const Rational &other) const
{
return from_mpq(this->real_ * other.as_rational_class(),
this->imaginary_ * other.as_rational_class());
}
inline RCP<const Number> mulcomp(const Integer &other) const
{
return from_mpq(this->real_ * other.as_integer_class(),
this->imaginary_ * other.as_integer_class());
}
inline RCP<const Number> divcomp(const Complex &other) const
{
rational_class modulus_sq_other
= other.real_ * other.real_ + other.imaginary_ * other.imaginary_;
if (get_num(modulus_sq_other) == 0) {
rational_class modulus_sq_this
= this->real_ * this->real_
+ this->imaginary_ * this->imaginary_;
if (get_num(modulus_sq_this) == 0) {
return Nan;
} else {
return ComplexInf;
}
} else {
return from_mpq((this->real_ * other.real_
+ this->imaginary_ * other.imaginary_)
/ modulus_sq_other,
(-this->real_ * other.imaginary_
+ this->imaginary_ * other.real_)
/ modulus_sq_other);
}
}
inline RCP<const Number> divcomp(const Rational &other) const
{
if (other.is_zero()) {
rational_class modulus_sq_this
= this->real_ * this->real_
+ this->imaginary_ * this->imaginary_;
if (get_num(modulus_sq_this) == 0) {
return Nan;
} else {
return ComplexInf;
}
} else {
return from_mpq(this->real_ / other.as_rational_class(),
this->imaginary_ / other.as_rational_class());
}
}
inline RCP<const Number> divcomp(const Integer &other) const
{
if (other.is_zero()) {
rational_class modulus_sq_this
= this->real_ * this->real_
+ this->imaginary_ * this->imaginary_;
if (get_num(modulus_sq_this) == 0) {
return Nan;
} else {
return ComplexInf;
}
} else {
return from_mpq(this->real_ / other.as_integer_class(),
this->imaginary_ / other.as_integer_class());
}
}
inline RCP<const Number> rdivcomp(const Integer &other) const
{
rational_class modulus_sq_this
= this->real_ * this->real_ + this->imaginary_ * this->imaginary_;
if (get_num(modulus_sq_this) == 0) {
if (other.is_zero()) {
return Nan;
} else {
return ComplexInf;
}
} else {
return from_mpq((this->real_ * other.as_integer_class())
/ modulus_sq_this,
(this->imaginary_ * (-other.as_integer_class()))
/ modulus_sq_this);
}
}
RCP<const Number> powcomp(const Integer &other) const;
virtual RCP<const Number> add(const Number &other) const
{
if (is_a<Rational>(other)) {
return addcomp(down_cast<const Rational &>(other));
} else if (is_a<Integer>(other)) {
return addcomp(down_cast<const Integer &>(other));
} else if (is_a<Complex>(other)) {
return addcomp(down_cast<const Complex &>(other));
} else {
return other.add(*this);
}
};
virtual RCP<const Number> sub(const Number &other) const
{
if (is_a<Rational>(other)) {
return subcomp(down_cast<const Rational &>(other));
} else if (is_a<Integer>(other)) {
return subcomp(down_cast<const Integer &>(other));
} else if (is_a<Complex>(other)) {
return subcomp(down_cast<const Complex &>(other));
} else {
return other.rsub(*this);
}
};
virtual RCP<const Number> rsub(const Number &other) const
{
if (is_a<Rational>(other)) {
return rsubcomp(down_cast<const Rational &>(other));
} else if (is_a<Integer>(other)) {
return rsubcomp(down_cast<const Integer &>(other));
} else {
throw NotImplementedError("Not Implemented");
}
};
virtual RCP<const Number> mul(const Number &other) const
{
if (is_a<Rational>(other)) {
return mulcomp(down_cast<const Rational &>(other));
} else if (is_a<Integer>(other)) {
return mulcomp(down_cast<const Integer &>(other));
} else if (is_a<Complex>(other)) {
return mulcomp(down_cast<const Complex &>(other));
} else {
return other.mul(*this);
}
};
virtual RCP<const Number> div(const Number &other) const
{
if (is_a<Rational>(other)) {
return divcomp(down_cast<const Rational &>(other));
} else if (is_a<Integer>(other)) {
return divcomp(down_cast<const Integer &>(other));
} else if (is_a<Complex>(other)) {
return divcomp(down_cast<const Complex &>(other));
} else {
return other.rdiv(*this);
}
};
virtual RCP<const Number> rdiv(const Number &other) const
{
if (is_a<Integer>(other)) {
return rdivcomp(down_cast<const Integer &>(other));
} else {
throw NotImplementedError("Not Implemented");
}
};
virtual RCP<const Number> pow(const Number &other) const
{
if (is_a<Integer>(other)) {
return powcomp(down_cast<const Integer &>(other));
} else {
return other.rpow(*this);
}
};
virtual RCP<const Number> rpow(const Number &other) const
{
throw NotImplementedError("Not Implemented");
};
};
} // SymEngine
#endif