2

I have two vectors, a and b, of the same length, each having some random order. I want a to have its same order, and for b to be sorted according to a.

So for example:

a = [5 4 1 2]
b = [7 8 9 6]

now I want the highest value of b to be in the position of the highest value of a, and the second highest value of b to be in the position of the second highest value of a, etc; that is:

b = [9 8 6 7]

I have tried

[~, indices] = sort(a)
b(indices)

but this yields

ans = [9 6 8 7]

which is clearly not right.

Any suggestions?

1
  • I want to maintain a's original order. Commented Mar 6, 2015 at 18:46

3 Answers 3

4

You're almost right. You need to sort both of the results and use indices to index into the sorted vector b. You also want to use the 'descend' flag to sort the values from highest to lowest first.

So do this:

a = [5 4 1 2];
b = [7 8 9 6];

[~,indices] = sort(a,'descend');
bsort = sort(b,'descend');
bsort(indices)

indices in this case will give you the positions of where each value in a appears in sorted form in descending order. If you want to align up the values of b so that they conform to the same order as a, you would need to sort b in descending order as well so that the values line up, then use indices to index into the sorted version of b to complete the task.

We get:

ans =

 9     8     6     7
Sign up to request clarification or add additional context in comments.

10 Comments

I was trying out something similar. Strangely enough, this only works with the descend option, not if you sort the vector in ascending order. Although you could of course obtain this behaviour using indices(end:1)
@WouterKuijsters - Yes that's what I did. You probably left that comment as I was putting in a blurb about why descend was needed.
my confusion lay mainly with the fact that sort(a,'ascend') and sort(b,'ascend') do not work - your output would become 8 9 6 7. I find it kind of strange this only works in descending order, and can't really find out why ascending doesn't work. I'm probably too tired...
@WouterKuijsters - Because the OP wants the highest values to appear first, followed by the lowest values in the end. Note that the first element of the output needs to be positioned where a has its highest value, which is why descend is needed. If the opposite problem was required, where the lowest values need to appear first, then ascend can be used.
@WouterKuijsters The 8 9 6 7 makes sense if ascending order is respected. As such, the 6 appears where the position of 1 appears in a. Similarly, the 7 appears where the position of 2 appears in a and so on. We are positioning b so the values are increasing in ascending order with respect to a. Since we want the opposite problem, we must reverse it. FWIW, I was quite confused as you were on why ascend didn't work until I worked it out on paper.
|
3

Your variable 'indices' doesn't store exactly what you expected. Revise the help of the find function. This sligtly different code may be your answer:

a = [5 4 1 2];
b = [7 8 9 6];

[~, idx] = sort(a);
b(idx) = sort(b)

Comments

2

After all, it turns out you can use the ascend option, although in a bit different way:

a=[5 5 6 3];
b=[1 2 3 4];
[asorted,indices] = sort(a,'ascend');
bsorted = sort(b,'ascend');
output(indices) = bsorted

which yields:

output =

     2     3     4     1

4 Comments

I see Jordi actually beat me to it, and his code is more efficient. Oh well, learned something anyway!
I like your answer because it's more verbose. I'm working out why mine doesn't work with duplicates.
Jordi's works with duplicates, so I have accepted it. Thanks for your help anyway though, you two.
@rhombidodecahedron - No worries. Thanks for posing an interesting problem!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.