Thanks for the tip about making a Symbol real.  That is easily fixed, 
though.  I can simply test 
if x.is_number and x.is_real 

Or, I discovered the attribute .is_comparable.  So it seems there are two 
reasonable options.  

1.  Test if x.is_number and x_is_real.  If so, create a sort key for number.

 Or,

2.  Test if x.is_comparable.  If so, create a sort key for number.

In either case, return default_sort_key if condition is not met.

You raise some concerns about .as_real_imag being slow.  So, if that is the 
case, then it could be that option 2 is slow, as .is_comparable is based on 
.as_real_imag.  However, I don't see what objections can be made to option 
1, except that it does not cover cases like (I*exp_polar(I*pi/2)).  Are 
there cases where the standard default_sort_key works better than option 
1?  To my naive understanding, it does everything that .default_sort_key 
does while preserving the ordering of real numbers.  (I'm not worried about 
how it sorts complex numbers.  I suppose it would take some more logic to 
get purely imaginary numbers sorted like their real counterparts.  But, to 
me, what is important is getting real numbers sorted as expected.)

For example, with option 1 written as

def customized_sort_key(item, order=None):
    try:
        x=sympify(item)
    except:
        pass
    else:
        if x.is_real and x.is_number:
            return  ((1, 0, 'Number'), (0, ()), (), x)
    return default_sort_key(item, order)

I get the following results:

n [4]: l2 = [1 - sqrt(2), 1, pi, 4, 1 + sqrt(2)] 

In [5]: lx = [1 - sqrt(x), 1, pi, 4, 1 + sqrt(x)] 

In [6]: l2I = map(lambda x: x + I, l2) 

In [7]: lxI = map(lambda x: x + I, lx) 

In [8]: sorted(l2, key=customized_sort_key)
Out[8]: [-sqrt(2) + 1, 1, 1 + sqrt(2), pi, 4]

In [9]: sorted(lx, key=customized_sort_key)
Out[9]: [1, pi, 4, -sqrt(x) + 1, sqrt(x) + 1]

In [10]: sorted(l2I, key=customized_sort_key)
Out[10]: [1 + I, 4 + I, pi + I, 1 + sqrt(2) + I, -sqrt(2) + 1 + I]

In [11]: sorted(lxI, key=customized_sort_key)
Out[11]: [1 + I, 4 + I, pi + I, -sqrt(x) + 1 + I, sqrt(x) + 1 + I]


I guess the one objection I can see to this solution is that it is not 
applied recursively.  It doesn't use the same logic, for example, on 
numbers within Tuples or for coefficients of terms with symbols.  But, if 
one just does solution 1 recursively, then it shouldn't be slower than the 
default, should it?

Thanks,
Duane


On Monday, October 20, 2014 5:48:47 AM UTC-5, Mateusz Paprocki wrote:
>
> Hi, 
>
> On 19 October 2014 05:40, Duane Nykamp <[email protected] <javascript:>> 
> wrote: 
> > Here's my solution for a customized sort key.  Does this seem 
> reasonable?  I 
> > just copied the format for the sort key for numbers and applied it to 
> > anything that was real.  It seems to work how I'd want it to work. 
> > 
> > 
> > def customized_sort_key(item, order=None): 
> > 
> >     try: 
> >         x=sympify(item) 
> >     except: 
> >         pass 
> >     else: 
> >         if x.is_real: 
> >             return  ((1, 0, 'Number'), (0, ()), (), x) 
> > 
> >     return default_sort_key(item,order) 
> > 
>
> This won't work, e.g.: 
>
> In [1]: r = Symbol('r', real=True) 
>
> In [2]: r.is_real 
> Out[2]: True 
>
> Really what you should be looking into are sort_key() methods defined 
> all over sympy. default_sort_key() is just a convenience function that 
> allows to handle non-Basic objects as well, thus being usable as a key 
> to sorted(). 
>
> Defining the default sort key isn't that simple, e.g.: 
>
> In [1]: l2 = [1 - sqrt(2), 1, pi, 4, 1 + sqrt(2)] 
>
> In [2]: lx = [1 - sqrt(x), 1, pi, 4, 1 + sqrt(x)] 
>
> In [3]: l2I = map(lambda x: x + I, l2) 
>
> In [4]: lxI = map(lambda x: x + I, lx) 
>
> In [5]: sorted(l2, key=default_sort_key) 
> Out[5]: 
> ⎡               ___      ___    ⎤ 
> ⎣1, 4, π, 1 + ╲╱ 2 , - ╲╱ 2  + 1⎦ 
>
> In [6]: sorted(lx, key=default_sort_key) 
> Out[6]: 
> ⎡             ___        ___    ⎤ 
> ⎣1, 4, π, - ╲╱ x  + 1, ╲╱ x  + 1⎦ 
>
> In [7]: sorted(l2I, key=default_sort_key) 
> Out[7]: 
> ⎡                           ___          ___        ⎤ 
> ⎣1 + ⅈ, 4 + ⅈ, π + ⅈ, 1 + ╲╱ 2  + ⅈ, - ╲╱ 2  + 1 + ⅈ⎦ 
>
> In [8]: sorted(lxI, key=default_sort_key) 
> Out[8]: 
> ⎡                         ___            ___        ⎤ 
> ⎣1 + ⅈ, 4 + ⅈ, π + ⅈ, - ╲╱ x  + 1 + ⅈ, ╲╱ x  + 1 + ⅈ⎦ 
>
> Will your key provide the same level of uniformity? Perhaps you could, 
> doing fair amount of symbolic processing, using as_real_imag(), etc., 
> but then you would increase cost of sort_key() considerably and, most 
> likely, make printing framework even slower than it already is. 
>
> There should be some old discussions regarding this on the mailing 
> list or in the issue tracker. At the time, it was a pretty big 
> undertaking (historically sort_key started as as_tuple_tree, so you 
> may also use this keyword). 
>
> Mateusz 
>
> > 
> > 
> > 
> > On Saturday, October 18, 2014 8:52:50 PM UTC-5, Duane Nykamp wrote: 
> >> 
> >> I was using sympy's default_sort_order to sort objects.  However, I 
> >> realized that it does not sort numerical quantities in order: 
> >> 
> >> In [15]: sorted([-1, -1-sqrt(2),1+sqrt(2), pi, 4], 
> key=default_sort_key) 
> >> Out[15]: [-1, 4, pi, 1 + sqrt(2), -sqrt(2) - 1] 
> >> 
> >> The default sort key, lex, works in this case 
> >> 
> >> In [16]: sorted([-1, -1-sqrt(2),1+sqrt(2), pi, 4]) 
> >> Out[16]: [-sqrt(2) - 1, -1, 1 + sqrt(2), pi, 4] 
> >> 
> >> but that doesn't work on symbolic objects. 
> >> 
> >> Is there a way to sort that works on all sympy objects, symbolic or 
> not, 
> >> but still produces the normal order for numerical quantities? 
> >> 
> >> The only thing I can think of is trying the lex sort key first, then 
> >> reverting to default_sort_key on TypeError.  But, that has the 
> undesirable 
> >> effect of changing the relative order of numerical quantities once a 
> >> symbolic quantity is added to the mix. 
> >> 
> >> Any suggestions or pointers to a place where this is discussed already? 
> >> 
> >> Thanks, 
> >> 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 [email protected] <javascript:>. 
> > To post to this group, send email to [email protected] 
> <javascript:>. 
> > 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/ade686f6-776c-4e6b-a34f-997918afa64c%40googlegroups.com.
>  
>
> > 
> > For more options, visit https://groups.google.com/d/optout. 
>

-- 
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 [email protected].
To post to this group, send email to [email protected].
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/23e423c6-e221-40e8-a28f-1e326f5cffdc%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to