I found a solution that works for me, but since I don't understand how the 
sorting work or all the places where it fits in, I'm unsure of the merits 
of the solution.

I just made a couple changes to .as_terms from expr.py, as shown in the 
diff below.  The idea is that
1) since a given base can show up multiple times in a term, we have to add 
up the exponents from all instances, and
2) since the exponent alone doesn't distinguish x*x from x**2, we also keep 
track of how many times the base appeared.

I stored this information in a tuple so that x*x is represented by (2,2) 
and x**2 is represented by (2,1).  

With the change, an unevaluated polynomial sorts its terms in a consistent 
way.

In [4]: Add(x, x**3, x, Mul(x,x,x,evaluate=False), x, Mul(x**2,x, 
evaluate=False), x**3, evaluate=False)
Out[4]: 
           2    3    3            
x⋅x⋅x + x⋅x  + x  + x  + x + x + x

If this seems reasonable, I could make a pull request.

Duane


diff --git a/sympy/core/expr.py b/sympy/core/expr.py
index 0de02ff..c9093f0 100644
--- a/sympy/core/expr.py
+++ b/sympy/core/expr.py
@@ -928,7 +928,8 @@ def as_terms(self):
                     if factor.is_commutative:
                         base, exp = decompose_power(factor)
 
-                        cpart[base] = exp
+                        prev = cpart.get(base,(0,0))
+                        cpart[base] = (prev[0]+exp, prev[1]+1)
                         gens.add(base)
                     else:
                         ncpart.append(factor)


On Tuesday, March 31, 2015 at 5:04:37 PM UTC-5, Duane Nykamp wrote:
>
> The sort key seems insufficient for sorting unevaluated expressions.
>
> In [37]: Add(x, Mul(x,x,x,evaluate=False), x, evaluate=False)
> Out[37]: x + x⋅x⋅x + x
>
> With a slight change, it works as expected:
>
> In [38]: Add(x, Mul(x,y,x,evaluate=False), x, evaluate=False)
> Out[38]: x⋅x⋅y + x + x
>
> It seems that the sort key is the same for all three terms in the case 
> that doesn't work.
> In [43]: poly=Add(x, Mul(x,x,x,evaluate=False), x, x, evaluate=False)
>
> In [49]: terms, gens = poly.as_terms()
>
> In [56]: key, reverse = poly._parse_order(None)
>
> In [57]: key(terms[0])
> Out[57]: ((-1,), (), ((False, 0.0), (1.0, 0.0)))
>
> In [58]: key(terms[1])
> Out[58]: ((-1,), (), ((False, 0.0), (1.0, 0.0)))
>
> In [59]: key(terms[2])
> Out[59]: ((-1,), (), ((False, 0.0), (1.0, 0.0)))
>
> Since the key function completely ignores the first component of each 
> term, I'm guessing that the remaining components of the term data structure 
> all supposed to encode all the useful information.  Except for the first 
> component, each term is identical, which I believe to be the source of the 
> problem.
>
> In [68]: terms[0]
> Out[68]: (x, ((1.0, 0.0), (1, 0), ()))
>
> In [69]: terms[1]
> Out[69]: (x⋅x⋅x, ((1.0, 0.0), (1, 0), ()))
>
> In [70]: terms[2]
> Out[70]: (x, ((1.0, 0.0), (1, 0), ()))
>
> I can't say I understand all the ways in which terms are used, so I don't 
> know what would be an appropriate fix.  But, clearly, it's broken for the 
> terms one gets with unevaluated functions.
>
> Any idea on how to fix it?
>
> Duane
>

-- 
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+unsubscr...@googlegroups.com.
To post to this group, send email to sympy@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sympy/8b727451-a1b3-4c5e-820d-7f06b93db6cc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to