First time here? Check out the FAQ!

Ask Your Question
1

can sage stop ordering terms?

asked 11 years ago

frnhr gravatar image

updated 10 years ago

FrédéricC gravatar image

Noob question incoming...

sage: var('A B C x y')
(A, B, C, x, y)
sage: y == (C - Ax) / B
y == -(A
x - C)/B

What I would like/expect to get here is y == (C - Ax)/B. Is there a way to tell Sage to stop ordering terms?

Rationale - the expression ultimately goes to latex() and I'd like to be able to control how the result looks like.

Preview: (hide)

3 Answers

Sort by » oldest newest most voted
2

answered 11 years ago

kcrisman gravatar image

Short answer is "probably not, unless you want to muck about in the internals of Ginac/Pynac, our symbolics engine". Even this one reorders:

sage: B.add(A,hold=True)
A + B

I think that some symbolics programs find a semi-canonical ordering and stick with that... Interestingly,

sage: C - A*x
-A*x + C

so the minus sign comes out only with the fraction. It's conceivable that one could consider this inconsistency a bug, though I am not qualified to assess that.

That said, perhaps one could make a feature request to control this, though I suspect this would be harder than one thinks.

Preview: (hide)
link

Comments

If I had to guess, I'd say that Sage tries to guess the order of each term and sorts them accordingly. `x^3` will probably come before `x^2`, etc.

frnhr gravatar imagefrnhr ( 11 years ago )
1

answered 11 years ago

ndomes gravatar image

Your example:

sage: y == C.add(-A*x,hold=True)/B
y == (C - A*x)/B

Another example:

sage: a = (-2*x).add(x^2,-x^3, hold=True); a
-2*x + x^2 - x^3

Further operations reorder the expression

sage: -2*a
2*x^3 - 2*x^2 + 4*x

You have to start with a symbolic expression:

sage: -2.mul(a,hold=True)
AttributeError: 'sage.rings.integer.Integer' object has no attribute
'mul'

sage: Expression(SR,-2).mul(a,hold=True)
-2*(-2*x + x^2 - x^3)

sage: a.mul(-2,hold=True)
-2*(-2*x + x^2 - x^3)

Don't know why kcrisman gets a reordered expression

sage: B.add(A,hold=True)
B + A
Preview: (hide)
link

Comments

This does not work for me on 5.12.

tmonteil gravatar imagetmonteil ( 11 years ago )

I used an older version (5.6)

ndomes gravatar imagendomes ( 11 years ago )

I just tried Sage Cell Server (aleph.sagemath.org) x.add(x^2,hold=True) reorders to x^2 + x

ndomes gravatar imagendomes ( 11 years ago )

Yeah, this is probably because Pynac was upgraded a few times ago.

kcrisman gravatar imagekcrisman ( 11 years ago )
1

answered 11 years ago

vdelecroix gravatar image

updated 11 years ago

Definitely we want that Sage reorders... We want A+B+A to become 2A + B...

I do not think it would be hard to manage a pretty print that put first the "positive" terms and then the negative ones (knowing that negative are considered as mul(x,-1)).

Here is a simple function that do it on the first level.

def pretty_print(E):
    if E.operator() == operator.add:
        pos = []
        neg = []
        for elt in E.operands():
            if (elt.operator() == operator.mul and elt.operands()[-1] < 0) or (elt.is_numeric() and elt < 0):
                neg.append(-elt)
            else:
                pos.append(elt)
        pos_str = ' + '.join(map(repr,pos))
        neg_str = ' + '.join(map(repr,neg))
        if len(neg) == 0:
            print pos_str
        elif len(neg) == 1:
            print pos_str + ' - ' + neg_str
        else:
            print ' + '.join(map(str,pos)) + ' - (' + ' + '.join(map(str,neg)) + ')'

    else:
        print E

Then inside Sage

sage: var('x,y,z,t')
sage: pretty_print(x-y+z)
x + z - y
sage: pretty_print(z-x-y)
z - (x + y)
sage: pretty_print(y-x-3*z+t)
t + y - (x + 3*z)
sage: pretty_print(3*x*y - 2*z*t - 3)
3*x*y - (2*t*z + 3)
Preview: (hide)
link

Comments

Eek, tree walkers! Cool stuff. Any way to make this recursive for more complicated ones? :-)

kcrisman gravatar imagekcrisman ( 11 years ago )

We definitely want B+A+B to become 2A+B, but I'm in a situation that I don't want B+2A to become 2A+B. That pretty much sums it up :) Thanks for the effort on the function! Looks good for simple expressions, though I doubt this approach can be flexible enough for more complex expressions, e.g. fractions, several parenthesis etc.

frnhr gravatar imagefrnhr ( 11 years ago )

Sure my code does not work for more complicated expressions (and I do not want to do it). If you are really interested in that feature for more complex expressions either you walk on the tree as kcricsman pointed out (.operator and .operands makes you go one level down). You could also access to ginac which is the library used for symbolic expression.

vdelecroix gravatar imagevdelecroix ( 11 years ago )

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

Stats

Asked: 11 years ago

Seen: 814 times

Last updated: Oct 25 '13