关于迭代过程中 Matlab 中的循环结构
Regarding loop structure in Matlab for an iterative procedure
我正在尝试在 Matlab 中编写一个循环,以迭代方式求解由 0 和 1 组成的最佳向量 s。这是我的代码
N = 150;
s = ones(N,1);
for i = 1:N
if s(i) == 0
i = i + 1;
else
i = i;
end
select = s;
HI = (item_c' * (weights.*s)) * (1/(weights'*s));
s(i) = 0;
CI = (item_c' * (weights.*s)) * (1/(weights'*s));
standarderror_afterex = sqrt(var(CI - CM));
standarderror_priorex = sqrt(var(HI - CM));
ratio = (standarderror_afterex - standarderror_priorex)/(abs(mean(weights.*s) - weights'*select));
ratios(i) = ratio;
s(i) = 1;
end
[M,I] = min(ratios);
s(I) = 0;
此代码将 s 中的元素设置为零,其比率最低。但是我需要这个过程重新开始,使用带有一个零的新 s 来找到比率并排除 s 中具有最低比率的元素。我一遍又一遍地需要它,直到没有比率为负数。
我需要另一个循环,还是我错过了什么?
我希望我的问题足够清楚,如果您需要我解释更多,请告诉我。
预先感谢您帮助新手程序员。
编辑
我认为我还需要添加某种形式的 while 循环。但我看不出如何构建它。这就是我想要的流程
包含所有项目(所有 i 为 s(i) = 1
),计算 HI、CI 和标准误差并列出比率,排除项目 i(s(I) = 0
)对应于负比率最低。
使用新的 s,包括除一个零之外的所有 1,计算 HI,CI 和标准误差并列出比率,排除项目 i,它对应于最低负比率。
使用新的 s,现在包括除两个零之外的所有 1,重复该过程。
这样做直到比率中没有负元素可以排除。
希望现在更清楚了。
好的。在列出我的代码之前,我想做一些事情。这些正是 I 会尝试做的。不一定是最好的方法,甚至不一定是最快的方法(尽管我认为它会很快)。我尽量保持代码中的结构,这样您就可以很好地理解它(尽管我可能会将所有计算合并到一个函数或一行中)。
我在代码中使用的一些功能:
bsxfun
:学习这个!它的工作方式令人惊奇,可以加快代码速度,并使某些事情变得更容易。
v = rand(n,1);
A = rand(n,4);
% The two lines below compute the same value:
W = bsxfun(@(x,y)x.*y,v,A);
W_= repmat(v,1,4).*A;
bsxfun
点将 v
向量与 A
的每一列相乘。
W
和 W_
都是与 A
大小相同的矩阵,但第一个会快得多(通常)。
预先计算辍学率:我制作了 select
一个矩阵,之前它是一个向量。这使我可以使用逻辑结构形成一个变量 included
。 ~(eye(N))
生成单位矩阵并将其求反。通过逻辑 "and" 与 select 相结合,第 $i$ 列现在是 select,第 $i$ 元素被删除。
您明确计算了 weights'*s
作为每个 for 循环中的分母。通过使用上面的矩阵来计算这个,我们现在可以做一个 sum(W)
,其中 W
在每一列中基本上是 weights.*s
。
利用列操作:var()
和 sqrt()
函数都被编码为沿着矩阵的列工作,输出矩阵的动作以行向量的形式。
好的。完整的东西。有任何问题请告诉我:
% Start with everything selected:
select = true(N);
stop = false; % Stopping flag:
while (~stop)
% Each column leaves a variable out...
included = ~eye(N) & select;
% This calculates the weights with leave-one-out:
W = bsxfun(@(x,y)x.*y,weights,included);
% You can comment out the line below, if you'd like...
W_= repmat(weights,1,N).*included; % This is the same as previous line.
% This calculates the weights before dropping the variables:
V = bsxfun(@(x,y)x.*y,weights,select);
% There's different syntax, depending on whether item_c is a
% vector or a matrix...
if(isvector(item_c))
HI = (item_c' * V)./(sum(V));
CI = (item_c' * W)./(sum(W));
else
% For example: item_c is a matrix...
% We have to use bsxfun() again
HI = bsxfun(@rdivide, (item_c' * V),sum(V));
CI = bsxfun(@rdivide, (item_c' * W),sum(W));
end
standarderror_afterex = sqrt(var(bsxfun(@minus,HI,CM)));
standarderror_priorex = sqrt(var(bsxfun(@minus,CI,CM)));
% or:
%
% standarderror_afterex = sqrt(var(HI - repmat(CM,1,size(HI,2))));
% standarderror_priorex = sqrt(var(CI - repmat(CM,1,size(CI,2))));
ratios = (standarderror_afterex - standarderror_priorex)./(abs(mean(W) - sum(V)));
% Identify the negative ratios:
negratios = ratios < 0;
if ~any(negratios)
% Drop out of the while-loop:
stop = true;
else
% Find the most negative ratio:
neginds = find(negratios);
[mn, mnind] = min(ratios(negratios));
% Drop out the most negative one...
select(neginds(mnind),:) = false;
end
end % end while(~stop)
% Your output:
s = select(:,1);
如果由于某种原因它不起作用,请告诉我。
我正在尝试在 Matlab 中编写一个循环,以迭代方式求解由 0 和 1 组成的最佳向量 s。这是我的代码
N = 150;
s = ones(N,1);
for i = 1:N
if s(i) == 0
i = i + 1;
else
i = i;
end
select = s;
HI = (item_c' * (weights.*s)) * (1/(weights'*s));
s(i) = 0;
CI = (item_c' * (weights.*s)) * (1/(weights'*s));
standarderror_afterex = sqrt(var(CI - CM));
standarderror_priorex = sqrt(var(HI - CM));
ratio = (standarderror_afterex - standarderror_priorex)/(abs(mean(weights.*s) - weights'*select));
ratios(i) = ratio;
s(i) = 1;
end
[M,I] = min(ratios);
s(I) = 0;
此代码将 s 中的元素设置为零,其比率最低。但是我需要这个过程重新开始,使用带有一个零的新 s 来找到比率并排除 s 中具有最低比率的元素。我一遍又一遍地需要它,直到没有比率为负数。
我需要另一个循环,还是我错过了什么?
我希望我的问题足够清楚,如果您需要我解释更多,请告诉我。
预先感谢您帮助新手程序员。
编辑
我认为我还需要添加某种形式的 while 循环。但我看不出如何构建它。这就是我想要的流程
包含所有项目(所有 i 为 s(i) = 1
),计算 HI、CI 和标准误差并列出比率,排除项目 i(s(I) = 0
)对应于负比率最低。
使用新的 s,包括除一个零之外的所有 1,计算 HI,CI 和标准误差并列出比率,排除项目 i,它对应于最低负比率。
使用新的 s,现在包括除两个零之外的所有 1,重复该过程。
这样做直到比率中没有负元素可以排除。
希望现在更清楚了。
好的。在列出我的代码之前,我想做一些事情。这些正是 I 会尝试做的。不一定是最好的方法,甚至不一定是最快的方法(尽管我认为它会很快)。我尽量保持代码中的结构,这样您就可以很好地理解它(尽管我可能会将所有计算合并到一个函数或一行中)。
我在代码中使用的一些功能:
bsxfun
:学习这个!它的工作方式令人惊奇,可以加快代码速度,并使某些事情变得更容易。v = rand(n,1); A = rand(n,4); % The two lines below compute the same value: W = bsxfun(@(x,y)x.*y,v,A); W_= repmat(v,1,4).*A;
bsxfun
点将v
向量与A
的每一列相乘。W
和W_
都是与A
大小相同的矩阵,但第一个会快得多(通常)。预先计算辍学率:我制作了
select
一个矩阵,之前它是一个向量。这使我可以使用逻辑结构形成一个变量included
。~(eye(N))
生成单位矩阵并将其求反。通过逻辑 "and" 与 select 相结合,第 $i$ 列现在是 select,第 $i$ 元素被删除。您明确计算了
weights'*s
作为每个 for 循环中的分母。通过使用上面的矩阵来计算这个,我们现在可以做一个sum(W)
,其中W
在每一列中基本上是weights.*s
。利用列操作:
var()
和sqrt()
函数都被编码为沿着矩阵的列工作,输出矩阵的动作以行向量的形式。
好的。完整的东西。有任何问题请告诉我:
% Start with everything selected:
select = true(N);
stop = false; % Stopping flag:
while (~stop)
% Each column leaves a variable out...
included = ~eye(N) & select;
% This calculates the weights with leave-one-out:
W = bsxfun(@(x,y)x.*y,weights,included);
% You can comment out the line below, if you'd like...
W_= repmat(weights,1,N).*included; % This is the same as previous line.
% This calculates the weights before dropping the variables:
V = bsxfun(@(x,y)x.*y,weights,select);
% There's different syntax, depending on whether item_c is a
% vector or a matrix...
if(isvector(item_c))
HI = (item_c' * V)./(sum(V));
CI = (item_c' * W)./(sum(W));
else
% For example: item_c is a matrix...
% We have to use bsxfun() again
HI = bsxfun(@rdivide, (item_c' * V),sum(V));
CI = bsxfun(@rdivide, (item_c' * W),sum(W));
end
standarderror_afterex = sqrt(var(bsxfun(@minus,HI,CM)));
standarderror_priorex = sqrt(var(bsxfun(@minus,CI,CM)));
% or:
%
% standarderror_afterex = sqrt(var(HI - repmat(CM,1,size(HI,2))));
% standarderror_priorex = sqrt(var(CI - repmat(CM,1,size(CI,2))));
ratios = (standarderror_afterex - standarderror_priorex)./(abs(mean(W) - sum(V)));
% Identify the negative ratios:
negratios = ratios < 0;
if ~any(negratios)
% Drop out of the while-loop:
stop = true;
else
% Find the most negative ratio:
neginds = find(negratios);
[mn, mnind] = min(ratios(negratios));
% Drop out the most negative one...
select(neginds(mnind),:) = false;
end
end % end while(~stop)
% Your output:
s = select(:,1);
如果由于某种原因它不起作用,请告诉我。