实现矩阵函数的最有效方法?

香蕉

我已经尝试了一段时间,以找出处理包含变量的二维数组(即矩阵)最有效方法。我通过串联较小的数组并使用变量加权来构造一个大矩阵。作为简化示例,这是我目前正在做的。

function myMatrix(x::Float64)
    M = vcat(hcat(x*A, C), hcat(C, 2*x*B))
    return M
end

const A = ones(2,2)  
const B = ones(2,2)
const C = zeros(2,2)
y_values = collect(0:0.01:10)

for y in y_values
    eivals, eivecs = eig(myMatrix(y))
    dosomething(eivals,eivecs) 
end

问题:我有更多(和更复杂的非对角线)矩阵,最终大小很大。此时,我调用该函数几百次。是否有人建议如何使该过程在运行时方面更高效?

提前致谢

香蕉

这种使用注释中某处建议的预分配方法的解决方案并不能直接解决我的问题(由于我构造矩阵的方式),但是它对于某些阅读此书的人仍然有用。同样,我也不保证最初使用的“最有效”的陈述,因为这似乎在很大程度上取决于您的目的,矩阵的大小等。Julia的“性能提示”部分中也提到了该方法。

由于存在一些混淆,请考虑以下示例:

function myMatrix(x::Float64)
    M = vcat(hcat(x*A, C), hcat(D, 2*x*B))
    return M
end

function doSomething(A::Array{Float64,2})
    nothing
end

const ArraySize = 1000
const A = ones(ArraySize,ArraySize)  
const B = ones(ArraySize,ArraySize)
const C = rand(ArraySize,ArraySize)
const D = rand(ArraySize,ArraySize)


for i = 1:1000
    ret = myMatrix( convert(Float64,i) )
    doSomething(ret)
end

实际上,这只是根据一个参数从初始矩阵构造一个BlockMatrix(function)而已。我当时认为这种重复的构造是多余的,的确,可以通过编写以下代码为矩阵预先分配内存:

function xinc!(ret::Array{T,2}, x::T) where T
    ret[1:ArraySize, 1:ArraySize] = x*A
    ret[1:ArraySize, ArraySize+1:2*ArraySize] = C
    ret[ArraySize+1:2*ArraySize, 1:ArraySize] = D
    ret[ArraySize+1:2*ArraySize, ArraySize+1:2*ArraySize] = 2*x*B
    nothing
end

function doSomething(A::Array{Float64,2})
    nothing
end

const ArraySize = 1000
const A = ones(ArraySize,ArraySize)  
const B = ones(ArraySize,ArraySize)
const C = rand(ArraySize,ArraySize)
const D = rand(ArraySize,ArraySize)



ret = Array{Float64}(2*ArraySize, 2*ArraySize)
for i = 1:1000
    xinc!(ret, convert(Float64,i))
    doSomething(ret)
end

对我来说,第二条代码执行时间为9.866s,而第一条代码执行时间为38.076s。

编辑:回应以前的评论,如果我写

function xinc!(ret::Array{T,2}, x::T) where T
    ret = [x*A  C
            D   2*x*B]
    nothing
end

该代码需要16.173s来执行。我不知道为什么,但是这种分配矩阵的方式要慢得多。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章