在Julia 1.0中对特征值/特征向量进行排序

时间:2019-03-02 18:13:13

标签: arrays sorting julia

这个问题并不需要解决方案,而是要问我的方法对Julia语言(Julianic?)是否自然,如果不是这样的话,更自然的实现是什么?

@doc """
function sorteigen!(evals::Array{Number,1},evecs::Array{Number,2})

Sort the eigenvalues and vectors.
"""
function sorteigen!(evals::Array{Number,1},evecs::Array{Number,2})
n=size(evecs)[1];

#Shallow copy and force local scope
local sortedevals = copy(evals);
local sortedevecs = copy(evecs);

#Sort eigenvalue Array{Number,1}
sortedindex = sortperm(evals);
evals[:] = sortedevals[sortedindex];

#Sort eigenvectors
for i=1:n
    sortedevecs[:,i] = evecs[:,sortedindex[i]];
end

evecs[:,:] = sortedevecs[:,:]

end

1 个答案:

答案 0 :(得分:1)

在这种情况下,我会做一个非变异函数:

function sorteigen(evals::Vector{T},evecs::Matrix{T}) where {T<:Real}
    p = sortperm(evals)
    evals[p], evecs[:, p]
end

如果您确实需要节省内存,则可以执行如下操作:

function sorteigen!(evals::Vector{T},evecs::Matrix{T}) where {T<:Real}
    p = sortperm(evals)
    s = similar(evals)
    for i in axes(evecs, 1)
        for (j, pv) in enumerate(p)
            @inbounds s[pv] = evecs[i, j]
        end
        for j in eachindex(s)
            @inbounds evecs[i, j] = s[j]
        end
    end
    sort!(evals), evecs
end

这将提高内存效率,但可能会更慢,因为我们逐行操作,因此无法应用SIMD。

还要注意,我在方法的签名中使用了Real,因为一般的Number不必定义顺序(特别是复数)。