我正在尝试向量化以下代码。我的程序花了很长时间才能执行结果。因此,我想对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
您要做的实际上是2D矩阵的卷积。您只需要指定所需的输入过滤器即可。对于您的情况,您希望找到基本基本方向的加权总和:北,东,南,西,给定矩阵中的特定位置作为输出。这样,创建一个包含这些方向的3 x 3滤镜,然后使用imfilter
或conv2
创建输出矩阵。就像您要如何创建一个在结果周围有1个元素边框的图像一样,我们应该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
上面的代码所做的基本上就是您使用doublefor
循环所做的事情。除了现在,我们正在使用conv2
。第一行Mat_new
计算矩阵中每个位置的四个基本方向的总和,而不考虑for
循环中显示的边界。完成此操作后,我们将矩阵中每个条目的绝对值abs
加到每个条目的2,然后除以4。然后,使用填充所有零的输出矩阵的边界padarray
。顺便说一下,我已经对您的error
语句进行了重组,以使其不使用对的嵌套调用max
。我从不喜欢那种样子。
不幸的是,while
循环(我不认为...)可以向量化。您正在每次迭代中计算一个新的输出,并且想要计算先前迭代和当前迭代之间的误差。在这种情况下,无法通过强大的递归关系对这样的向量进行矢量化..因此,您现在还停留在while
循环中。但是,您绝对可以向量化双for
循环,这就是我们刚刚完成的。
这有望实现您想要的!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句