Matlab中多投影的快速算法

时间:2015-07-22 16:36:06

标签: algorithm matlab time-complexity projection

我的问题是在Matlab中快速执行许多低维投影 。我有一个数组z,其维度为(n,L,d);这些参数如下获得。我接受一个大小为N的输入数组,比如说N = [200, 200]n = prod(N) = 200*200 = 40,000d = numel(N) = 2;也就是说,n是我的离散网格中的点数,d是输入数组的维数(例如图像,或来自高度图的平面)。然后,我将可能的高度(我的程序将输出 - 注意上面的高度图)与L点分开,比如说L = 32

对于每个i = 1:nj = 1:L,我想将向量z(i,j,:)投影到单位球上。*目前,我有以下天真的代码:

z = reshape(z,[n,L,d]); z_norms = norms(z,2,3);
for i = 1:n
for j = 1:L
    z(i,j,:) = z(i,j,:)/max(1,z_norms(i,j));
end
end

函数norms(v,p,dim)沿着维度dim取得矩阵v的p范数(在这种情况下输出(n,L)矩阵)。

我对如何改进这一点有各种各样的想法。一个想法如下:

for i = 1:n
for j = 1:L
normsquared = sum(z(i,j,:).^2)
if normsquared > 1
    z(i,j,:) = z(i,j,:)/sqrt(normsquared)
end
end
end

请注意,每次都会覆盖normsquared,因此它不会占用我的空间。当我在另一个问题上使用它时,它加快了这个过程;但是,我刚刚对这个问题进行了测试,实际情况要差得多 - 大约慢三倍;事实上,计算normsquared需要大约2.5倍的时间,就像在第一种情况下做预测一样!

奇怪的是,如果我将sum(z(i,j,:).^2)更改为z(i,j,1)^2 + z(i,j,2)^2(在使用d = 2的情况下),那么它实际上比第一种(天真)方法稍快一些......如果有人也可以向我解释这一点,那就太棒了!

如果有人对如何提高速度有任何建议,那么我会非常感激!目前大约90%的程序运行时间用于此!

*实际上,我想把它投射到lambda乘以lambda是另一个参数的单位球,但这不太可能在算法上产生差异 - 只需将z除以lambda,做投影然后乘以lambda, 例如

2 个答案:

答案 0 :(得分:2)

当您可以使用bsxfun重写双parfor循环来“向量化”操作时,无需使用for

z = bsxfun(@rdivide,z,max(1,z_norms))

max函数对n-by-L z_norms矩阵的阈值进行矢量化,使得所有值都小于或等于1。 z是一个3维n-by-L-by-d数组。 bsxfunz_norms的第三个维度上d实际上复制了较低维z矩阵NoClassDefFoundError次,这样两者的元素划分(rdivide)就可以了执行。结果是n-by-L-by-d数组。

在您的代码profiling之后,重写循环以利用Matlab的vectorization功能应该是您尝试improve performance的第一件事。

答案 1 :(得分:1)

您可以尝试使用for循环替换内部parfor循环。 parfor允许您在多核处理器上同时运行多次迭代。

http://nl.mathworks.com/help/distcomp/parfor.html