Reputation: 1459
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
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