2#include <symengine/printers/strprinter.h>
10 bool operator()(
const RCP<const Basic> &x,
const RCP<const Basic> &
y)
const
14 return x->__cmp__(*
y) == -1;
21 "| __|_ _ _____| __|___ ___|_|___ ___ \n"
22 "|__ | | | | __| | . | | | -_|\n"
23 "|_____|_ |_|_|_|_____|_|_|_ |_|_|_|___|\n"
28void Precedence::bvisit(
const Add &x)
30 precedence = PrecedenceEnum::Add;
33void Precedence::bvisit(
const Mul &x)
35 precedence = PrecedenceEnum::Mul;
38void Precedence::bvisit(
const Relational &x)
40 precedence = PrecedenceEnum::Relational;
43void Precedence::bvisit(
const Pow &x)
45 precedence = PrecedenceEnum::Pow;
48void Precedence::bvisit(
const GaloisField &x)
54void Precedence::bvisit(
const Rational &x)
56 precedence = PrecedenceEnum::Add;
59void Precedence::bvisit(
const Complex &x)
62 if (x.imaginary_ == 1) {
63 precedence = PrecedenceEnum::Atom;
65 precedence = PrecedenceEnum::Mul;
68 precedence = PrecedenceEnum::Add;
72void Precedence::bvisit(
const Integer &x)
74 if (x.is_negative()) {
75 precedence = PrecedenceEnum::Mul;
77 precedence = PrecedenceEnum::Atom;
81void Precedence::bvisit(
const RealDouble &x)
83 if (x.is_negative()) {
84 precedence = PrecedenceEnum::Mul;
86 precedence = PrecedenceEnum::Atom;
90#ifdef HAVE_SYMENGINE_PIRANHA
93 precedence = PrecedenceEnum::Add;
98 precedence = PrecedenceEnum::Add;
101void Precedence::bvisit(
const ComplexDouble &x)
103 precedence = PrecedenceEnum::Add;
105#ifdef HAVE_SYMENGINE_MPFR
106void Precedence::bvisit(
const RealMPFR &x)
108 if (x.is_negative()) {
109 precedence = PrecedenceEnum::Mul;
111 precedence = PrecedenceEnum::Atom;
115#ifdef HAVE_SYMENGINE_MPC
116void Precedence::bvisit(
const ComplexMPC &x)
118 precedence = PrecedenceEnum::Add;
122void Precedence::bvisit(
const Basic &x)
124 precedence = PrecedenceEnum::Atom;
127PrecedenceEnum Precedence::getPrecedence(
const RCP<const Basic> &x)
133void StrPrinter::bvisit(
const Basic &x)
136 s <<
"<" <<
typeName<Basic>(x) <<
" instance at " << (
const void *)
this
141void StrPrinter::bvisit(
const Symbol &x)
146void StrPrinter::bvisit(
const Infty &x)
149 if (x.is_negative_infinity())
151 else if (x.is_positive_infinity())
158void StrPrinter::bvisit(
const NaN &x)
163void StrPrinter::bvisit(
const Integer &x)
166 s << x.as_integer_class();
170void StrPrinter::bvisit(
const Rational &x)
173 s << x.as_rational_class();
177void StrPrinter::bvisit(
const Complex &x)
183 if (mp_sign(x.imaginary_) == 1) {
189 if (x.imaginary_ != mp_sign(x.imaginary_)) {
190 s << mp_abs(x.imaginary_);
191 s << print_mul() << get_imag_symbol();
196 if (x.imaginary_ != mp_sign(x.imaginary_)) {
198 s << print_mul() << get_imag_symbol();
200 if (mp_sign(x.imaginary_) == 1) {
201 s << get_imag_symbol();
203 s <<
"-" << get_imag_symbol();
216 if (str_.find(
".") == std::string::npos
217 and str_.find(
"e") == std::string::npos) {
227void StrPrinter::bvisit(
const RealDouble &x)
229 str_ = print_double(x.i);
232void StrPrinter::bvisit(
const ComplexDouble &x)
234 str_ = print_double(x.i.real());
235 if (x.i.imag() < 0) {
236 str_ +=
" - " + print_double(-x.i.imag()) + print_mul()
239 str_ +=
" + " + print_double(x.i.imag()) + print_mul()
244void StrPrinter::bvisit(
const Equality &x)
247 s << apply(x.get_arg1()) <<
" == " << apply(x.get_arg2());
251void StrPrinter::bvisit(
const Unequality &x)
254 s << apply(x.get_arg1()) <<
" != " << apply(x.get_arg2());
258void StrPrinter::bvisit(
const LessThan &x)
261 s << apply(x.get_arg1()) <<
" <= " << apply(x.get_arg2());
265void StrPrinter::bvisit(
const StrictLessThan &x)
268 s << apply(x.get_arg1()) <<
" < " << apply(x.get_arg2());
272void StrPrinter::bvisit(
const Interval &x)
275 if (x.get_left_open())
279 s << *x.get_start() <<
", " << *x.get_end();
280 if (x.get_right_open())
287void StrPrinter::bvisit(
const BooleanAtom &x)
296void StrPrinter::bvisit(
const And &x)
303 s <<
", " << apply(*
it);
309void StrPrinter::bvisit(
const Or &x)
316 s <<
", " << apply(*
it);
322void StrPrinter::bvisit(
const Xor &x)
329 s <<
", " << apply(*
it);
335void StrPrinter::bvisit(
const Not &x)
338 s <<
"Not(" << *x.get_arg() <<
")";
342void StrPrinter::bvisit(
const Contains &x)
345 s <<
"Contains(" << apply(x.get_expr()) <<
", " << apply(x.get_set())
350void StrPrinter::bvisit(
const Piecewise &x)
353 auto vec = x.get_vec();
354 auto it =
vec.begin();
358 s << apply((*it).first);
360 s << apply((*it).second);
363 if (
it !=
vec.end()) {
373void StrPrinter::bvisit(
const Complexes &x)
378void StrPrinter::bvisit(
const Reals &x)
383void StrPrinter::bvisit(
const Rationals &x)
388void StrPrinter::bvisit(
const Integers &x)
393void StrPrinter::bvisit(
const Naturals &x)
398void StrPrinter::bvisit(
const Naturals0 &x)
403void StrPrinter::bvisit(
const EmptySet &x)
408void StrPrinter::bvisit(
const Union &x)
411 s << apply(*x.get_container().begin());
412 for (
auto it = ++(x.get_container().begin());
it != x.get_container().end();
414 s <<
" U " << apply(*
it);
419void StrPrinter::bvisit(
const Intersection &x)
422 vec_basic
vec = x.get_args();
424 s << parenthesize(apply(
vec));
428void StrPrinter::bvisit(
const Complement &x)
431 s << apply(*x.get_universe());
432 s <<
" \\ " << apply(*x.get_container());
436void StrPrinter::bvisit(
const ImageSet &x)
439 s <<
"{" << apply(*x.get_expr()) <<
" | ";
440 s << apply(*x.get_symbol());
441 s <<
" in " << apply(*x.get_baseset()) <<
"}";
445void StrPrinter::bvisit(
const UniversalSet &x)
447 str_ =
"UniversalSet";
450void StrPrinter::bvisit(
const FiniteSet &x)
453 s << x.get_container();
457void StrPrinter::bvisit(
const ConditionSet &x)
460 s <<
"{" << apply(*x.get_symbol());
461 s <<
" | " << apply(x.get_condition()) <<
"}";
465#ifdef HAVE_SYMENGINE_MPFR
466void StrPrinter::bvisit(
const RealMPFR &x)
472 / 3.3219280948873626)
478 if (str_.at(0) ==
'-') {
480 str_ = str_.substr(1, str_.length() - 1);
483 s << str_.at(0) <<
'.' << str_.substr(1, str_.length() - 1) <<
'e'
486 s << str_.substr(0, (
unsigned long)
ex) <<
".";
487 s << str_.substr((
unsigned long)
ex, str_.length() -
ex);
488 }
else if (
ex > -5) {
490 for (
int i = 0; i < -
ex; ++i) {
495 s << str_.at(0) <<
'.' << str_.substr(1, str_.length() - 1) <<
'e'
502#ifdef HAVE_SYMENGINE_MPC
503void StrPrinter::bvisit(
const ComplexMPC &x)
505 RCP<const Number> imag = x.imaginary_part();
506 if (imag->is_negative()) {
508 str = str.substr(1, str.length() - 1);
509 str_ = this->apply(x.real_part()) +
" - " + str + print_mul()
512 str_ = this->apply(x.real_part()) +
" + " + this->apply(imag)
513 + print_mul() + get_imag_symbol();
517void StrPrinter::bvisit(
const Add &x)
522 x.get_dict().begin(), x.get_dict().end());
524 if (
neq(*(x.get_coef()), *zero)) {
525 o << this->apply(x.get_coef());
528 for (
const auto &p : dict) {
530 if (
eq(*(p.second), *one)) {
531 t = parenthesizeLT(p.first, PrecedenceEnum::Add);
532 }
else if (
eq(*(p.second), *minus_one)) {
533 t =
"-" + parenthesizeLT(p.first, PrecedenceEnum::Mul);
535 t = parenthesizeLT(p.second, PrecedenceEnum::Mul) + print_mul()
536 + parenthesizeLT(p.first, PrecedenceEnum::Mul);
554 const RCP<const Basic> &b)
557 o <<
"exp(" << apply(b) <<
")";
559 o <<
"sqrt(" << apply(a) <<
")";
561 o << parenthesizeLE(a, PrecedenceEnum::Pow);
563 o << parenthesizeLE(b, PrecedenceEnum::Pow);
567void StrPrinter::bvisit(
const Mul &x)
573 if (
eq(*(x.get_coef()), *minus_one)) {
575 }
else if (
neq(*(x.get_coef()), *one)) {
576 if (
not split_mul_coef()) {
577 o << parenthesizeLT(x.get_coef(), PrecedenceEnum::Mul)
582 as_numer_denom(x.get_coef(), outArg(
numer), outArg(
denom));
585 o << parenthesizeLT(
numer, PrecedenceEnum::Mul) << print_mul();
589 o2 << parenthesizeLT(
denom, PrecedenceEnum::Mul) << print_mul();
594 for (
const auto &p : x.get_dict()) {
597 and neq(*(p.first), *E)) {
598 if (
eq(*(p.second), *minus_one)) {
599 o2 << parenthesizeLT(p.first, PrecedenceEnum::Mul);
601 _print_pow(
o2, p.first,
neg(p.second));
606 if (
eq(*(p.second), *one)) {
607 o << parenthesizeLT(p.first, PrecedenceEnum::Mul);
609 _print_pow(
o, p.first, p.second);
617 o <<
"1" << print_mul();
627 str_ = print_div(s,
s2,
true);
629 str_ = print_div(s,
s2,
false);
640 return num +
"/" + parenthesize(
den);
646bool StrPrinter::split_mul_coef()
651void StrPrinter::bvisit(
const Pow &x)
654 _print_pow(
o, x.get_base(), x.get_exp());
659char _print_sign(
const T &i)
668void StrPrinter::bvisit(
const GaloisField &x)
675 auto dict = x.get_dict();
676 if (x.get_dict().size() == 0)
679 for (
auto it = dict.size();
it-- != 0;) {
687 s <<
" " << _print_sign(dict[
it]) <<
" "
694 if (mp_abs(dict[
it]) == 1) {
700 s << detail::poly_print(x.get_var());
702 s <<
" " << _print_sign(dict[
it]) <<
" "
703 << detail::poly_print(x.get_var());
711 s << dict[
it] <<
"*" << detail::poly_print(x.get_var());
713 s <<
" " << _print_sign(dict[
it]) <<
" " << mp_abs(dict[
it])
714 <<
"*" << detail::poly_print(x.get_var());
739 for (
auto it = x.obegin();
it != x.oend(); ++
it) {
742 if (
it->first == 0) {
746 s <<
" " << _print_sign(m) <<
" " << mp_abs(m);
752 if (mp_abs(m) == 1) {
758 s << detail::poly_print(x.get_var());
760 s <<
" " << _print_sign(m) <<
" "
761 << detail::poly_print(x.get_var());
769 s << m <<
"*" << detail::poly_print(x.get_var());
771 s <<
" " << _print_sign(m) <<
" " << mp_abs(m) <<
"*"
772 << detail::poly_print(x.get_var());
776 if (
it->first != 1) {
777 s <<
"**" <<
it->first;
787void StrPrinter::bvisit(
const UIntPoly &x)
792void StrPrinter::bvisit(
const URatPoly &x)
797#ifdef HAVE_SYMENGINE_FLINT
808#ifdef HAVE_SYMENGINE_PIRANHA
821void StrPrinter::bvisit(
const UExprPoly &x)
824 if (x.get_dict().size() == 0)
827 s << x.get_poly().__str__(detail::poly_print(x.get_var()));
831void StrPrinter::bvisit(
const UnivariateSeries &x)
834 o << x.get_poly().__str__(x.get_var()) <<
" + O(" << x.get_var() <<
"**"
835 << x.get_degree() <<
")";
839#ifdef HAVE_SYMENGINE_PIRANHA
843 o << x.get_poly() <<
" + O(" << x.get_var() <<
"**" << x.get_degree()
850 o << x.get_poly() <<
" + O(" << x.get_var() <<
"**" << x.get_degree()
856void StrPrinter::bvisit(
const Constant &x)
864 for (
auto p =
d.begin(); p !=
d.end(); p++) {
865 if (p !=
d.begin()) {
868 o << this->apply(*p);
873void StrPrinter::bvisit(
const Function &x)
877 o << names_[x.get_type_code()];
878 vec_basic
vec = x.get_args();
879 o << parenthesize(apply(
vec));
883void StrPrinter::bvisit(
const FunctionSymbol &x)
887 vec_basic
vec = x.get_args();
888 o << parenthesize(apply(
vec));
892void StrPrinter::bvisit(
const Derivative &x)
895 o <<
"Derivative(" << this->apply(x.get_arg());
896 auto m1 = x.get_symbols();
897 for (
const auto &
elem :
m1) {
898 o <<
", " << this->apply(
elem);
904void StrPrinter::bvisit(
const Subs &x)
907 for (
auto p = x.get_dict().begin(); p != x.get_dict().end(); p++) {
908 if (p != x.get_dict().begin()) {
912 vars << apply(p->first);
913 point << apply(p->second);
915 o <<
"Subs(" << apply(x.get_arg()) <<
", (" <<
vars.str() <<
"), ("
916 <<
point.str() <<
"))";
920void StrPrinter::bvisit(
const NumberWrapper &x)
925void StrPrinter::bvisit(
const MIntPoly &x)
933 for (vec_uint
exps : v) {
934 integer_class
c = x.get_poly().dict_.find(
exps)->second;
936 s <<
" " << _print_sign(
c) <<
" ";
944 for (
auto it : x.get_vars()) {
956 if (mp_abs(
c) != 1) {
958 if (!
expr.str().empty()) {
961 }
else if (
expr.str().empty()) {
973void StrPrinter::bvisit(
const MExprPoly &x)
981 for (vec_int
exps : v) {
982 Expression
c = x.get_poly().dict_.find(
exps)->second;
983 std::string t = parenthesizeLT(
c.get_basic(), PrecedenceEnum::Mul);
984 if (
'-' == t[0] && !
first) {
993 for (
auto it : x.get_vars()) {
1005 if (
c != 1 &&
c != -1) {
1007 if (!
expr.str().empty()) {
1010 }
else if (
expr.str().empty()) {
1017 if (s.
str().empty())
1022void StrPrinter::bvisit(
const Tuple &x)
1025 vec_basic
vec = x.get_args();
1026 o << parenthesize(apply(
vec));
1030void StrPrinter::bvisit(
const IdentityMatrix &x)
1035void StrPrinter::bvisit(
const ZeroMatrix &x)
1040std::string StrPrinter::parenthesizeLT(
const RCP<const Basic> &x,
1045 return parenthesize(apply(x));
1051std::string StrPrinter::parenthesizeLE(
const RCP<const Basic> &x,
1056 return parenthesize(apply(x));
1064 return "(" + x +
")";
1067std::string StrPrinter::apply(
const RCP<const Basic> &b)
1143 const RCP<const Basic> &a,
1144 const RCP<const Basic> &b)
1147 o <<
"exp(" << apply(b) <<
")";
1149 o <<
"sqrt(" << apply(a) <<
")";
1151 o << parenthesizeLE(a, PrecedenceEnum::Pow);
1153 o << parenthesizeLE(b, PrecedenceEnum::Pow);
1157void JuliaStrPrinter::bvisit(
const Constant &x)
1162 str_ = x.get_name();
1163 std::transform(str_.begin(), str_.end(), str_.begin(), ::tolower);
1167void JuliaStrPrinter::bvisit(
const NaN &x)
1172void JuliaStrPrinter::bvisit(
const Infty &x)
1175 if (x.is_negative_infinity())
1177 else if (x.is_positive_infinity())
Main namespace for SymEngine package.
bool eq(const Basic &a, const Basic &b)
Checks equality for a and b
void hash_combine(hash_t &seed, const T &v)
RCP< const Number > rational(long n, long d)
convenience creator from two longs
bool neq(const Basic &a, const Basic &b)
Checks inequality for a and b
RCP< const Basic > neg(const RCP< const Basic > &a)
Negation.
Less operator (<) using cmp:
bool operator()(const RCP< const Basic > &x, const RCP< const Basic > &y) const
true if x < y, false otherwise