我已经尝试了一段时间来找出处理包含变量的二维数组(即矩阵)的最有效方式。 我通过连接较小的数组构造一个大矩阵,用变量加权。作为一个简化的例子,这就是我目前所做的。
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
问题:我有更多(更复杂,非对角线)的矩阵,最终的大小非常大。此时,我将该函数调用了几百次。有没有人建议如何使这个过程在运行时更有效?
提前致谢
答案 0 :(得分:1)
编辑:根据以下评论,这不回答问题。
你的意思是构建矩阵吗?做意识形态的一种方法是使用块矩阵:
M = [x*A C
C 2x*B]
不确定这在运行时是否最有效,抱歉。
答案 1 :(得分:0)
这个解决方案,使用在评论中某处提出的预分配,并没有直接解决我的问题(因为我构造矩阵的方式),但对于读这个的人来说它可能仍然有用。另外,我不保证最初使用的#34;效率最高的声明,因为这似乎在很大程度上取决于你的目的,矩阵的大小等等。 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 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.173秒才能执行。我不知道为什么,但这种分配矩阵的方式要慢得多。