Optimize ordering of arguments in e.g. Add for LaTeX printing

69 views
Skip to first unread message

Björn Dahlgren

unread,
Jul 8, 2016, 11:45:40 AM7/8/16
to sympy
Hi,

The argument ordering of e.g. Add is lexiographical, and the printing follows the argument order:

>>> (y-x)*(z-y)
(-x + y)⋅(-y + z)

is there already functionality to have the printing system reorder arguments to minimize number of signs printed?
(I am generating LaTeX expressions and I'd rather avoid editing them by hand).

Best regards,
Björn

Aaron Meurer

unread,
Jul 8, 2016, 3:53:38 PM7/8/16
to sy...@googlegroups.com
Isn't just a question of picking a nonnegative term to go first?

Aaron Meurer

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/a4d0ec78-c065-4894-9582-a5c42d8dff37%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Björn Dahlgren

unread,
Jul 8, 2016, 5:22:41 PM7/8/16
to sympy


On Friday, 8 July 2016 21:53:38 UTC+2, Aaron Meurer wrote:
Isn't just a question of picking a nonnegative term to go first?

Yes (I have some other ideas regarding optimizing the printed width of an equation too but let's skip that for now).
But how would I go about doing so? the `.args` attribute cannot be modified since it is immutable, and this doesn't help:

>>> Add(y, -x, evaluate=False)
-x + y

Aaron Meurer

unread,
Jul 8, 2016, 5:26:32 PM7/8/16
to sy...@googlegroups.com
I don't think the printing order and the args order are the same in general. You should create a custom latex printer subclass with a custom _print_Add.

Aaron Meurer

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.

Björn Dahlgren

unread,
Jul 8, 2016, 6:02:44 PM7/8/16
to sympy


On Friday, 8 July 2016 23:26:32 UTC+2, Aaron Meurer wrote:
I don't think the printing order and the args order are the same in general. You should create a custom latex printer subclass with a custom _print_Add.

Got it, thanks!

Björn Dahlgren

unread,
Jul 14, 2016, 5:07:28 AM7/14/16
to sympy
For reference (if anyone googles this):

>>> latex((y-x)*(z-y), order='old')
'\\left(y - x\\right) \\left(z - y\\right)'

Björn Dahlgren

unread,
Jul 14, 2016, 3:07:13 PM7/14/16
to sympy

That didn't work:

>>> print(latex(f(x) - 1, order='old'))
-1 + f{\left (x \right )}



 here's my next iteration

>>> from sympy.core.function import _coeff_isneg
>>> from sympy.printing.latex import LatexPrinter
>>> class MyLatexPrinter(LatexPrinter):
...    def _as_ordered_terms(self, expr, order=None):
...        return sorted(Add.make_args(expr), key=lambda arg: (_coeff_isneg(arg),) + arg.sort_key())
...
>>> print(MyLatexPrinter().doprint(f(x) - 1))
f
{\left (x \right )} - 1


Unfortunately this relies by importing a non-public function "_coeff_isneg", so no guarantee that it will keep working. I looked into the kwarg "order" used by the printers, but I didn't quite manage to figure out how to pass e.g. a callable which would let non-negativity take precedence over lexiographical order.

Aaron Meurer

unread,
Jul 14, 2016, 6:40:06 PM7/14/16
to sy...@googlegroups.com
I looked at it too and I don't think it supports a callable, but it would be nice if it did. 

Aaron Meurer

--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at https://groups.google.com/group/sympy.

Aaron Meurer

unread,
Aug 2, 2016, 7:13:30 PM8/2/16
to sy...@googlegroups.com
We should add an option to the printers to do this. I think some of
the printers (particularly the code printers) ought to do this by
default.

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages