我试图对以下代码进行矢量化。我的程序花了很长时间来执行结果。出于这个原因,我想对while循环进行矢量化。有可能对它进行矢量化吗或者你对我应该怎么做有不同的想法吗?
这里我取相邻像素的平均值并迭代循环,直到我得到一个近似的结果:
n = 500;
Mat_new = rand(n);
error = 1;
while error > 0.000001
Mat_Old = Mat_new;
for i = 2:n-1
for j = 2:n-1
Mat_new(i,j) =abs((2+((Mat_Old(i+1,j)+Mat_Old(i-1,j)+Mat_Old(i,j+1)+Mat_Old(i,j-1))))/(4));
end
end
error =max(max(abs(Mat_Old-Mat_new)));
end
你所做的本质上是一个二维矩阵的卷积。你只需要指定你想要的输入过滤器。在您的例子中,您希望找到基本基本方向的加权和:北、东、南、西,给定矩阵中的特定位置作为输出。因此,创建一个包含这些方向的3 × 3滤波器,然后使用imfilter
或conv2
来创建输出矩阵。看到你想要如何创建一个图像,有一个元素的边界周围的结果,我们应该使用conv2
代替。虽然你有很多括号(讨厌),但(我相信)你所做的是把所有的基本方向上的值加起来,把这个和加上2,取绝对值,然后除以4。
这样做:
n = 500;
Mat_new = rand(n);
error = 1;
h = [0 1 0; 1 0 1; 0 1 0]; % // Define filter here
while error > 0.000001
Mat_Old = Mat_new;
Mat_new = conv2(Mat_Old, h, 'valid');
Mat_new = abs(Mat_new + 2) / 4; %//Take the output, add 2, absolute then divide by 4
%// Pad border with zeroes
Mat_new = padarray(Mat_new, [1 1]);
error = max(abs(Mat_Old(:) - Mat_new(:))); %// Calculate maximum error
end
上面的代码所做的基本上就是你用双for
循环所做的。除了现在,我们正在用conv2
做这件事。Mat_new
的第一行计算矩阵中每个位置的四个基本方向的总和,忽略在for
循环中显示的边界。一旦我们这样做了,我们通过abs
对每个条目加2,然后除以4,然后取矩阵中每个条目的绝对值。之后,我们使用padarray
将输出矩阵的边界填充为全零。顺便说一句,我已经重组了您的error
语句,使其不使用对max
的嵌套调用。我从来就不喜欢它的样子。
不幸的是,while
循环(我不认为…)可以矢量化。您在每次迭代中计算一个新的输出,并希望计算前一次迭代与当前迭代之间的误差。在这种情况下,没有办法用一个强递归关系....对这样的东西进行矢量化所以你现在只能使用while
循环了。然而,你绝对可以对双for
循环进行矢量化,这就是我们刚刚完成的。
这应该有望实现你想要的!