The sort!function

In matlab, with the code

[table, ind]= sort(table)

we get not only the sorted ‘table’, but also the ‘ind’ that contains the information of the positions of the sorted elements in the original table.

What is the counterpart in julia?

With ‘sort!’, we only get the table, but not ind.

I think sortperm is what you’re looking for.

help?> sortperm
search: sortperm sortperm! partialsortperm partialsortperm! isconcretetype

  sortperm(A; alg::Algorithm=DEFAULT_UNSTABLE, lt=isless, by=identity, rev::Bool=false, order::Ordering=Forward, [dims::Integer])

  Return a permutation vector or array I that puts A[I] in sorted order along the given
  dimension. If A has more than one dimension, then the dims keyword argument must be
  specified. The order is specified using the same keywords as sort!. The permutation is
  guaranteed to be stable even if the sorting algorithm is unstable: the indices of equal
  elements will appear in ascending order.
6 Likes

thanks a lot! But it is not as convenient as matlab. In matlab, we need only one line

[table, ind]= sort(table)

Here in julia, we need two lines

ind=sortperm(table)
table = table(ind)
1 Like

Semicolons can help to write two expressions in 1 line:

ind = sortperm(table); table = table[ind]

I don’t know if it’s closer to the MATLAB variable model to do table .= table[ind] to sort table in-place, but in Julia you may need table to remain the same instance that might already be shared with other variables. It performs about the same, and there is a permute!(table, ind) that does the same thing; you can’t optimize to elementwise table .= getindex.((table,), ind) because it overwrites elements that weren’t reordered yet.

1 Like

The number of lines is one thing, but does this imply some superfluous work on the part of Julia? Could it be more efficient to sort the array and produce the indices simultaneously?

1 Like

That was assuming the sort must use ind. The more performant equivalent way would be ind = sortperm(table); sort!(table). I don’t know if it’ll be any faster if those were sorted together, or generally multiple arrays being reordered with respect to sorting one of them.

sort(tuple.(table, eachindex(table)), by=first)
collect(zip(sort(tuple.(table, eachindex(table)), by=first)...))

table, ind = (fs(t)=(table[t],t))(sortperm(table))

table, ind = (t=sortperm(table); (table[t],t))

If this desired syntax isn’t directly replicable but is particularly important to you, you can absolutely define your own convenience functions, e.g.:

function matlabsort(tbl)
    ind = sortperm(tbl)
    return (tbl[ind], ind)
end

Julia is not intended to be a 1:1 direct replacement for any other language, including Matlab. There are always going to be functions or features which don’t directly translate, and this isn’t inherently a bug, just a difference in implementation.

This seems to be one of those Matlab-isms where the returns captured from a function depend on the left-hand side of the assignment operation, i.e. tbl = sort(tbl) captures only the sorted table but [tbl,ind] = sort(tbl) captures both the table and the permuted indices. This style isn’t consistent with how code is written in Julia, where instead you’d always have to write something like (tbl, _) = sort(tbl) to disregard the unneeded returns.

In any event, as a breaking change there’s a 0% chance that modifying Base.sort like this would be accepted prior to some theoretical future v2.0 of Julia. If someone felt strongly about enabling this, there’s a few potentials ways forward: submit the code as a PR to Julia ( Pull requests · JuliaLang/julia · GitHub ), write up your own package that includes this implementation and share it to the General registry ( How to develop a Julia package (julialang.org) ), or if you only care to have them defined for your own non-shared code just keep a file of such convenience functions handy and import them as needed.

6 Likes

Looks like the second option I referenced, writing your own Matlab-style package, has already been attempted at least once: GitHub - juliamatlab/MatLang: Matlab’s language functions written in Julia. The repo shows no commits in the past 4 years, but the Project.toml shows compatibility with at least Julia v1.0, and it seems to add just fine for me in a fresh Pluto environment.

It has a sortM function defined such that

using MatLang

v = randn(5)
# v = [-0.14698, 0.279868, -0.216259, -0.699488, 0.933226]

tbl, ind = sortM(v, I=true)
# tbl = [-0.699488, -0.216259, -0.14698, 0.279868, 0.933226]
# ind = [4, 3, 1, 2, 5]
2 Likes