在Julia中使用多维数组广播二维数组

在Julia中使用多维数组广播二维数组,julia,Julia,我有一个二维矩阵,a,大小为mxn,其中n可能是一个非常大的数字(例如,n>10000)和一个大小为mxmn的多维矩阵。因此,对于A中的每一列i,我想计算A[:,i]'*B[:,:,i]。下面是我在Julia中使用广播功能尝试的代码。但是,我的代码的性能相当慢。我想知道我的代码的性能是否可以提高。那么,有人知道我如何改进代码吗 using LinearAlgebra; m = 500; n = 20000; # this could be a very large number. vecA =

我有一个二维矩阵,
a
,大小为mxn,其中n可能是一个非常大的数字(例如,n>10000)和一个大小为mxmn的多维矩阵。因此,对于
A
中的每一列
i
,我想计算
A[:,i]'*B[:,:,i]
。下面是我在Julia中使用广播功能尝试的代码。但是,我的代码的性能相当慢。我想知道我的代码的性能是否可以提高。那么,有人知道我如何改进代码吗

using LinearAlgebra;
m = 500;
n = 20000; # this could be a very large number.

vecA = rand(m,n);
matB = rand(m,m,n);


combinedAB = Array{Array{Float64,2},2}(undef,n,1);
for ii in eachindex(combinedAB)
  combinedAB[ii] = [vecA[:,ii] matB[:,:,ii]];
end

# this is the result.
res = broadcast(eAB -> dotProd(eAB), combinedAB);

function dotProd(matZ::Array{Float64,2})
   return sum(broadcast(dot,matZ[:,1],matZ[:,2:end]),dims=1);
end

这对你来说够快吗

res = [a'*b for (a, b) in zip(eachcol(vecA), eachslice(matB, dims=3))]
我没有足够的RAM根据您的输入值进行测试,但考虑到我对较小数据所做的测试,它应该在~3秒内运行

我还假设你真的想要一个
a
的伴随词(这是你在问题中写的;如果你在使用reals,那么使用
'
转置都不重要)


代码之间的关键区别(在我的解决方案中,它隐藏在引擎盖下,因为它更短),是我的解决方案不分配中间数组,而是使用视图。

感谢您关注我的问题。事实上,您的解决方案非常快速和简短!但我们能进一步改进它吗?我正在使用reals,我应该用
转置
来替换```````。谢谢你的解释。因为实的伴随和转置是一样的,应该没关系。只有在处理复数时,它才会有所不同(因为虚数部分的处理方式不同)。您可能获得的最快速度是三重嵌套循环,其中包含
@inbounds
@simd
,以及精心设计的遍历,以避免CPU缓存未命中。但我认为建议的解决方案要么速度相同,要么速度几乎相同(即速度的数量级相同),而且肯定要简单得多。