Issues with populating a matrix using for loop and if conditional statements

N= 200;
l_length = 1600;
fileToRead1='Length.xlsx';
sheetName='Sheet1';
[numbers, strings, raw] = xlsread(fileToRead1, sheetName);
if ~isempty(numbers)
newData1.vert_curves = numbers;
end
if ~isempty(strings)
newData1.textdata = strings;
end
if ~isempty(strings) && ~isempty(numbers)
[strRows, strCols] = size(strings);
[numRows, numCols] = size(numbers);
likelyRow = size(raw,1) - numRows;
% Break the data up into a new structure with one field per column.
if strCols == numCols && likelyRow > 0 && strRows >= likelyRow
newData1.colheaders = strings(likelyRow, :);
end
end
% Create new variables in the base workspace from those fields.
vars = fieldnames(newData1);
for i = 1:length(vars)
assignin('base', vars{i}, newData1.(vars{i}));
end
profile=numbers;
M1_return= 10;
M2_return= 20;
M3_return= 30;
for i= 2:N/2
for j=2:size(profile)
if profile(j,1)<round(0.25*l_length/2)
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
elseif profile(j,1)<round(0.75*l_length/2)
M3_carry_empty(i)=M3_return;
elseif profile(j,1)<round(0.9*l_length/2)
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
else
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
end
end
end
When i run the code, i expect that for M1_carry_empty will get populated with 10 from 2:24 & 91:100 . While M3_carry_empty would be populated with 20 from 25:75 and M3_carry_empty would be populated with 30 from 76:90. However, it doesn't do that and it only fills up at 2. I believe the problem might lie in this line.
for j=2:size(profile)
As the size of my profile is 161x5. The file length.xlsx is just a series of numbers from 0-1600 in increments of 10 and theyre all in the first column of the excel file.
The aim was,
for 200m<lengths>600m it would be populated with the M1_Carry_empty & M2_carry_empty.
for 200m>lengths<600m would be populated with M3_carry empty.
I have attached the excel file for reference. Please advise.

1 件のコメント

Bob Thompson
Bob Thompson 2019 年 1 月 9 日
The first thing you should do is specify a direction for size(). I assume you want to loop through all rows of 'profile' so the proper calling should be:
for j = 2:size(profile,1)
Unfortunately, I do not have the ability to view your excel file, so I can't test things directly, but if M1, M2, and M3 are only populationg cell 2 then you might need to look at your loop for 'i' rather than 'j'.

サインインしてコメントする。

回答 (1 件)

Guillaume
Guillaume 2019 年 1 月 9 日
There are many issues with your code, the usage of the horror that is assignin, probably the biggest one. Nowadays, I would also recommend using readtable over xlsread.
" I believe the problem might lie in this line."
for j=2:size(profile)
It is certainly a poorly written line, but it actually shouldn't be a problem in your case. You should never pass an array to the right side of the colon (:) operator as I'm fairly certain that you don't know how colon deals with arrays. As Bob said, you should always specify the size dimension explictly, so:
for j = 2:size(profile, 1) %iterate over the rows
However, since colon uses the first element of the array, the two lines are equivalent.
There is certainly a problem with your i loop however. Other than the destination index, nothing inside the loop depends on i, so all elements of M1_carry_empty will have the same values, all elements of M2_carry_empty will have the same values, etc.
I suspect your j loop is also wrong. We have three possible destinations (M1_carry_empty(i), M2_carry_empty(i), and M3_carry_empty(i)) for however many elements there are in column 1 of profile, so the j loop is going to be overwriting these destinations a lot.
I'm actually not sure what it is you're trying to do. It's not clear what the it is in "it would be populated with ...", nor how the it can be populated by two values simultaneously ("it would be populated with the M1_Carry_empty & M2_carry_empty"). Most likely what you want to do involves a call to discretize and no loop at all.

6 件のコメント

Aleef Rahman
Aleef Rahman 2019 年 1 月 10 日
編集済み: Aleef Rahman 2019 年 1 月 10 日
Thank you for the response and i will like to rephrase the problem. So for the code, yes all elements of M1_carry_empty will have the same values however they would only populate from 2:24 and 76:100. I also forget to include that i have created zeros for the variables M1_carry_empty, M2_carry_empty and M3_carry_empty.
M1_carry_empty=zeros(N,1);
M2_carry_empty=zeros(N,1);
M3_carry_empty=zeros(N,1);
So the next step of the code that im trying to acheive is to start populating this variables. This is where the loops come into play.
N=200;
l_length=1600;
M1_return= 10;
M2_return= 20;
M3_return= 30;
for i= 2:N/2 % Say i= 2:100,
for j=1:size(profile,1) % j = 1:161,
if profile(j,1)<round(0.25*l_length/2) % at profile(1,1) = 0, at profile(21,1) = 200
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
elseif profile(j,1)<round(0.75*l_length/2) %profile(61,1)= 600
M3_carry_empty(i)=M3_return;
elseif profile(j,1)<round(0.9*l_length/2) %profile(91,1)= 720
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
else
M1_carry_empty(i)=M1_return;
M2_carry_empty(i)= M2_return;
end
end
end
What im trying to achieve here is to populate M1_carry_empty(2) to M1_carry_empty(24) & M1_carry_empty(76) to M1_carry_empty(100) with the value of M1_return which is 10.
M2_carry_empty would be populated similarly to M1_carry_empty but with the value of M2_return of 20.
M3_carry_empty(25) to M3_carry(75) would be populated with the values of M3_return which is 30.
Lets say the for the first iteration meaning i =2 and j=1, profile(1,1)=0 which is less than round(0.25*l_length/2) =200 so M1_carry_empty(2) and M2_carry_empty(2) would be populated with the M1_return and M2_return values respectively. After which it runs for i=3 and j=2 and so on. Once profile(j,1) = 200, it will then move to the next statement and start populating M3_carry_empty. I realized that this wouldn't work as the loop for my j is bigger than the i loop meaning as i loop reaches the 100th iteration, the value of j would only be until profile(100,1) which is 990. My idea is to rework the profile variable and make it to the same size (N/2). Am i approaching this the wrong way? Please advise.
Guillaume
Guillaume 2019 年 1 月 10 日
It looks to me that you don't understand loops. The i and j loop are not synchronised. The first iteration is indeed i=2 and j=1, however after that, you're still iterating inside the j loop, so i is still 2 and j is now 2. Since i is still 2, you're still filling the same element of Mx_xxx. Carry on until j = 161, then finally, you're moving to i=3 and j starts back at 1.
What you're trying to do is probably very simple but I still don't understand it. Why is it elements 2 to 25 and 76 to 100 that are populated? Where do the 2, 25, 76, and 100 come from?
Rather than giving us code that doesn't work, give us an example of input and the corresponding desired output.
I see, so my concept for the loops requires more understanding. I will practice some loop scenarios especially ones that uses an excel file before proceeding any further with my codes. Thank you so much Mr Guillaume for your advise and guidance. As per request, here is the full working code.
global N l_length M1_carry_empty M2_carry_empty M3_carry_empty profile
N=200;
l_length=1600;
fileToRead1='Lengths.xlsx';
sheetName='Sheet1';
[numbers, strings, raw] = xlsread(fileToRead1, sheetName);
if ~isempty(numbers)
newData1.vert_curves = numbers;
end
if ~isempty(strings)
newData1.textdata = strings;
end
if ~isempty(strings) && ~isempty(numbers)
[strRows, strCols] = size(strings);
[numRows, numCols] = size(numbers);
likelyRow = size(raw,1) - numRows;
% Break the data up into a new structure with one field per column.
if strCols == numCols && likelyRow > 0 && strRows >= likelyRow
newData1.colheaders = strings(likelyRow, :);
end
end
% Create new variables in the base workspace from those fields.
vars = fieldnames(newData1);
for i = 1:length(vars)
assignin('base', vars{i}, newData1.(vars{i}));
end
profile=numbers;
M1_carry_empty=zeros(N,1);
M2_carry_empty=zeros(N,1);
M3_carry_empty=zeros(N,1);
M1_return= 10;
M2_return= 20;
M3_return= 30;
for i=2:N/2
for j=1:size(profile,1)
if profile(j,1)<=round(0.25*l_length/2) %Belt and Cart Seperated (25%)
M1_carry_empty(i)=M1_return; %Empty belt
M2_carry_empty(i)= M2_return; %Empty cart
end
if profile(j,1)<round(0.75*l_length/2) %Belt and Cart Joined (50%)
M3_carry_empty(i)=M3_return;
end
if profile(j,1)<round(0.9*l_length/2) %Belt and Cart Seperated approaching turnaround
M1_carry_empty(i)=M1_return; %Empty belt
M2_carry_empty(i)= M2_return; %Empty cart
else %turnaround
M1_carry_empty(i)=M1_return; %Empty belt
M2_carry_empty(i)= M2_return; %Empty cart
end
end
end
The 2, 25, 76 and 100 comes from the matrix rows of Mx_xxx (example, M1_carry_empty(2,1) to M1_carry(25,1)). Theyre associated with the rows of the particular variable. This was what i would want to expect from running this code (see attachment).
Guillaume
Guillaume 2019 年 1 月 10 日
Screenshots are useless, it's not something we can manipulate in matlab and experiment with. Use mat files instead.
My question about 2, 25, 76 and 100 was why these values? I understand that they're the rows of Mx_xxx that you want filled, but why is it row 2 to 25 and not row 3 to 24 or any other value. Where do these numbers come from.
Aleef Rahman
Aleef Rahman 2019 年 1 月 15 日
Apologies for the late reply. Those numbers come from the conditions that im trying to achieve. So, for the first condition which was 2 to 25, out of the 100 elements (N/2) i wanted 25% to be filled with M1_carry_empty. This was because im trying to breakdown the 100 elements into 25% (filled by M1_carry_empty & M2_carry_empty), 50%(M3_carry_empty), 75% to 100 %(filled by M1_carry_empty & M2_carry_empty). Im not too sure as to how to explain this but heres what im trying to achieve. So the lengths.xls will run from 10 to 1600. N= number of elements for each variable of Mx_xxx. Im trying to write a condition for i=2:N/2, that if the length reaches 200m, i want M1_carry_empty(2:25) & M2_carry_empty(2:25) to be populated. Subsequently, when length reaches 600m, M3_carry_empty(26:75) to be populated. Lastly, for the remaining 200m, i want M1_carry_empty(76:100) & M2_carry_empty(76:100). The problem was as mentioned, the sizes for the loops were not equal lengths.
I have attached the mat file.
Guillaume
Guillaume 2019 年 1 月 15 日
編集済み: Guillaume 2019 年 1 月 15 日
I'm sorry to say but you're really not clear. I'm actually not sure that it's even clear for you what it is you want to achieve.
So, for the first condition which was 2 to 25 What does a condition is 2 to 25 mean?, out of the 100 elements (N/2) 100 elements of what? i wanted 25% of what? to be filled with M1_carry_empty I was under the impression that M1_carry_empty was an array. Which elements of that array are used to fill the 25% of something?
So far, all I've understood is that we have an array
lengths = 10:10:1600;
and 3 arrays (Mxx_carry_empty) to fill with some values (where do the fill values come from) under some conditions. Perhaps if you wrote these conditions mathematically, it would be clearer. Please don't use matlab code since your code is obviously wrong.
"I have attached the mat file."
No, you've attached a m file of your code, which we already know doesn't work. I wanted a mat file of the expected result (the 3 Mxxx_carry_empty). Every time you mention the indices of these matrices you start at 2 (eg. 2:25). Why is 1 being ignored?
Perhaps, if you explained what all of this is going to be used for it would also be clearer.

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeLoops and Conditional Statements についてさらに検索

質問済み:

2019 年 1 月 9 日

編集済み:

2019 年 1 月 15 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by