Я пишу функцию, которая проверяет, является ли матрица X
положительной полуопределенной с заданным рангом k
.Для этого я вычисляю собственные значения X
и проверяю, что ровно k
из них положительны, а остальные равны 0. Вот что у меня есть:
using LinearAlgebra
function ispossemdef(X::AbstractMatrix, k::Int, ϵ::Real = 1e-10)
n = size(X, 1) # dim of X
!issymmetric(X) && return false # short-circuit if X is asymmetric
k > n && error("k > n") # throw error if k > n
eigs = eigvals(X) # eigenvalues of X in ascending order
z = eigs[1:(n - k)] # the values that should be zero
p = eigs[(n - k + 1):end] # the values that should be positive
n_minus_k_zero_eigenvalues = norm(z) < ϵ
k_positive_eigenvalues = all(p .> ϵ)
return n_minus_k_zero_eigenvalues & k_positive_eigenvalues
end
Есть лилучший алгоритм для этого?Лучше может означать быстрее (избегает вычисления собственных значений) или более численно устойчивым (позволяет мне избежать более строгих ошибок).
Например, функция isposdef
(это особый случай k = n
из того, что я делаю) работает, пытаясь вычислить коэффициент Холецкого X
и сообщая, может ли он.Можно ли обобщить эту процедуру для полуопределенных матриц?Если так, то это лучше, чем проверка собственных значений?