Matlab For循环内部while循环

Matlab For循环内部while循环,matlab,for-loop,while-loop,Matlab,For Loop,While Loop,让我描述一个任务:我有3个矩阵M1,M2,M3,它们每个都有lenghtMi行和2列。给出了一个函数gx,s,其中s是一个二维参数,x和eta是给定的。我想检查第一个矩阵M1,如果存在一个s,比如gx,M1i,:>eta,我想结束alghoritm并设置s_new=M1i,:。如果M1中不存在这样的s,我想去矩阵M2,在它里面搜索。接下来是矩阵M3。如果在所有矩阵中都不存在这样的s_new,我想打破它。 我的第一次尝试: function[s_new]= checking(M1,M2,M3,x)

让我描述一个任务:我有3个矩阵M1,M2,M3,它们每个都有lenghtMi行和2列。给出了一个函数gx,s,其中s是一个二维参数,x和eta是给定的。我想检查第一个矩阵M1,如果存在一个s,比如gx,M1i,:>eta,我想结束alghoritm并设置s_new=M1i,:。如果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
我的第二次尝试涉及一些中断选项,但也不起作用。问题是:当alghoritm在M1中找到s时,它不会停止,比如我们的条件保持不变,它会转到M2,如果它找到这样的s,它会将s_更改为新的。此外,为了节省一些时间,我不希望alghoritm通过矩阵M2,如果M1中存在这样的情况

示例:它工作不好的原因:

M1=[0,-1;0,-1], M2=[0,-2;0,-2], M3=[0,0;0,0], x=0 
它应该返回向量[0,-1],而不是返回[0,-2]。谢谢你的帮助。
编辑:for循环中的bool1=1用红色下划线,表示bool1可能未使用,好像它在开始时没有从条件中识别它,而bool1=0

我想我发现了问题

您打算在bool1=1的情况下中断while循环

您可以添加if bool1,break;每节结束后:

%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)
没有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)

再加上@Rotem的解决方案,您可以完全摆脱for循环来解决您的问题。您可以使用find函数及其报告满足条件的第一个索引的能力,而不是遍历所有索引。此外,还可以完全避免变量bool1。我建议订立以下守则:

%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