interp1 and Index exceeds the number of array elements (0)

5 views (last 30 days)
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,

Accepted Answer

Walter Roberson
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
Vahid Esmaeili
Vahid Esmaeili on 18 Jul 2020
Dear Image Analyst,
Thank you so much for your comment and sorry for the inconvenience. In fact, to get the CoM, it is necessary to run several functions and needs a long process. The CoM is a matrix of 3 columns (CoM(:,1), CoM(:,2), CoM(:,3)) and 1911 rows. Honestly, it is not the original CoM file which is huge. I just selected a small piece of it that I have on my computer at home. The program reads the data on a server located in a biomechanics and human movement analysis lab to calculate and to extract variables (like CoM and LatMal_R_y). I am a student in that lab and unfortunately, I do not know a lot about MATLAB (just a beginner who has to use the help of MATLAB , internet and ask professionals). The only person that was able to help me has been diagnosed as a coronavirus patient and I have to submit my papers and project in a few months. Usually, they do not use MATLAB in that lab. I have to use MATLAB because it is faster than the traditional softwares they use there.
I included the CoM and other variables in the attached EXCEL file. Please kindly open the EXCEL file and find them. Also, I hope the following line helps to read the data from the attached EXCEL file. I used the Help Center of MathWorks to write it.
T = readtable('MATLAB.xlsx','Range','A1:H1912');
Walter Roberson
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,:);

Sign in to comment.

More Answers (1)

Vahid Esmaeili
Vahid Esmaeili on 20 Jul 2020
Edited: Vahid Esmaeili on 20 Jul 2020
Dear Walter Roberson
Thank you so much for your favour. To appreciate your kindness, I will add your name to the acknowledgment section of my thesis. Sorry for the delay in providing you with the feedback. As a beginner, I had to spend time to understand why the following issues happened.
------Different age-groups with different patterns of gait have participated in the project. I tried to test the program in different age-groups. Unfortunately, it did not work in some of them. It took me time to find out the reason by comparing the graphs of markers ((LatMal_R_y) and (R_5Met_y)) in different age-groups.
Problem was in the following lines:
RMal_Min=islocalmin(LatMal_R_y, 'MinSeparation', 50) & LatMal_R_y<.1;
R5Min=islocalmin(R_5Met_y, 'MinSeparation', 50) & R_5Met_y<.03;
In fact, the minimum of "R_5Met_y" and "LatMal_R_y" in some groups was not "<.3" and in some of them ".<1". So, I changed them as the following lines to make them appropriate for all groups:
RMal_Min=islocalmin(LatMal_R_y, 'MinSeparation', 50)& LatMal_R_y<min(LatMal_R_y)+.04;
R5Min=islocalmin(R_5Met_y, 'MinSeparation', 50)& R_5Met_y<min(R_5Met_y)+.04;
As a professional, you certainly have a better and more precise suggestion. It is appreciated if you apply your ideas to the program.
----The study also includes walking at different speeds. When I checked the program for subjects who walked at .05 m/s, I received this error message: T_TORM(8) = 736 is before T_HCRM(8) = 746. I added the data of this subject in the second sheet "Healthy_.05" of the attached EXCEL file. It seems that the front marker contacted the ground sooner than the rear marker and took off the ground before the rear marker contacted the ground. I would like to tell you that it is possible in some conditions that such a thing happens. But the condition added to the following line stops the program:
assert(L>0, sprintf('T_TORM(%d) = %g is before T_HCRM(%d) = %g', i, T_TORM(i), i, T_HCRM(i)));
What is the solution? We have to assure that the following line precisely defines the time that the rear marker contacts to the ground (red arrows in fig-1):
LMal_Min=islocalmin(LatMal_L_y, 'MinSeparation', 50)& LatMal_L_y<min(LatMal_L_y)+.04;
Also, we have to assure that the following line precisely defines the time that the front marker takes off the ground (green arrows in fig-2):
R5Min=islocalmin(R_5Met_y, 'MinSeparation', 50)& R_5Met_y<min(R_5Met_y)+.04;
L5Min1=islocalmin(diff([L_5Met_y(1); L_5Met_y]))& L_5Met_y<.03;
R5Min1=islocalmin(diff([R_5Met_y(1); R_5Met_y]))& R_5Met_y<.03;
If we define precisely the points corresponding to the blue and green arrows, the presence of T_TORM sooner than T_HCRM is accepted and even is normal. I mean the condition in this line is not necessarily always true, particularely in pathological situations like patteron of walking after amputation:
assert(L>0, sprintf('T_TORM(%d) = %g is before T_HCRM(%d) = %g', i, T_TORM(i), i, T_HCRM(i)));
It could happen in pathologic gait like the gait of stroke patients as well. That's why I think it is better to find the corresponding points of red and green arrows for both markers. As I mentioned somebody else offered a solution. I thought it is better to have your idea about the solution. Maybe you have a better idea.
Since I saw these issues, I searched a lot and I tried a lot to change the program but I am a beginner and I am not confident. On the other hand, I am not fast enough. As you are a professional, it is easy for you to find a solution.
Thank you so much for your kind attention to my situation,
  5 Comments
Walter Roberson
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.
Vahid Esmaeili
Vahid Esmaeili on 21 Jul 2020
Gait is the sate of continuous imbalance and unpredictable events, particularly pathologic gait.
Thank you for your suggestion.

Sign in to comment.

Categories

Find more on MATLAB in Help Center and File Exchange

Community Treasure Hunt

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

Start Hunting!