Adding python support to GiNaC
Pearu Peterson
pearu at cens.ioc.ee
Tue Dec 18 18:48:42 CET 2001
Hi!
I have been working on the python interface to GiNaC. It is quite usable
already and I have tested it in many problems. However, it would be great
if some python specific changes that I had to do in GiNaC, could be added
to GiNaC. These changes include mostly printing expressions. Earlier I
used hooks from GiNaC archive features to get desired output for python,
but it was _very_ slow compared to the native GiNaC print hooks.
So, please find a patch attached that adds two new print_context classes,
print_python and print_python_repr, with the corresponding additions to
print methods of the basic classes.
The patch includes also the following change in the idx::print method for
print_latex context: `a.b' becomes `a_{b}' if b is covariant, `a^{b}',
otherwise (you can ignore it if you don't like it).
This patch is against GiNaC-1.0.1. I can make it also against the
latest GiNaC in CVS. Let me know if needed.
Thanks,
Pearu
-------------- next part --------------
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/add.cpp GiNaC-1.0.1-print_python/ginac/add.cpp
--- GiNaC/ginac/add.cpp Thu Nov 22 19:15:03 2001
+++ GiNaC-1.0.1-print_python/ginac/add.cpp Fri Nov 23 16:28:09 2001
@@ -155,7 +155,16 @@
if (precedence() <= level)
c.s << ")";
-
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << '(';
+ unsigned end = nops();
+ if (end)
+ op(0).print(c);
+ for (unsigned i=1; i<end; ++i) {
+ c.s << ',';
+ op(i).print(c);
+ }
+ c.s << ')';
} else {
if (precedence() <= level) {
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/constant.cpp GiNaC-1.0.1-print_python/ginac/constant.cpp
--- GiNaC/ginac/constant.cpp Thu Nov 22 19:15:04 2001
+++ GiNaC-1.0.1-print_python/ginac/constant.cpp Fri Nov 23 20:58:47 2001
@@ -136,7 +136,12 @@
<< std::endl;
} else if (is_a<print_latex>(c))
c.s << TeX_name;
- else
+ else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << "('" << name << "'";
+ if (TeX_name != "\\mbox{" + name + "}")
+ c.s << ",TeX_name='" << TeX_name << "'";
+ c.s << ')';
+ } else
c.s << name;
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/container.pl GiNaC-1.0.1-print_python/ginac/container.pl
--- GiNaC/ginac/container.pl Fri Oct 26 17:08:24 2001
+++ GiNaC-1.0.1-print_python/ginac/container.pl Fri Nov 23 17:41:39 2001
@@ -430,7 +430,11 @@
++i;
}
c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
-
+ } else if (is_a<print_python>(c)) {
+ printseq(c, '[', ',', ']', precedence(), precedence()+1);
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name ();
+ printseq(c, '(', ',', ')', precedence(), precedence()+1);
} else {
// always print brackets around seq, ignore upper_precedence
printseq(c, '${open_bracket}', ',', '${close_bracket}', precedence(), precedence()+1);
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/exprseq.cpp GiNaC-1.0.1-print_python/ginac/exprseq.cpp
--- GiNaC/ginac/exprseq.cpp Tue Nov 20 11:00:11 2001
+++ GiNaC-1.0.1-print_python/ginac/exprseq.cpp Fri Nov 23 18:11:55 2001
@@ -345,7 +345,11 @@
++i;
}
c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
-
+ } else if (is_a<print_python>(c)) {
+ printseq(c, '[', ',', ']', precedence(), precedence()+1);
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name ();
+ printseq(c, '(', ',', ')', precedence(), precedence()+1);
} else {
// always print brackets around seq, ignore upper_precedence
printseq(c, '(', ',', ')', precedence(), precedence()+1);
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/idx.cpp GiNaC-1.0.1-print_python/ginac/idx.cpp
--- GiNaC/ginac/idx.cpp Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/idx.cpp Fri Nov 23 17:36:39 2001
@@ -156,7 +156,9 @@
} else {
- if (!is_of_type(c, print_latex))
+ if (is_a<print_latex>(c))
+ c.s << "_{";
+ else
c.s << ".";
bool need_parens = !(is_ex_exactly_of_type(value, numeric) || is_ex_of_type(value, symbol));
if (need_parens)
@@ -164,6 +166,8 @@
value.print(c);
if (need_parens)
c.s << ")";
+ if (is_a<print_latex>(c))
+ c.s << "}";
}
}
@@ -180,8 +184,13 @@
dim.print(c, level + delta_indent);
} else {
-
- if (!is_of_type(c, print_latex)) {
+ if (is_a<print_latex>(c)) {
+ if (covariant)
+ c.s << "_{";
+ else
+ c.s << "^{";
+ }
+ else {
if (covariant)
c.s << ".";
else
@@ -193,6 +202,8 @@
value.print(c);
if (need_parens)
c.s << ")";
+ if (is_a<print_latex>(c))
+ c.s << "}";
}
}
@@ -212,7 +223,12 @@
} else {
bool is_tex = is_of_type(c, print_latex);
- if (!is_tex) {
+ if (is_tex) {
+ if (covariant)
+ c.s << "_{";
+ else
+ c.s << "^{";
+ } else {
if (covariant)
c.s << ".";
else
@@ -231,6 +247,8 @@
if (need_parens)
c.s << ")";
if (is_tex && dotted)
+ c.s << "}";
+ if (is_tex)
c.s << "}";
}
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/lst.cpp GiNaC-1.0.1-print_python/ginac/lst.cpp
--- GiNaC/ginac/lst.cpp Tue Nov 20 11:00:11 2001
+++ GiNaC-1.0.1-print_python/ginac/lst.cpp Fri Nov 23 18:11:55 2001
@@ -345,7 +345,11 @@
++i;
}
c.s << std::string(level + delta_indent,' ') << "=====" << std::endl;
-
+ } else if (is_a<print_python>(c)) {
+ printseq(c, '[', ',', ']', precedence(), precedence()+1);
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name ();
+ printseq(c, '(', ',', ')', precedence(), precedence()+1);
} else {
// always print brackets around seq, ignore upper_precedence
printseq(c, '{', ',', '}', precedence(), precedence()+1);
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/matrix.cpp GiNaC-1.0.1-print_python/ginac/matrix.cpp
--- GiNaC/ginac/matrix.cpp Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/matrix.cpp Fri Nov 23 17:44:47 2001
@@ -147,6 +147,9 @@
} else {
+ if (is_a<print_python_repr>(c))
+ c.s << class_name() << '(';
+
c.s << "[";
for (unsigned y=0; y<row-1; ++y) {
c.s << "[";
@@ -164,6 +167,9 @@
}
m[row*col-1].print(c);
c.s << "]]";
+
+ if (is_a<print_python_repr>(c))
+ c.s << ')';
}
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/mul.cpp GiNaC-1.0.1-print_python/ginac/mul.cpp
--- GiNaC/ginac/mul.cpp Thu Nov 22 19:15:04 2001
+++ GiNaC-1.0.1-print_python/ginac/mul.cpp Fri Nov 23 16:28:32 2001
@@ -168,7 +168,16 @@
if (precedence() <= level)
c.s << ")";
-
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << '(';
+ unsigned end = nops();
+ if (end)
+ op(0).print(c);
+ for (unsigned i=1; i<end; ++i) {
+ c.s << ',';
+ op(i).print(c);
+ }
+ c.s << ')';
} else {
if (precedence() <= level) {
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/ncmul.cpp GiNaC-1.0.1-print_python/ginac/ncmul.cpp
--- GiNaC/ginac/ncmul.cpp Fri Oct 26 17:08:24 2001
+++ GiNaC-1.0.1-print_python/ginac/ncmul.cpp Fri Nov 23 16:38:15 2001
@@ -111,9 +111,9 @@
inherited::print(c, level);
- } else if (is_a<print_csrc>(c)) {
+ } else if (is_a<print_csrc>(c) || is_a<print_python_repr>(c)) {
- c.s << "ncmul(";
+ c.s << class_name() << "(";
exvector::const_iterator it = seq.begin(), itend = seq.end()-1;
while (it != itend) {
it->print(c, precedence());
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/numeric.cpp GiNaC-1.0.1-print_python/ginac/numeric.cpp
--- GiNaC/ginac/numeric.cpp Tue Nov 6 17:55:29 2001
+++ GiNaC-1.0.1-print_python/ginac/numeric.cpp Fri Nov 23 17:46:43 2001
@@ -389,6 +389,8 @@
const std::string mul_sym = is_a<print_latex>(c) ? " " : "*";
const cln::cl_R r = cln::realpart(cln::the<cln::cl_N>(value));
const cln::cl_R i = cln::imagpart(cln::the<cln::cl_N>(value));
+ if (is_a<print_python_repr>(c))
+ c.s << class_name() << "('";
if (cln::zerop(i)) {
// case 1, real: x or -x
if ((precedence() <= level) && (!this->is_nonneg_integer())) {
@@ -446,6 +448,8 @@
c.s << par_close;
}
}
+ if (is_a<print_python_repr>(c))
+ c.s << "')";
}
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/power.cpp GiNaC-1.0.1-print_python/ginac/power.cpp
--- GiNaC/ginac/power.cpp Fri Oct 26 17:08:24 2001
+++ GiNaC-1.0.1-print_python/ginac/power.cpp Fri Nov 23 21:30:11 2001
@@ -159,6 +159,14 @@
c.s << ')';
}
+ } else if (is_a<print_python_repr>(c)) {
+
+ c.s << class_name() << '(';
+ basis.print(c);
+ c.s << ',';
+ exponent.print(c);
+ c.s << ')';
+
} else {
if (exponent.is_equal(_ex1_2)) {
@@ -179,7 +187,10 @@
c.s << "(";
}
basis.print(c, precedence());
- c.s << '^';
+ if (is_a<print_python>(c))
+ c.s << "**";
+ else
+ c.s << '^';
if (is_a<print_latex>(c))
c.s << '{';
exponent.print(c, precedence());
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/print.cpp GiNaC-1.0.1-print_python/ginac/print.cpp
--- GiNaC/ginac/print.cpp Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/print.cpp Fri Nov 23 14:01:57 2001
@@ -36,6 +36,16 @@
print_latex::print_latex(std::ostream & os)
: print_context(os) {}
+print_python::print_python()
+ : print_context(std::cout) {}
+print_python::print_python(std::ostream & os)
+ : print_context(os) {}
+
+print_python_repr::print_python_repr()
+ : print_context(std::cout) {}
+print_python_repr::print_python_repr(std::ostream & os)
+ : print_context(os) {}
+
print_tree::print_tree(unsigned d)
: print_context(std::cout), delta_indent(d) {}
print_tree::print_tree(std::ostream & os, unsigned d)
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/print.h GiNaC-1.0.1-print_python/ginac/print.h
--- GiNaC/ginac/print.h Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/print.h Sat Nov 24 10:35:57 2001
@@ -49,6 +49,22 @@
print_latex(std::ostream &);
};
+/** Context for python pretty-print output. */
+class print_python : public print_context
+{
+public:
+ print_python();
+ print_python(std::ostream &);
+};
+
+/** Context for python-parsable output. */
+class print_python_repr : public print_context
+{
+public:
+ print_python_repr();
+ print_python_repr(std::ostream &);
+};
+
/** Context for tree-like output for debugging. */
class print_tree : public print_context
{
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/pseries.cpp GiNaC-1.0.1-print_python/ginac/pseries.cpp
--- GiNaC/ginac/pseries.cpp Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/pseries.cpp Tue Nov 27 11:40:46 2001
@@ -133,7 +133,23 @@
}
var.print(c, level + delta_indent);
point.print(c, level + delta_indent);
-
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << "(relational(";
+ var.print(c);
+ c.s << ',';
+ point.print(c);
+ c.s << "),[";
+ unsigned num = seq.size();
+ for (unsigned i=0; i<num; ++i) {
+ if (i)
+ c.s << ',';
+ c.s << '(';
+ seq[i].rest.print(c);
+ c.s << ',';
+ seq[i].coeff.print(c);
+ c.s << ')';
+ }
+ c.s << "])";
} else {
if (precedence() <= level)
@@ -174,7 +190,10 @@
} else
var.print(c);
if (i->coeff.compare(_ex1)) {
- c.s << '^';
+ if (is_a<print_python>(c))
+ c.s << "**";
+ else
+ c.s << '^';
if (i->coeff.info(info_flags::negative)) {
c.s << par_open;
i->coeff.print(c);
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/relational.cpp GiNaC-1.0.1-print_python/ginac/relational.cpp
--- GiNaC/ginac/relational.cpp Thu Nov 22 19:15:15 2001
+++ GiNaC-1.0.1-print_python/ginac/relational.cpp Fri Nov 23 20:36:26 2001
@@ -95,9 +95,17 @@
} else {
- if (precedence() <= level)
- c.s << "(";
- lh.print(c, precedence());
+ if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << '(';
+ lh.print(c);
+ c.s << ',';
+ rh.print(c);
+ c.s << ",'";
+ } else {
+ if (precedence() <= level)
+ c.s << "(";
+ lh.print(c, precedence());
+ }
switch (o) {
case equal:
c.s << "==";
@@ -120,9 +128,13 @@
default:
c.s << "(INVALID RELATIONAL OPERATOR)";
}
- rh.print(c, precedence());
- if (precedence() <= level)
- c.s << ")";
+ if (is_a<print_python_repr>(c))
+ c.s << "')";
+ else {
+ rh.print(c, precedence());
+ if (precedence() <= level)
+ c.s << ")";
+ }
}
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/symbol.cpp GiNaC-1.0.1-print_python/ginac/symbol.cpp
--- GiNaC/ginac/symbol.cpp Fri Oct 26 17:08:25 2001
+++ GiNaC-1.0.1-print_python/ginac/symbol.cpp Fri Nov 23 18:00:58 2001
@@ -153,7 +153,12 @@
} else if (is_a<print_latex>(c))
c.s << TeX_name;
- else
+ else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << "('" << name;
+ if (TeX_name != default_TeX_name())
+ c.s << "','" << TeX_name;
+ c.s << "')";
+ } else
c.s << name;
}
diff -Nau -x CVS -x .libs -x .deps -x *.o -x *.lo -x *.la -x *~ -x Makefile GiNaC/ginac/wildcard.cpp GiNaC-1.0.1-print_python/ginac/wildcard.cpp
--- GiNaC/ginac/wildcard.cpp Sat Oct 27 18:18:57 2001
+++ GiNaC-1.0.1-print_python/ginac/wildcard.cpp Fri Nov 23 18:07:48 2001
@@ -95,6 +95,8 @@
c.s << std::string(level, ' ') << class_name() << " (" << label << ")"
<< std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
<< std::endl;
+ } else if (is_a<print_python_repr>(c)) {
+ c.s << class_name() << '(' << label << ')';
} else
c.s << "$" << label;
}
More information about the GiNaC-devel
mailing list