让我描述一个任务:我有3个矩阵(M1,M2,M3)
,它们每个都有lenght(Mi)行和2列。给我们一个函数g(x,s)
,其中s
是一个二维参数,并且给出了x
和eta
。我想检查第一个矩阵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
我的第二次尝试涉及一些break选项,但是也没有用。问题是:当alghoritm在M1中找到s(例如我们的条件成立)时,它不会停止,它转到M2,如果找到了s,它将更改s_new。另外,为了节省时间,如果M1中存在这样的算法,我不希望算法通过矩阵M2。
示例为何效果不佳:
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时从启动条件无法识别它一样
答案 0 :(得分:2)
我想我找到了问题
您打算在bool1=1;
情况下中断while循环
您可以在每个部分之后添加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)
没有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)
答案 1 :(得分:2)
添加到@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