A MaplePrimes member recently asked me how to sort two sets, using the permutation of one to sort the other.  For example, given the list

L1 := [3+I, I, 2, -1, 5, 4]:

sort it according to its magnitude and then permute the second list

L2 := [a, b, c, d, e, f]:

in the same manner.

The way to accomplish that is to create a permutation of indices that sorts L1, and then apply it to both lists.  A fast way to do that is to use a variation of sorting-with-attributes, the variation being to attribute the scalar with the index rather than the original value. Thus

P := map(attributes, sort([seq(setattribute(evalf(abs(L1[i])),i), i = 1..nops(L1))]));
                            P := [2, 4, 3, 1, 6, 5]

Now use P to permute L1 and L2

[seq(L1[p], p in P)];
                             [I, -1, 2, 3 + I, 4, 5]
[seq(L2[p], p in P)];
                               [b, d, c, a, f, e]
 

Notice the call to ?evalf.  That is necessary to force the value to a float because while attributes can be attached to floats, they cannot be attached to integers. In my original email I used ?SFloat instead of evalf.  That only works properly if its argument is of ?type/numeric.  Here SFloat(sqrt(10)) appears and the resulting list, not being a list of numerics, is sorted according to its addresses rather than its values.


Please Wait...