Сортировка собственных значений / собственных векторов в Julia 1.0 - PullRequest
0 голосов
/ 02 марта 2019

Этот вопрос не столько потребность в решении, сколько вопрос о том, является ли мой подход естественным для языка Julia (юлианский?), Если нет, то что было бы более естественной реализацией:

@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 голосов
/ 03 марта 2019

Я бы сделал немутирующую функцию в этом случае:

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 необязательно определять порядок (в частности, комплексные числа).

...