Research of inflexion point - Index exceeds the number of array elements.

조회 수: 2 (최근 30일)
Hélène
Hélène 2023년 6월 20일
답변: Hélène 2023년 6월 21일
Hello
As part of a data analysis project, I've written a function to calculate the inflection points of a curve using its derivatives.
The program consists of two functions and a main code. A first basic function calculates the derivatives :
function F1 = derivee(x1, x2, y1, y2)
F1 = (y2-y1)/(x2-x1);
end
A second function calculates inflection points using the signs of left, center and right derivatives:
function [outputArray] = inflexion_point(x, y)
dg = [];
dd = [];
dc = [];
n = length(x);
dd(1) = derivee(x(2), x(1), y(2), y(1));
dg(1) = derivee(x(1), x(2), y(1), y(2));
dc(1) = derivee(x(1), x(3), y(1), y(3));
for i = 2:(n-1)
dd(i) = derivee(x(i), x(i+1), y(i), y(i+1));
dg(i) = derivee(x(i-1), x(i+1), y(i-1), y(i+1));
dc(i) = derivee(x(i-1), x(i+1), y(i-1), y(i+1));
end
dg(n) = derivee(x(n-1), x(n), y(n-1), y(n));
inflex = [];
plat = [];
for i = 2:(n-1)
if dg(i) * dg(i+1) == 0 && y(i) == y(i+1)
j = i + 1;
while j < n && dg(j) == 0 && y(j) == y(j+1)
plat = [plat j];
j = j + 1;
end
elseif dg(i) * dg(i+1) < 0 || dd(i) * dd(i+1) < 0 || dc(i) * dc(i+1) < 0
inflex = [inflex i];
end
end
xinflex = x(inflex);
yinflex = y(inflex);
dg %This six lines are just to try to figure out where the problem is
dc
dd
a=length(dd)
b=length(dc)
c=length(dd)
outputArray = [xinflex', yinflex'];
end
I made a first test with a basic data set in my main file:
x=[]
y = [10,9,8,7,6,5,5,6,8,8,7,5,4,3,4,5,6,6,5,5,4,3,2,1,1,1,1,1];
for i = 1 : length(y)
x = [x i]; %ici, pour construire les x
end
[outputArray] = inflexion_point(x,y);
xinflex = outputArray(:,1);
yinflex = outputArray(:,2);
figure(1)
plot(x,y)
hold on
scatter(xinflex, yinflex)
In the real case, my data are data vectors (X,Y) of length 199, so I created a random vector to generate data for a more consistent test. And then, when I compile, I get the error
Index exceeds the number of array elements. Index must not exceed 198.
lowerBound = 0;
upperBound = 800;
y = (upperBound - lowerBound) * rand(1, 199) + lowerBound;
for i = 1 : length(y)
x = [x i]; %ici, pour construire les x
end
[outputArray] = inflexion_point(x,y);
xinflex = outputArray(:,1);
yinflex = outputArray(:,2);
figure(1)
plot(x,y)
hold on
scatter(xinflex, yinflex)
is displayed. In the inflexion_point function, I tried to modify the end indices of the for and while loops by stopping at the previous point, but this didn't change anything and the error "adapted" by becoming :
Index exceeds the number of array elements. Index must not exceed 197.
I don't understand why this code works for one lambda data set and not for another.
Is there a step I've missed or a glaring error in my code?
Thank you in advance for your help!

채택된 답변

Hélène
Hélène 2023년 6월 21일
Ok I found what the problem was, this line
dg(n) = derivee(x(n-1), x(n), y(n-1), y(n));
was adding an extra term to dg, so dc dd and dg were not the same length. Moreover, in this for loop :
for i = 2:(n-1)
if dg(i) * dg(i+1) == 0 && y(i) == y(i+1)
...
end
the loop went to index n-1, but the if condition was looking for the n-th term of dg which didn't exist. I solved the problem by modifiying the last index of the for loop :
for i = 2:(n-2)

추가 답변 (1개)

Torsten
Torsten 2023년 6월 20일
편집: Torsten 2023년 6월 20일
You forgot to initialize x as
x = []
in the second example.
  댓글 수: 1
Hélène
Hélène 2023년 6월 21일
Hello,
Thanks for your reply but no, it's initialized, I just forgot this line in the copy/paste of the code I put here.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품


릴리스

R2022a

Community Treasure Hunt

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

Start Hunting!

Translated by