Specifying term order

100 views
Skip to first unread message

David Ketcheson

unread,
Jan 16, 2013, 7:09:07 AM1/16/13
to sy...@googlegroups.com
What options are available for specifying the order in which terms are printed?  If I do

sympy.diff(f,x) + sympy.diff(f,x,2)

I get

Derivative(f(x), x) + Derivative(f(x), x, x)

but if I do

sympy.diff(f,x) + h*sympy.diff(f,x,2)

then the terms are reversed:

h*Derivative(f(x), x, x) + Derivative(f(x), x)

I think I know what the logic here is, but I'd like to order terms by increasing order of derivative (or increasing powers of h). How can I do that?

Sergiu Ivanov

unread,
Jan 16, 2013, 8:40:54 AM1/16/13
to sy...@googlegroups.com
Hello,

On Wed, Jan 16, 2013 at 04:09:07AM -0800, David Ketcheson wrote:
>
> What options are available for specifying the order in which terms are
> printed? If I do

[...]

> I think I know what the logic here is, but I'd like to order terms by
> increasing order of derivative (or increasing powers of h). How can I do
> that?

Try using the -o option of isympy:

-o ORDER, --order ORDER

Setup the ordering of terms for printing. The default is lex, which
orders terms lexicographically (e.g., x**2 + x + 1). You can choose
other orderings, such as rev-lex, which will use reverse
lexicographic ordering (e.g., 1 + x + x**2):

$isympy -o rev-lex

ORDER must be one of 'lex', 'rev-lex', 'grlex', 'rev-grlex',
'grevlex', 'rev-grevlex', 'old', or 'none'.

I believe you can also specify the ordering directly when invoking the
printing functions, which can be useful if you are not using isympy.

Sergiu

Chris Smith

unread,
Jan 16, 2013, 10:40:11 PM1/16/13
to sy...@googlegroups.com
btw, trying to sort the args yourself doesn't work because the
printers (unfortunately?) reorder them:

>>> eq
h*Derivative(f(x), x, x) + Derivative(f(x), x) + Derivative(f(x), x, x)
>>> new = Add(*ordered(eq.args, lambda w: (sum(len(d.variables) if isinstance(d, Derivative) else 0 for d in Mul.make_args(w)), sum(d.exp for d in Mul.make_args(w) if d.is_Pow and d.base == h))), evaluate=False)
>>> new.args
(Derivative(f(x), x), Derivative(f(x), x, x), h*Derivative(f(x), x, x))

Note that by using evaluate=False, the order of the actual arguments
is different but when you print them...

>>> print new
h*Derivative(f(x), x, x) + Derivative(f(x), x) + Derivative(f(x), x, x)

they come out as they did before.

Here, a string is created manually from the args in the unevaluted Add:

>>> ' + '.join(str(arg) for arg in new.args)'Derivative(f(x), x) + Derivative(f(x), x, x) + h*Derivative(f(x), x, x)'

David Ketcheson

unread,
Jan 19, 2013, 11:59:18 AM1/19/13
to sy...@googlegroups.com
Thanks, Sergiu.  I don't use isympy and I can't find any documentation of these options or how to use them directly with the print command.  Do you know where any documentation is, or do you have an example using print?

Thanks,
David

Sergiu Ivanov

unread,
Jan 21, 2013, 8:31:02 AM1/21/13
to sy...@googlegroups.com
On Sat, Jan 19, 2013 at 07:59:18PM +0300, David Ketcheson wrote:
>
> Thanks, Sergiu. I don't use isympy and I can't find any documentation of
> these options or how to use them directly with the print command. Do you
> know where any documentation is, or do you have an example using print?

I am not sure I can point you to an exact place in the docs; my
solution often consists in looking at the concerned code directly.
For example, a big part of printing can be found under
sympy/printing/.

As for your question, you may consider doing something like this:

>>> from sympy import *
>>> x = Symbol("x")
>>> x
x
>>> pprint(x**2 + x)
2
x + x
>>> pprint(x**2 + x, order='rev-lex')
2
x + x
>>>

From what I know, the supported monomial orders are exactly the same
as the ones listed in the excerpt of the source of isympy I cited in
my previous message.

Sergiu

Aaron Meurer

unread,
Feb 8, 2013, 9:28:03 PM2/8/13
to sy...@googlegroups.com
It's also possible to specify a custom ordering, depending on how much
work you want to put into this. I forget how to do it, but I think the
code is near the Groebner basis code.

You could also try subclassing the printer with a custom printer for
Add. Again, it would be more work, so it really depends on what you
need it for. If you are just doing stuff interactively (i.e., using
SymPy as a calculator), it's probably not worth it.

Aaron Meurer
Reply all
Reply to author
Forward
0 new messages