"Desort" a vector (undo a sorting)

matlab, sorting, vectorization

Solution

The solution is:

w(ix) = v;

This is a valid Matlab operation provided that `w` is either at least as big as `v`, or not yet declared.

Example:

>> u = [4 8 10 6 2];
>> [v, ix] = sort(u)

    v = 2 4 6 8 10        
    ix = 5 1 4 2 3

>> u(ix)

    ans = 2 4 6 8 10

>> w(ix) = v

    w = 4 8 10 6 2

(Apologies for the trivial question-answer, but I realized the solution as I was typing the question, and thought it might be useful to someone.)

Problem

In Matlab, `sort` returns both the sorted vector and an index vector showing which vector element has been moved where: ``` [v, ix] = sort(u); ``` Here, `v` is a vector containing all the elements of `u`, but sorted. `ix` is a vector showing the original position of each element of `v` in `u`. Using Matlab's syntax, `u(ix) == v`. My question: How do I obtain `u` from `v` and `ix`? Of course, I could simply use: ``` w = zero(size(v)); for i = 1:length(v) w(ix(i)) = v(i) end if nnz(w == u) == length(u) print('Success!'); else print('Failed!'); end ``` But I am having this tip-of-the-tongue feeling that there is a more elegant, single-statement, vectorized way of doing this. If you are wondering why one would need to do this instead of just using `u`: I was trying to implement the Benjamini-Hochberg procedure which adjusts each element of the vector based on its position after sorting, but recovering the original order after adjusting was important for me.

Original source