简体   繁体   English

在while循环内进行for循环

[英]For loop inside while loop

Let me describe a task: I have 3 matrices (M1,M2,M3) , they each have lenght(Mi) rows and 2 columns. 让我描述一个任务:我有3个矩阵(M1,M2,M3) ,它们每个都有lenght(Mi)行和2列。 We are given a function g(x,s) where s is a 2 dimensional parameter and x and eta are given. 给定一个函数g(x,s) ,其中s是二维参数,并且给出xeta I want to check first matrix M1, if there exists an s such as g(x,M1(i,:)>eta I want to END the alghoritm and set s_new=M1(i,:) . If such s inside M1 does not exist I want to go to matrix M2 and search inside it. Next matrix M3. If such s_new does not exist inside all of the matrices, I want to break. My first try: 我想检查第一个矩阵M1,是否存在诸如g(x,M1(i,:)>eta我想结束算法并设置s_new=M1(i,:) 。如果M1中的此类s不存在,我想转到矩阵M2并在其中搜索。下一个矩阵M3。如果所有矩阵中都不存在s_new,我想破坏一下。

function[s_new]= checking(M1,M2,M3,x)
bool1=0;
eta = 10^-8;
g = @(x,s) x-s(1)-s(2);
while bool1==0
            for i=1:length(M1)
                if g(x,M1(i,:))>eta
                    s_new=M1(i,:);
                    bool1=1;
                end
            end
            for i=1:length(M2)
                 if g(x,M2(i,:))>eta
                    s_new=M2(i,:);
                    bool1=1;
                 end
            end
            for i=1:length(M3)
                 if g(x,M3(i,:))>eta
                    s_new=M3(i,:);
                    bool1=1;
                 end
            end
            bool1=1;
        end

My second try involved some break option but it didn't work either. 我的第二次尝试涉及一些中断选项,但是它也不起作用。 The problem is: alghoritm does not stop when it finds s in M1 such as our condition holds, it goes to M2 and if it finds there such s, it changes s_new. 问题是:当alghoritm在M1中找到s(例如我们的条件成立)时,它不会停止,它转到M2,如果找到了s,它将更改s_new。 Also in order to save some time I dont want alghoritm to go through the matrix M2 if such s exsists in M1. 另外,为了节省时间,如果M1中存在这样的算法,我不希望算法通过矩阵M2。

Example why it works badly: 为何效果不佳的示例:

M1=[0,-1;0,-1], M2=[0,-2;0,-2], M3=[0,0;0,0], x=0 

It should return vector [0,-1] and returns [0,-2] instead. 它应该返回向量[0,-1]并返回[0,-2] Any help appreciated. 任何帮助表示赞赏。 EDIT: the bool1=1 inside the for loops are underlined with red, which states bool1 might be unused as if it didnt recognise it from the condition at start while bool1=0 编辑:for循环内的bool1 = 1用红色下划线标记,表明bool1可能未使用,就好像bool1 = 0时从启动条件无法识别它一样

I think I found the problem 我想我发现了问题

You have meant to break the while loop in case bool1=1; 您打算在bool1=1;情况下打破while循环bool1=1;

You can add if bool1, break;end after each section: 您可以添加if bool1, break;end在每个部分之后if bool1, break;end

%function[s_new]= checking(M1,M2,M3,x)
M1=[0,-1;0,-1]; 
M2=[0,-2;0,-2];
M3=[0,0;0,0];
x=0;

bool1=0;
eta = 10^-8;
g = @(x,s) x-s(1)-s(2);
while bool1==0
    for i=1:length(M1)
        if g(x,M1(i,:))>eta
            s_new=M1(i,:);
            bool1=1;
        end
    end
    if bool1, break;end

    for i=1:length(M2)
         if g(x,M2(i,:))>eta
            s_new=M2(i,:);
            bool1=1;
         end
    end
    if bool1, break;end

    for i=1:length(M3)
         if g(x,M3(i,:))>eta
            s_new=M3(i,:);
            bool1=1;
         end
    end
    bool1=1;
end

display(s_new)

It is more elegant without the while loop: 没有while循环,它会更加优雅:

%function[s_new]= checking(M1,M2,M3,x)
M1=[0,-1;0,-1]; 
M2=[0,-2;0,-2];
M3=[0,0;0,0];
x=0;

bool1=0;
eta = 10^-8;
g = @(x,s) x-s(1)-s(2);

for i=1:length(M1)
    if g(x,M1(i,:))>eta
        s_new=M1(i,:);
        bool1=1;
    end
end

if ~bool1
    for i=1:length(M2)
         if g(x,M2(i,:))>eta
            s_new=M2(i,:);
            bool1=1;
         end
    end
end

if ~bool1
    for i=1:length(M3)
         if g(x,M3(i,:))>eta
            s_new=M3(i,:);
            bool1=1;
         end
    end
end

display(s_new)

Adding on to @Rotem's solution, you can get rid of the for-loops entirely for your problem. 加上@Rotem的解决方案,您可以完全解决问题的for循环。 Instead of looping over all indices, you can use the find function and its ability to report the first index which satisfies your condition. 无需遍历所有索引,您可以使用find函数及其功能来报告满足您条件的第一个索引。 Also, you can avoid the variable bool1 entirely as well. 同样,您也可以完全避免使用变量bool1 I propose the following code: 我提出以下代码:

%function [s_new]= checking(M1,M2,M3,x)
M1 = [0,-1; 0,-1]; 
M2 = [0,-2; 0,-2];
M3 = [0,0; 0,0];
x = 0;
eta = 10^-8;
% Here I have vectorized your function g so that it can work over all the rows of the s matrix. This is the step which actually removes the for-loop. sum(s, 2) always sums over the 2 columns in your matrix.
g = @(x, s) x - sum(s, 2);
% Now we assign an empty matrix to s_new. This step gets rid of the bool1 because now we can check whether s_new is still empty or not. It also returns empty matrix if no value of s_new is found in any of your matrices M1, M2 or M3
s_new = [];
% Now we find if an s_new exists in M1. We first calculate the g function over the entire M1 matrix. Then we check if your condition is satisfied. Then the find function returns the first row of M1 that satisfies your condition. If it doesnot find any row that satisifies this condition, find will return an empty matrix which we can check to assign the value to s_new
s_new_index = find(g(x, M1) > eta, 1, 'first');
if ~isempty(s_new_index) % the isempty function checks for empty matrices. ~ stands for NOT
    s_new = M1(s_new_index, :);
end
% Now we check if s_new was assigned earlier. If not then we repeat the same thing with M2 and then M3
if isempty(s_new)
    s_new_index = find(g(x, M2) > eta, 1, 'first');
    if ~isempty(s_new_index)
        s_new = M2(s_new_index, :);
    end
end
if isempty(s_new)
    s_new_index = find(g(x, M3) > eta, 1, 'first');
    if ~isempty(s_new_index)
        s_new = M3(s_new_index, :);
    end
end

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM