interp1 and Index exceeds the number of array elements (0)
4 views (last 30 days)
Show older comments
Vahid Esmaeili
on 18 Jul 2020
Commented: Vahid Esmaeili
on 21 Jul 2020
Hello,
Would you please assist me with the following program
for i=1:length(T_HCRM)-2
for j=1:phaz
comX1(i,:)=interp1([1:length(comXS(T_HCRM(i):T_TORM(i)))],comXS(T_HCRM(i):T_TORM(i)),[1:(length(comXS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comXS(T_HCRM(i):T_TORM(i)))],'cubic');
end
end
I always receive this error message: Index exceeds the number of array elements (0). Error in interp1 (line 153) extrapMask = Xq < X(1) | Xq > X(end);
The mentioned lines are part of a program and has to normalize comXS which is a matrix of one column and 1911 rows to equal sections of 100 frames. Somebody else who is not available provided the program on a database for students but everybody has to change it according to his project.
As I understood from help of MATLAB, the 3 parts of the interp1 function (I mean parts separated by commas) have to have the same lengths. While the first two parts of the interp1 function (parts before the 1st ( length(comXS(T_HCRM(i):T_TORM(i))) ) and the 2nd comma (comXS(T_HCRM(i):T_TORM(i)) )) have equal length AND different part of the 3rd part have equal length, I do not understand why the total length of the 3rd part is 532! I mean length of length (comXS(T_HCRM(i):T_TORM(i))) is 537 and length of comXS(T_HCRM(i):T_TORM(i)) is 537. These parts agait are used in the 3rd part (part located between 2nd comma and 3rd comma). But surprizingly, total length of the 3rd part " length(comXS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comXS(T_HCRM(i):T_TORM(i))) ".
As you are professionals, maybe the way that I asked you my question is not the best way, but believe me, after spending several hours to find a solution, I am really confused and frustrated with this issue. I hope your knowledge and experience assist me. I am a beginner.
Thank you so much,
0 Comments
Accepted Answer
Walter Roberson
on 18 Jul 2020
Sometimes it is easier to use temporary variables to make things clearer.
for i=1:length(T_HCRM)-2
idx = T_HCRM(i):T_TORM(i);
L = length(idx);
assert(L>0, sprintf('T_TORM(%d) = %f is before T_HCRM(%d) = %f', i, T_TORM(i), i, T_HCRM(i)));
dx = (L-1)/(phaz-1);
for j = 1:phaz
comX1(i,:) = interp1(1:L, comXS(idx), 1:dx:L, 'cubic');
end
end
Now as you look at this, you should ask yourself why you are looping over j but never using j inside the loop.
You should also ask yourself whether it guaranteed that T_HCRM(i):T_TORM(i) will always be the same length -- because if it is not, then some of the rows of comX1 would want to be different lengths than others.
In order to do the assignment of multiple rows, you need to guarantee that each row will be the same length -- and if you can make that guarantee then you should move the calculation of that length outside the loop.
I would suggest that if you are trying to force there to be phaz-1 or phaz entries in length(comXS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comXS(T_HCRM(i):T_TORM(i))) that you use linspace, such as
L = length(T_HCRM(1):T_TORM(1));
assert(L>0, sprintf('T_TORM(1) = %f is before T_HCRM(1) = %f', T_TORM(1), T_HCRM(1)));
for i=1:length(T_HCRM)-2
idx = T_HCRM(i):T_TORM(i);
comX1(i,:) = interp1(comXS(idx), linspace(1, L, phaz), 'cubic');
end
4 Comments
Walter Roberson
on 19 Jul 2020
R5Min=islocalmin(R_5Met_y)& R_5Met_y<.03;% To detect when marker contacts the ground: minimum position of the marker is the time it takes off the ground
That test is not good enough for your purposes. A number of your R_5Met_y areas descend steeply, then rise very slightly, descend shallowly, then rise steeply. A local min is detected just before the very slight rise, and another just before the steep rise, leading to two local min being found in some of the dips. Meanwhile your other data does not have that property, so you end up with unsychronized peak locations.
T = readtable('MATLAB.xlsx', 'PreserveVariableNames', true);
CoM = T{:,[1 3 5]};
LatMal_R_y = T.LatMal_R_y;
R_5Met_y = T.R_5Met_y;
phaz=100;
sample=CoM;
sample(:,1)=sample(:,1)+(((sample(1,1)-sample(end,1))/(length(sample)-1))*(1:length(sample)))';
CoM=sample;
comXS=CoM(:,1);
comYS=CoM(:,2);
comZS=CoM(:,3);
LatMal_R_y=movmean(LatMal_R_y,4);
RMal_Min=islocalmin(LatMal_R_y, 'MinSeparation', 50) & LatMal_R_y<.1; % To detect when marker contacts the ground: minimum position of the marker is the time it contacts the ground
R_5Met_y=movmean(R_5Met_y,4);
R5Min=islocalmin(R_5Met_y, 'MinSeparation', 50) & R_5Met_y<.03;% To detect when marker contacts the ground: minimum position of the marker is the time it takes off the ground
T_TORM = find(R5Min(1:end-1)).'; %I do not know why you end one shorter)
T_HCRM = find(RMal_Min).';
if ( T_TORM(1) < T_HCRM(1) )
T_TORM = T_TORM(2:end);
end
if length (T_HCRM) ~= length (T_TORM) % To provide similar length for both T_HCRM and T_TORM
minLengthR = min(length(T_HCRM), length(T_TORM));
T_HCRM = T_HCRM(1:minLengthR);
T_TORM = T_TORM(1:minLengthR);
end
N = length(T_HCRM)-2; %I am not sure why you end early
comX1 = zeros(N, phaz);
comY1 = zeros(N, phaz);
comZ1 = zeros(N, phaz);
for i=1:N
idx = T_HCRM(i):T_TORM(i);
L = length(idx);
assert(L>0, sprintf('T_TORM(%d) = %g is before T_HCRM(%d) = %g', i, T_TORM(i), i, T_HCRM(i)));
comX1(i,:) = interp1(comXS(idx), linspace(1, L, phaz), 'pchip');
comY1(i,:) = interp1(comYS(idx), linspace(1, L, phaz), 'pchip');
comZ1(i,:) = interp1(comZS(idx), linspace(1, L, phaz), 'pchip');
end
% Original program
% for i=1:length(T_HCRM)-2
% for j=1:phaz
%
% comX1(i,:)=interp1([1:length(comXS(T_HCRM(i):T_TORM(i)))],comXS(T_HCRM(i):T_TORM(i)),[1:(length(comXS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comXS(T_HCRM(i):T_TORM(i)))],'cubic');
% comY1(i,:)=interp1([1:length(comYS(T_HCRM(i):T_TORM(i)))],comYS(T_HCRM(i):T_TORM(i)),[1:(length(comYS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comYS(T_HCRM(i):T_TORM(i)))],'cubic');
% comZ1(i,:)=interp1([1:length(comZS(T_HCRM(i):T_TORM(i)))],comZS(T_HCRM(i):T_TORM(i)),[1:(length(comZS(T_HCRM(i):T_TORM(i)))-1)/(phaz-1):length(comZS(T_HCRM(i):T_TORM(i)))],'cubic');
%
%
% end
% end
cycl=20; %Provides with 20 cycles (rows) with 100 columns
comX1_=comX1(1:cycl,:);
comY1_=comY1(1:cycl,:);
comZ1_=comZ1(1:cycl,:);
More Answers (1)
Vahid Esmaeili
on 20 Jul 2020
Edited: Vahid Esmaeili
on 20 Jul 2020
5 Comments
Walter Roberson
on 20 Jul 2020
This has gotten too complicated for me. I am working on a lot of different things at the same time, and it would take a lot of analysis for me to figure out what the above explanations mean in practice.
I see why fuzzy logic gait classification has been used by a number of people...
I would consider something like a Finite State Machine that instead of examining indefinitely into the future, has state about current hypotheses of what is happening, and state about predictions of where the feet will go next, and at each step receives one reading from each of the two sensors, and uses the information to change state or refine the predictions about where the feet will go next.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!