phinz
phinz

Reputation: 1459

Julialang: In-place sort for columns of a matrix

I have a huge matrix and want to sort the columns in place for speed/memory efficency. Is it possible to use in-place sort for the columns of a matrix in Julia? As an example, take the following matrix:

julia> M=Matrix{Int}(3,3);

julia> for i = 1:size(M)[1]
           for j = 1:size(M)[2]
               M[i,j]=3*(j-1)+i
           end
       end

julia> M
3×3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9

I want to use in-place sort for the columns to obtain the matrix

3×3 Array{Int64,2}:
 3  6  9
 2  5  8
 1  4  7

This can be obtained without in-place sort as follows:

julia> M_sorted=Matrix{Int}(3,3);

julia> for j = 1:size(M)[2]
           M_sorted[:,j]=sort(M[:,j],rev=true)
       end

julia> M_sorted
3×3 Array{Int64,2}:
 3  6  9
 2  5  8
 1  4  7

But something like that fails (here only for one column):

julia> sort!(M[:,1],rev=true)
3-element Array{Int64,1}:
 3
 2
 1

julia> M
3×3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9

Is there any way to use in-place sort in this case? Note that there is no problem with the indexing since the matrix is saved column-wise in memory:

julia> M[1:end]
9-element Array{Int64,1}:
 1
 2
 3
 4
 5
 6
 7
 8
 9

So I think it should be possible.

Upvotes: 1

Views: 190

Answers (1)

Chris Rackauckas
Chris Rackauckas

Reputation: 19162

Slicing creates a copy of the column and sorts on that. If you instead want to directly sort in the memory of the existing array, use a view. Example:

M=Matrix{Int}(undef,3,3)
for i = 1:size(M)[1]
   for j = 1:size(M)[2]
       M[i,j]=3*(j-1)+i
   end
end

M

3×3 Array{Int64,2}:
 1  4  7
 2  5  8
 3  6  9

sort!(@view(M[:,1]),rev=true)

M

3×3 Array{Int64,2}:
 3  4  7
 2  5  8
 1  6  9

Upvotes: 5

Related Questions