Optimization 优化稀疏阵列数学

Optimization 优化稀疏阵列数学,optimization,julia,sparse-matrix,sparse-array,Optimization,Julia,Sparse Matrix,Sparse Array,我有一个稀疏数组:term\u doc 它的大小是622256x715个浮点64。它非常稀疏: 在它的444913040个细胞中,通常只有22215个是非空的 在622256行中,只有4699行被占用 虽然715列中的所有列都已被占用 我想要执行的操作符可以描述为返回该矩阵的行规范化版本和列规范化版本 我写的朴素的非解析版本是: function doUnsparseWay() gc() #Force Garbage collect before I start (and per

我有一个稀疏数组:
term\u doc

  • 它的大小是622256x715个浮点64。它非常稀疏:

    • 在它的444913040个细胞中,通常只有22215个是非空的
    • 在622256行中,只有4699行被占用
    • 虽然715列中的所有列都已被占用
我想要执行的操作符可以描述为返回该矩阵的行规范化版本和列规范化版本

我写的朴素的非解析版本是:

function doUnsparseWay()
    gc() #Force Garbage collect before I start (and periodically during). This uses alot of memory
    term_doc

    N = term_doc./sum(term_doc,1)
    println("N done")  

    gc()
    P = term_doc./sum(term_doc,2)    
    println("P done")
    gc()

    N[isnan(N)] = 0.0
    P[isnan(P)] = 0.0

    N,P,term_doc
end
运行此:

> @time N,P,term_doc= doUnsparseWay()
outputs:
N done
P done
elapsed time: 30.97332475 seconds (14466 MB allocated, 5.15% gc time in 13 pauses with 3 full sweep)
这相当简单。 它会占用内存,如果垃圾收集没有在正确的时间发生(因此我手动调用它),它将崩溃。 但速度相当快


我想让它在稀疏矩阵上工作。 为了不让我失去记忆, 因为从逻辑上讲,这是一种更快的操作——需要操作的单元更少

我听从了来自和来自政府的建议

它永远不会完成。 它可以输出“N Done”, 但从不输出“P完成”。 我让它运行了好几个小时

  • 如何优化它,以便在合理的时间内完成?
  • 或者如果不可能,请解释原因。

首先,您将
term\u doc
作为一个全局变量,这对性能是一个大问题。将其作为参数传递,
doSparseWay(term\u doc::SparseMatrixCSC)
。(函数开头的类型注释没有任何用处。)

您希望使用一种方法:


这是一种通用模式:当您想要优化稀疏矩阵时,提取
I
J
V
,并在
V

上执行所有计算,以供参考-在我看到的代码中,稀疏矩阵调用哈希函数(非内联)将虚拟坐标转换为绝对坐标。在稀疏矩阵和正规矩阵中访问元素的速度差别很大。如果您需要速度,请找出一种避免使用稀疏矩阵的方法。
function doSparseWay()
    term_doc::SparseMatrixCSC{Float64,Int64}

    N= spzeros(size(term_doc)...)
    N::SparseMatrixCSC{Float64,Int64}

    for (doc,total_terms::Float64) in enumerate(sum(term_doc,1))
        if total_terms == 0
            continue
        end
        @fastmath @inbounds N[:,doc] = term_doc[:,doc]./total_terms
    end
    println("N done")  

    P = spzeros(size(term_doc)...)'
    P::SparseMatrixCSC{Float64,Int64}

    gfs = sum(term_doc,2)[:]
    gfs::Array{Float64,1} 


    nterms = size(term_doc,1)
    nterms::Int64 
    term_doc = term_doc'

    @inbounds @simd for term in 1:nterms
        @fastmath @inbounds P[:,term] = term_doc[:,term]/gfs[term]
    end
    println("P done")
    P=P'


    N[isnan(N)] = 0.0
    P[isnan(P)] = 0.0

    N,P,term_doc
end
function doSparseWay(term_doc::SparseMatrixCSC)
    I, J, V = findnz(term_doc)
    normI = sum(term_doc, 1)
    normJ = sum(term_doc, 2)
    NV = similar(V)
    PV = similar(V)
    for idx = 1:length(V)
        NV[idx] = V[idx]/normI[J[idx]]
        PV[idx] = V[idx]/normJ[I[idx]]
    end
    m, n = size(term_doc)
    sparse(I, J, NV, m, n), sparse(I, J, PV, m, n), term_doc
end