关于迭代过程的Matlab中的循环结构

时间:2015-05-15 02:29:42

标签: matlab for-loop iteration

我试图在Matlab中编写循环,迭代地求解零和1的最佳向量。这是我的代码

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来查找比率并排除具有最低比率的s中的元素。我需要一遍又一遍,直到没有比率为负 我需要另一个循环,还是我想念一些东西?

我希望我的问题很清楚,只要告诉我你是否需要我解释一下。

提前感谢您帮助新手程序员。

修改

我认为我还需要添加某种形式的while循环。但我无法看到如何构建这个。这是我想要的流程

包含所有项目(s(i) = 1用于所有i),计算HI,CI和标准误差并列出比率,排除对应于最低负比率的项目i(s(I) = 0)。登记/> 使用新s,包括除零之外的所有1,计算HI,CI和标准误差并列出比率,排除项目i,其对应于最低负比率。
使用新的s,现在包括除了两个零之外的所有s,重复该过程 这样做直到要排除的比率没有负面因素。

希望现在变得更加清晰。

1 个答案:

答案 0 :(得分:0)

确定。在列出我的代码之前,我想要做一些事情。这些只是 I 尝试这样做的方式。不一定是最好的方式,或者最快的方式(尽管我认为它很快)。我试着保持你的代码中的结构,所以你可以很好地遵循它(即使我可能将所有的计算结合到一个函数或行中)。

我在代码中使用的一些功能:

  1. 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的每列相乘。 WW_都是与A大小相同的矩阵,但第一个矩阵会更快(通常)。

  2. 预先计算丢失:我将select作为一个矩阵,在它之前是一个向量。这允许我使用逻辑结构形成变量included~(eye(N))生成一个单位矩阵并对其进行否定。通过逻辑"和"用select,然后$ i $ th列现在被选中,$ i $ th元素被删除。

  3. 您明确地将weights'*s计算为每个for循环中的分母。通过使用上述矩阵进行计算,我们现在可以执行sum(W),其中W在每列中基本上为weights.*s

  4. 利用逐列操作:var()sqrt()函数都被编码为沿着矩阵的列工作,以矩阵的形式输出矩阵的动作行向量。

  5. 确定。完整的事情。有任何问题让我知道:

    % 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);
    

    如果由于某种原因它无法正常工作,请告诉我。