Let me describe a task: I have 3 matrices (M1,M2,M3)
, they each have lenght(Mi) rows and 2 columns. We are given a function g(x,s)
where s
is a 2 dimensional parameter and x
and eta
are given. 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:
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. Also in order to save some time I dont want alghoritm to go through the matrix M2 if such s exsists in M1.
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. 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
I think I found the problem
You have meant to break the while loop in case bool1=1;
You can add if bool1, break;end
after each section:
%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:
%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. Instead of looping over all indices, you can use the find
function and its ability to report the first index which satisfies your condition. Also, you can avoid the variable bool1
entirely as well. 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
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.