# 'Reference to non-existent field' when using nested for loops

1 view (last 30 days)
Inti Vanmechelen on 16 Apr 2019
Commented: Inti Vanmechelen on 16 Apr 2019
Hi,
I'm trying to calculate some simpe things for data that is in structures and put it in a new 'outcome' structure which can later be exported to excel.
I have the following code:
def = {'Acc_X','Acc_Y','Acc_Z','Gyr_X','Gyr_Y','Gyr_Z'};
RMSdef = {'RMS_Acc_X','RMS_Acc_Y','RMS_Acc_Z','RMS_Gyr_X','RMS_Gyr_Y','RMS_Gyr_Z'};
for k = 1:size(sensors,2)
for j = 1: length(def)
for u = 1:nEVENTS/2
% Max values & timing of maximal values
[OUTCOME(k).event(u).(MAXdef{j}),OUTCOME(k).event(u).(idxMAXdef{j})] = max(abs(Cycle(k).event(u).(def{j})));
% RMS
OUTCOME(k).event(u).(RMSdef{j}) = rms(Cycle(k).event(u).(def{j}));
% Sample entropy
OUTCOME(k).event(u).(E{j}) = SampEn(2,0.2*std(Cycle(k).event(u).(def{j})),(Cycle(k).event(u).(def{j})));
end
end
end
This works perfectly.
Now I want to do something similar:
jerkdef = {'Jerk_X','Jerk_Y','Jerk_Z'};
accdef = {'Acc_X','Acc_Y','Acc_Z'};
for k = 1:size(sensors,2)
for q = 1: length(accdef)
for u = 1:nEVENTS/2
% Calculate jerk
JERK(k).event(u).(jerkdef{q}) = diff(Cycle(k).event(u).(accdef{q}));
% Norm of jerk
JERK(k).event(u).NormJerk = ...
sqrt(((JERK(k).event(u).Jerk_X).^2 + (JERK(k).event(u).Jerk_Y).^2 + (JERK(k).event(u).Jerk_Z).^2));
end
end
end
For some reason, matlab gives me "Reference to non-existent field 'Jerk_Y' ", but when I run this line seperately:
JERK(1).event(1).(jerkdef{2}) = diff(Cycle(1).event(1).(accdef{2}));
It does work.
I might be missing something very very very obvious but currently, I'm lost..

Geoff Hayes on 16 Apr 2019
Inti - the cell array jerkdef has the different Jerk* fields for your struct, but you only add these fields on each iteration of the second for loop
for k = 1:size(sensors,2)
for q = 1: length(accdef) % <---- SHOULD THIS BE jerkdef INSTEAD??
for u = 1:nEVENTS/2
% Calculate jerk
JERK(k).event(u).(jerkdef{q}) = diff(Cycle(k).event(u).(accdef{q}));
% Norm of jerk
JERK(k).event(u).NormJerk = ...
sqrt(((JERK(k).event(u).Jerk_X).^2 + (JERK(k).event(u).Jerk_Y).^2 + (JERK(k).event(u).Jerk_Z).^2));
end
end
end
Here is the line that adds the field
JERK(k).event(u).(jerkdef{q}) = diff(Cycle(k).event(u).(accdef{q}));
but this will just add the qth field. When q is 1, then all we have added is the Jerk_X field and so an attempt to calculate something using Jerk_Y and Jerk_Z will fail. You need to add these fields first before you try to access them.

Inti Vanmechelen on 16 Apr 2019
Hi Geoff,
Since 'jerkdef'and 'accdef' have the same length, I don't think it matters for the command
for q = 1: length(accdef)
if I use 'jerkdeg' or 'accdef'? (Correct me if I'm wrong please)
I'm aware that I'm probably doing something wrong with order of the for loops, I am just very struck that everything works in the first code I gave above (where I do the exact same thing - adding a new field in every iteration of the for-loop). I have a hard time understanding why one works and the other one does not. If you would see an explanation there, I'd be very happy to hear it :)
I'll try to add the fields first and then calculate the jerk, thank you for the suggestion.
Geoff Hayes on 16 Apr 2019
Inti - I may be mistaken but the problem isn't with the line
JERK(k).event(u).(jerkdef{q}) = diff(Cycle(k).event(u).(accdef{q}));
which is similar to your
JERK(1).event(1).(jerkdef{2}) = diff(Cycle(1).event(1).(accdef{2}));
The error is coming from the lines
% Norm of jerk
JERK(k).event(u).NormJerk = ...
sqrt(((JERK(k).event(u).Jerk_X).^2 + (JERK(k).event(u).Jerk_Y).^2 + (JERK(k).event(u).Jerk_Z).^2));
where you are trying to access Jerk_Y and Jerk_Z before you have added them as a fields/members in the struct. Or am I misunderstanding something?
Inti Vanmechelen on 16 Apr 2019
I finally see what you mean.
No, you were absolutely correct, I was just staring through it...
I've put the two command seperately in loops and now it does wrok...
Should've known that one, thank you!