julia - 对角化稀疏酉矩阵

标签 julia sparse-matrix eigenvalue

我必须收集稀疏酉矩阵的特征值。 基本上每个元素中只有一个不为零的元素 行和列(它是某些马尔可夫过程的传递矩阵)。

我的问题是如何继续,最好的选择是什么 在所有功能套件中。我发现 eigs 可以提供帮助, 但我也看到必须选择初始向量

最佳答案

以下代码最终定义了pdeig,它返回一个矩阵的特征值,该矩阵是一个pdmatrix,即置换矩阵和对角矩阵的乘积,或者换句话说是一个矩阵就像问题所描述的那样。快速计算特征向量也是可能的(它们有一个明确的公式):

issquare(m) = all(x->x==size(m,1),size(m))
isunique(v) = v == unique(v)
permmatrix(sigma) = 
  [i==sigma[j] ? 1.0 : 0.0 for i=1:length(sigma),j=1:length(sigma)]
mat2perm(m) = [findfirst(m[:,i]) for i=1:size(m,1)]

function ispdmatrix(m)      # used to verify input matrix form
  (r,c,v) = findnz(m)
  return issquare(m) && isunique(r) && isunique(c)
end

function pdfact(m::Matrix)  # factor into permutation/dilation
  ispdmatrix(m) || error("input matrix must be a PD matrix")
  n = size(m,1)
  p = mat2perm(m)
  d = [p[i]>0 ? m[p[i],i] : zero(eltype(m)) for i=1:n]
  return (p,d)
end

# return eigenvalues from factored pdmatrix
function pdeig(p::Vector{Int},d::Vector)
  n = length(p)
  active = trues(n)
  eigv = Vector{Complex{eltype(d)}}(0)
  for i=1:n
    if !active[i]
      continue
    end
    if p[i]>0
      j=1
      cump = d[i]
      k=p[i]
      active[i]=false
      while active[k] > 0
        j+=1
        cump *= d[k]
        active[k] = false
        k=p[k]
      end
      append!(eigv,[cump^(1.0/j)*exp(2*im*π*m/j) for m=1:j])
    else
      push!(eigv,0.0 + 0.0im)
    end
  end
  return eigv
end

pdeig(m::Matrix) = pdeig(pdfact(m)...)

n = 4   # testing vector to matrix transformation of permutations
σ=randperm(n)
@assert mat2perm(permmatrix(σ))==σ

例如以下内容:

m = [ 0.0 1.0 0.0 ; 2.0 0.0 0.0 ; 0.0 0.0 0.0 ]
pdeig(m)

输出:

    3-element Array{Complex{Float64},1}:
 -1.41421+1.73191e-16im 
  1.41421-3.46382e-16im 
              0.0+0.0im

由于这些矩阵可对角化,因此特征值应提供对角矩阵(只需对它们使用 diagm )。

这些矩阵非常结构化,适当的 Julia 处理将为这些矩阵定义一个类型,然后定义各种线性代数函数来调度该类型。

如果出现错误,只需添加评论,我会尝试修复它们(或者如果我碰巧看到一个很好的重构,那么我会进行编辑)。

顺便说一句,计算引入了小的数值误差,这些误差不应该成为问题,并且可以通过适当的舍入来消除(因此无需担心 -1.0-1.0+1.234234e -16im)

关于julia - 对角化稀疏酉矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42494201/

相关文章:

julia - 如何在 Julia 中将字符串系列转换为日期时间系列

python - Julia 中 Python 的 ast.literal_eval() 相当于什么?

Python - linalg.eigsh 如何找到*所有*特征向量?

python - SymPy 无法计算此矩阵的特征值

Python 与 Julia 自相关

Julia 1.0.0 : What does the `=>` operator do?

python - 按元素乘以稀疏向量

r - 初始稀疏矩阵不会将新的零值变成稀疏矩阵

c++ - 对于巨大的稀疏对称矩阵,哪个是 Spectra 库中最快的特征值求解器?

matlab - 在 Matlab 中估计样本协方差矩阵特征值的方差