在Julia

时间:2017-10-25 10:44:37

标签: julia

有一种简单的方法可以在Julia中创建稀疏对称随机矩阵吗? 朱莉娅有命令

sprand(m,n,d)

"创建[稀疏] m-by-n随机矩阵(密度为d),其中iid非零元素在半开区间[0,1] [0,1]上均匀分布。 "但据我所知,这并不一定会返回对称矩阵。

我正在寻找与MATLAB相同的命令

R = sprandsym(n,density)

自动创建稀疏对称随机矩阵。如果尚未实现这样的命令,那么将sprand(m,n,d)返回的矩阵转换为对称矩阵的解决方法是什么?

谢谢!

3 个答案:

答案 0 :(得分:3)

你可以Symmetric(sprand(10,10,0.4))

答案 1 :(得分:2)

为了避免在对Michael Borregaard的回答的评论中提到额外的内存警告,以下函数采用稀疏矩阵并删除下三角部分中的条目。如果SparseMatrixCSC格式不熟悉,它也可以很好地呈现格式的操作方式:

function droplower(A::SparseMatrixCSC)
    m,n = size(A)
    rows = rowvals(A)
    vals = nonzeros(A)
    V = Vector{eltype(A)}()
    I = Vector{Int}()
    J = Vector{Int}()
    for i=1:n
        for j in nzrange(A,i)
            rows[j]>i && break
            push!(I,rows[j])
            push!(J,i)
            push!(V,vals[j])
        end
    end
    return sparse(I,J,V,m,n)
end

使用示例:

julia> a = [0.5 1.0 0.0 ; 2.0 0.0 0.0 ; 0.0 0.0 0.0]
3×3 Array{Float64,2}:
 0.5  1.0  0.0
 2.0  0.0  0.0
 0.0  0.0  0.0

julia> b = sparse(a)
3×3 SparseMatrixCSC{Float64,Int64} with 3 stored entries:
  [1, 1]  =  0.5
  [2, 1]  =  2.0
  [1, 2]  =  1.0

julia> c = droplower(b)
3×3 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [1, 1]  =  0.5
  [1, 2]  =  1.0

julia> full(Symmetric(c))    # note this is symmetric although c isn't
3×3 Array{Float64,2}:
 0.5  1.0  0.0
 1.0  0.0  0.0
 0.0  0.0  0.0

答案 2 :(得分:0)

SparseMatrixCSC上的操作通常需要进行自定义以实现最高效率。因此,要从稀疏矩阵A到具有相同上部的对称稀疏矩阵,这里是一个自定义版本(它有点神秘,但工作):

function symmetrize(A::SparseMatrixCSC)
    m,n = size(A)
    m == n || error("argument expected to be square matrix")
    rows = rowvals(A) ; vals = nonzeros(A)
    a = zeros(Int,n) ; b = zeros(Int,n) ; c = 0
    for i=1:n
        for j in nzrange(A, i)
            if rows[j]>=i
                if rows[j]==i a[i] += 1 ; c += 1 ; end
                break
            end
            a[i] += 1 ; b[rows[j]] += 1 ; c += 2
        end
    end
    c == 0 && return SparseMatrixCSC(n, n, ones(n+1), nrows, nvals)
    ncolptr = Vector{Int}(n+1)
    nrows = Vector{Int}(c) ; nvals = Vector{eltype(A)}(c)
    idx = 1
    for i=1:n
        ncolptr[i] = idx
        if a[i]==0 a[i] = idx ; idx += b[i] ; continue ; end
        for j in (0:a[i]-1)+first(nzrange(A, i))
            nvals[idx] = vals[j] ; nrows[idx] = rows[j] ; idx += 1
            rows[j] >= i && break
            nvals[a[rows[j]]] = vals[j] ; nrows[a[rows[j]]] = i
            a[rows[j]] += 1
        end
        a[i] = idx ; idx += b[i]
    end
    ncolptr[n+1] = idx
    return SparseMatrixCSC(n, n, ncolptr, nrows, nvals)
end

示例运行:

julia> f = sprand(5,5,0.2)
5×5 SparseMatrixCSC{Float64,Int64} with 5 stored entries:
  [1, 1]  =  0.981579
  [3, 1]  =  0.330961
  [5, 1]  =  0.527683
  [4, 5]  =  0.196898
  [5, 5]  =  0.579006

julia> full(f)
5×5 Array{Float64,2}:
 0.981579  0.0  0.0  0.0  0.0     
 0.0       0.0  0.0  0.0  0.0     
 0.330961  0.0  0.0  0.0  0.0     
 0.0       0.0  0.0  0.0  0.196898
 0.527683  0.0  0.0  0.0  0.579006

julia> full(symmetrize(f))
5×5 Array{Float64,2}:
 0.981579  0.0  0.0  0.0       0.0     
 0.0       0.0  0.0  0.0       0.0     
 0.0       0.0  0.0  0.0       0.0     
 0.0       0.0  0.0  0.0       0.196898
 0.0       0.0  0.0  0.196898  0.579006

此版本应该比其他版本更快,但仍需要进行基准测试(并在@inbounds循环中添加一些for