向量化 For-If-Elseif 循环
Vectorize For-If-Elseif Loop
我正在努力对这个 parfor 循环进行矢量化。我想从代码中完全删除 parfor 循环,因为当 n 很大时执行它需要很长时间。请参阅下面粘贴的代码。我将不胜感激 tips/advice/help 这个论坛中的任何人都可以给我这方面的信息。非常感谢。
% Initialization and precomputations
% w is an n x 1 vector
% beta: any number larger than 0. Usually set to 1.
f = zeros(n,1);
x = w;
y = w;
rho = 1;
v = f – (rho*y);
rhow = rho*w;
n = length(w);
parfor i = 1 : n
if w(i) >= 0
if v(i) < -rhow(i) – beta – 1
x(i) = (-beta -1 -v(i))/rho;
elseif (-rhow(i) – beta – 1 <= v(i)) && (v(i) <= -rhow(i) + beta – 1)
x(i) = w(i);
elseif (-rhow(i) + beta – 1 < v(i)) && (v(i) < beta – 1)
x(i) = (beta – 1 -v(i))/rho;
elseif (beta – 1 <= v(i)) && (v(i) <= beta + 1)
x(i) = 0;
else
x(i) = (beta + 1 – v(i))/rho;
end
else
if v(i) < -beta -1
x(i) = (-beta -1 – v(i))/rho;
elseif (-beta – 1 <= v(i) )&& (v(i) <= -beta + 1)
x(i) = 0;
elseif (-beta + 1 < v(i)) && (v(i) < -rhow(i) – beta + 1)
x(i) = (-beta + 1 – v(i))/rho;
elseif (-rhow(i) – beta + 1 <= v(i)) && (v(i) <= -rhow(i) + beta + 1)
x(i) = w(i);
else
x(i) = (beta + 1 – v(i))/rho;
end
end
end
更新:非常感谢Hbderts 的回答,它对我帮助很大。这是我最终想到的。我仍然遇到问题,因为当我插入变量的值时,我没有像使用 parfor 循环那样得到期望的结果。你能帮我看看,让我知道我哪里错了吗?非常感谢。
cond1 = (w >= 0);
cond2 = (w >= 0) & (v < -rhow-beta-1);
x(cond2) = (-beta-1-v(cond2))/rho;
cond3 = (w>=0)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1);
x(cond3) = w(cond3);
cond4 = (w>=0) & (-rhow +beta - 1 < v) & (v < beta - 1);
x(cond4) = (beta - 1 - v(cond4))/rho;
cond5 = (w>=0) & (beta - 1 <= v) & (v <= beta + 1);
x(cond5) = 0;
cond6 = (~cond2);
x(cond6) = (beta + 1 - v(cond6))/rho;
cond7 = ((~cond1) & v < -beta -1);
x(cond7) = (-beta -1 - v(cond7))/rho;
cond8 = ((~cond1) & (-beta - 1 <= v) & (v <= -beta + 1));
x(cond8) = 0;
cond9 = ((~cond1) & (-beta + 1 < v) & (v < -rhow - beta + 1));
x(cond9) = (-beta + 1 - v(cond9))/rho;
cond10 = ((~cond1) & (-rhow - beta + 1 <= v) & (v <= -rhow + beta + 1));
x(cond10) = w(cond10);
cond11 = (~cond1);
x(cond11) = (beta + 1 - v(cond11))/rho;
您可以使用逻辑向量来索引矩阵,如 MATLAB help 页中所述。举个简单的例子:
A = [1 2 3 4];
ind = logical([0 1 0 1]);
B = A(ind)
B =
2 4
您可以使用此系统对所有不同情况进行建模并删除 for 循环。对于第一种情况,那就是
x((w>=0)&(v<-rhow-beta-1)) = (-beta-1-v((w>=0)&(v<-rhow-beta-1)))/rho;
让我们详细了解x((w>=0)&(v<-rhow-beta-1))
这个词:
w>=0
创建一个包含 1
(true) 的逻辑向量,如果 w
中的相应条目是 >=0
,否则 0
(false)。
v<-rhow-beta-1
还创建一个逻辑向量,包含 true 或 false。
- 这些项之间的
&
是逻辑与。有了这个,我们就有了一个向量,其中包含所有满足这两个条件的元素的 true,否则为 false。
- 使用
x(...)
,我们得到x
中满足上述两个条件的所有元素。
现在我们已经有了第一步要设置的所有元素。我们现在必须创建我们将设置它们的值。 (-beta-1-v(...))/rho
部分与之前相同。 v(...)
where ...
与之前的条件相同,我们取所有相关的 v
,用它们进行计算,并将它们保存在 x
的正确位置。
我们可以对您拥有的所有 if-then-else 子句重复此过程。对于第二个,这将是
x((w>=0) & (-rhow–beta–1<=v) & (v<=-rhow+beta–1)) = ...
w((w>=0) & (-rhow-beta-1<=v) & (v<=-rhow+beta-1));
等等...
我正在努力对这个 parfor 循环进行矢量化。我想从代码中完全删除 parfor 循环,因为当 n 很大时执行它需要很长时间。请参阅下面粘贴的代码。我将不胜感激 tips/advice/help 这个论坛中的任何人都可以给我这方面的信息。非常感谢。
% Initialization and precomputations
% w is an n x 1 vector
% beta: any number larger than 0. Usually set to 1.
f = zeros(n,1);
x = w;
y = w;
rho = 1;
v = f – (rho*y);
rhow = rho*w;
n = length(w);
parfor i = 1 : n
if w(i) >= 0
if v(i) < -rhow(i) – beta – 1
x(i) = (-beta -1 -v(i))/rho;
elseif (-rhow(i) – beta – 1 <= v(i)) && (v(i) <= -rhow(i) + beta – 1)
x(i) = w(i);
elseif (-rhow(i) + beta – 1 < v(i)) && (v(i) < beta – 1)
x(i) = (beta – 1 -v(i))/rho;
elseif (beta – 1 <= v(i)) && (v(i) <= beta + 1)
x(i) = 0;
else
x(i) = (beta + 1 – v(i))/rho;
end
else
if v(i) < -beta -1
x(i) = (-beta -1 – v(i))/rho;
elseif (-beta – 1 <= v(i) )&& (v(i) <= -beta + 1)
x(i) = 0;
elseif (-beta + 1 < v(i)) && (v(i) < -rhow(i) – beta + 1)
x(i) = (-beta + 1 – v(i))/rho;
elseif (-rhow(i) – beta + 1 <= v(i)) && (v(i) <= -rhow(i) + beta + 1)
x(i) = w(i);
else
x(i) = (beta + 1 – v(i))/rho;
end
end
end
更新:非常感谢Hbderts 的回答,它对我帮助很大。这是我最终想到的。我仍然遇到问题,因为当我插入变量的值时,我没有像使用 parfor 循环那样得到期望的结果。你能帮我看看,让我知道我哪里错了吗?非常感谢。
cond1 = (w >= 0);
cond2 = (w >= 0) & (v < -rhow-beta-1);
x(cond2) = (-beta-1-v(cond2))/rho;
cond3 = (w>=0)&(-rhow - beta -1 <= v) & (v <= -rhow + beta - 1);
x(cond3) = w(cond3);
cond4 = (w>=0) & (-rhow +beta - 1 < v) & (v < beta - 1);
x(cond4) = (beta - 1 - v(cond4))/rho;
cond5 = (w>=0) & (beta - 1 <= v) & (v <= beta + 1);
x(cond5) = 0;
cond6 = (~cond2);
x(cond6) = (beta + 1 - v(cond6))/rho;
cond7 = ((~cond1) & v < -beta -1);
x(cond7) = (-beta -1 - v(cond7))/rho;
cond8 = ((~cond1) & (-beta - 1 <= v) & (v <= -beta + 1));
x(cond8) = 0;
cond9 = ((~cond1) & (-beta + 1 < v) & (v < -rhow - beta + 1));
x(cond9) = (-beta + 1 - v(cond9))/rho;
cond10 = ((~cond1) & (-rhow - beta + 1 <= v) & (v <= -rhow + beta + 1));
x(cond10) = w(cond10);
cond11 = (~cond1);
x(cond11) = (beta + 1 - v(cond11))/rho;
您可以使用逻辑向量来索引矩阵,如 MATLAB help 页中所述。举个简单的例子:
A = [1 2 3 4];
ind = logical([0 1 0 1]);
B = A(ind)
B =
2 4
您可以使用此系统对所有不同情况进行建模并删除 for 循环。对于第一种情况,那就是
x((w>=0)&(v<-rhow-beta-1)) = (-beta-1-v((w>=0)&(v<-rhow-beta-1)))/rho;
让我们详细了解x((w>=0)&(v<-rhow-beta-1))
这个词:
w>=0
创建一个包含1
(true) 的逻辑向量,如果w
中的相应条目是>=0
,否则0
(false)。v<-rhow-beta-1
还创建一个逻辑向量,包含 true 或 false。- 这些项之间的
&
是逻辑与。有了这个,我们就有了一个向量,其中包含所有满足这两个条件的元素的 true,否则为 false。 - 使用
x(...)
,我们得到x
中满足上述两个条件的所有元素。
现在我们已经有了第一步要设置的所有元素。我们现在必须创建我们将设置它们的值。 (-beta-1-v(...))/rho
部分与之前相同。 v(...)
where ...
与之前的条件相同,我们取所有相关的 v
,用它们进行计算,并将它们保存在 x
的正确位置。
我们可以对您拥有的所有 if-then-else 子句重复此过程。对于第二个,这将是
x((w>=0) & (-rhow–beta–1<=v) & (v<=-rhow+beta–1)) = ...
w((w>=0) & (-rhow-beta-1<=v) & (v<=-rhow+beta-1));
等等...