我有一个用Julia写的非常简单的函数,需要运行数百万次。
码:
function randfunc()
#rands could be a global variable if desired
rands = rand(200,100000)
for i=1:100000
#the alphabet can continue (and in Q1 as well)
# rand(1:100000) generates a random number within the number of columns in rands
a = rand(1:100000)
b = rand(1:100000)
c = rand(1:100000)
d = rand(1:100000)
e = rand(1:100000)
Q1 = hcat(rands[:,a],rands[:,b],rands[:,c],rands[:,d],rands[:,e])
Q2 = *(Q1.',Q1)
end
end
有什么方法可以加快hcat功能或将其替换为更高效的功能?
加快此功能的另一种方法是在不构造Q1矩阵的情况下手动进行矩阵乘法,但是内置的
*(,)
运算符的运行速度比使用+
和*
的运行速度快,至少在我看来尝试,并且这样做似乎比简单地构造Q1有更多的开销。使用
rands = convert(Array{Float32}, rands)
会有所帮助,但是Float16
实际上更糟(尤其是对于矩阵乘法)。 rands
中的元素不能严格是整数,并且在Q1中列向量的数量是任意的。编辑:这个问题的最初概念是试图获得一种从数据中调用矩阵的快速方法,该数据以后将成为其转置矩阵乘法的一部分。我已编辑代码以尝试解决任何歧义。
旧代码:
function randfunc()
#rands could be a global variable if desired
rands = rand(200,100000)
for i=1:100000-1
Q1 = hcat(rands[:,[i]],rands[:,[i]].*rands[:,[i+1]])
Q2 = *(Q1.',Q1)
end
end
最佳答案
该代码尝试通过将计算简化为两个嵌套的for
循环来优化功能。基本上,这通过根据输入的rands
矩阵元素扩展表达式来计算与原始矩阵形式相同的表达式。返回值是Q2
矩阵的行列式的向量。
function randfunc2(rands)
a,b,c = 0.0,0.0,0.0
detvec = Vector{Float64}(size(rands,2)-1)
@inbounds for i=1:(size(rands,2)-1)
a,b,c = 0.0,0.0,0.0
@inbounds for j=1:size(rands,1)
s = rands[j,i]
t = s*s
u = s*rands[j,i+1]
a += t
b += s*u
c += u*u
end
detvec[i] = a*c-b*b # calc determinant using 2x2 det formula
# Q2 = [a b; b c]
end
return detvec
end
要使用此功能,如问题示例中所示:
rands = rand(200,100000)
randfunc2(rands) # this returns the determinant vectors.
分配非常少,每个矩阵元素都被访问了两次,但以列顺序(即快速顺序)进行了访问。