Problems running a function in a for loop and dynamically assigning to a struct

Hello Community,
Could anyone help with this please. I have a function (HF) that I want to run in a for loop across various data in a struct. The function is a logical mask and works as intended - but I want to automate a bit of processing hence the loop. As this is a processing exercise, I also need to record the output to a new struct, hence the dynamic assignment to the struct which I believe is the way forward. The code is:
for i = 1:numel(plno)
x = HF(S.Plt,(i),S.HN,10);
s.pl(i) = x
end
where plno are a series of plot numbers, S.Plt and S.HN are data from an existing struct 'S'. I want the loop to run across all instances of S.Plt with the relevant number from 'i' eg S.Plt(1), S.Plt(2) etc., the function HF does its masking, then the output to be written to a new struct 's' with s.pl(1), s.pl(2) etc. as the result.
I've not got the hang of this dynamic assigning despite many attempts. I do get an output for s.pl(1) which is as expected/correct, but my loop stops and doesn't run the rest, so can anyone help please?
Thanks,
10B.

14 件のコメント

Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日
Does it give an error anywhere?
10B
10B 2016 年 11 月 17 日
編集済み: 10B 2016 年 11 月 17 日
Hello Alexandra,
The most recent error relating to the above code was:
In an assignment A(:) = B, the number of elements in A and B must be the same.
which I found somewhat confusing as the matrix sizes are the same throughout the masking procedure and the mask still works for one iteration? Perhaps this is saying that for the second run of the loop, the second output would be a different size to the first, therefore it wont run the second time?
Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日
編集済み: Alexandra Harkai 2016 年 11 月 17 日
Where exactly does the error occur (which function, which line)?
Before you run the code again, you can
dbstop if error
which will stop the code at the problem line where you can check which assignment is erroneous.
10B
10B 2016 年 11 月 17 日
編集済み: 10B 2016 年 11 月 17 日
Using the dbstop - I now get the following error:
Subscripted assignment dimension mismatch.
But it doesn't highlight a specific line? I did try this code as I thought preallocation of memory may be a problem:
for i = 1:numel(plno)
x=zeros(200,1);
x = HF(S.Plt,(i),S.HN,10);
s.pl(i) = x
end
and since the 'zeros' line was once run included and then %commented% out - I got the mismatch error.
At the moment, there are no other lines of code to speak of other than the for loop. I am testing this on variables I have in the workspace to see if I the filter will work.
10B
10B 2016 年 11 月 17 日
Incidentally, I also ran dbstop on the function HF to see if there was an error there, but it was fine. Any further thoughts?
You could skip x entirely and just write:
s.pl(i) = HF(S.Plt,(i),S.HN,10);
10B
10B 2016 年 11 月 17 日
Ah, yes of course! Thanks. Unfortunately however, the loop is still not moving past the first iteration. Now the code:
for i = 1:numel(plno)
s.pl(i) = HF(S.Plt,(i),S.HN,10);
end
Simply returns: In an assignment A(:) = B, the number of elements in A and B must be the same.
Does
dbstop if error
not point to you a particular line either?
Have you tried to put a breakpoint inside the loop and see what values does HF() return?
10B
10B 2016 年 11 月 17 日
The runs and results are as below. dbstop doesn't return anything as it appears to run:
>> dbstop if error
for i = 1:numel(plno)
s.pl(i) = HgtFilter(S.Plot,(i),S.Height_Norm,10);
end
but returns the error: In an assignment A(:) = B, the number of elements in A and B must be the same.
I tried dbstop on the function as below and it yields this:
>> dbstop if error
test = HgtFilter(S.Plot,(i),S.Height_Norm,10);
>>
So no problem there, and checking the variable 'test' - its all correct. I have just noticed something though - I think the loop changes the value of 'i' for some reason.
When i = 1:numel(plno) is run on its own, the result is 'i' is a numerical matrix 1x26 double - which is correct, but when run with the above loop, it now changes to 'i' as numerical matrix, but only with the single value of '1' - which presumably would lead to the size mismatch?
Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日
This sounds like the usual behaviour of the for loop (in the sense that it loops through the array 1:26).
However: did you check if HgtFilter returns the same size result for all of the i values?
10B
10B 2016 年 11 月 17 日
Yes, I tested, and it will potentially return different sized results for each loop eg s.pl1 = 12 data points, s.pl2 = 6 data points... etc. I see where this is going now ie this is the source of the mismatch!
Do you have an idea as to get around this mismatch problem?
Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日
編集済み: Alexandra Harkai 2016 年 11 月 17 日
Depends what you aim to do with the results. A very simple (but not necessarily beautiful) workaround is to whack them in a cell, like so:
N = numel(plno);
s.pl = cell(N, 1);
for i = 1:N
s.pl(i) = {HgtFilter(S.Plot,(i),S.Height_Norm,10)};
end
Or: you can pad them out with NaN or 0s to make them all the same size. (Note that you may not even need a struct to collect the results this way after all: if you pad them out, you can fill in the rows/columns of an array; if you put them in a cell, the result can be a cell array.)
Or: Use a non-scalar struct but let them all have a field for these results:
for i = 1:numel(plno)
s.pl(i).x = HgtFilter(S.Plot,(i),S.Height_Norm,10);
end
10B
10B 2016 年 11 月 17 日
Alexandra - you deserve a medal! Perhaps not beautiful - but it ultimately does what I couldn't acheive without your help. Perhaps one day Matlab and I will have a better relationship!
Many thanks for your help...
10B.
Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日
Happy to help. Could have suspected that earlier... :)

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

 採用された回答

Alexandra Harkai
Alexandra Harkai 2016 年 11 月 17 日

1 投票

Thought I'd add an 'Answer' to make this question 'answered' instead of the comments.
The loop fails eventually due to the HF function returning different sized arrays as output, which can't be assigned to the non-scalar struct, hence yielding an error, see details in comments.

その他の回答 (0 件)

カテゴリ

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

製品

Community Treasure Hunt

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

Start Hunting!

Translated by