Finding change point of an array values

Hi every one,
Please, i need help on specified task. I have vectors (as shown in the attached figure) and i would like to extract the points where the vector starts to decrase.
I did not found the appropriate functions to do it.
The data points is also in the attached file
Thank you in advance for your help.
Best regards

 Accepted Answer

Adam Danz
Adam Danz on 9 Nov 2019
Edited: Adam Danz on 10 Nov 2019
There are probably some smart algorithms that will be helpful (Image Analyst mentioned some hints). But here's a lower-level solution that relies on a subjetive threshold such that when the change in y-values drops below the threshold, it triggers the detection.
I only downloaded your figure and extracted the y values from each line and this works with your 3 lines. In this code, y is a vector of y-values from one of your lines.
How it works: It uses a sliding window (currently set to 5 coordinates) and compares the mean of the first 4 values and the last value. If the fraction y(5)/mean(y(1:4)) is less than 0.99, it detects the drop.
%Define window size: number of samples within window
win = 5;
% Sliding window that compares the last value in the window with the
% mean of the preceeding values in the window. If the mean/last is < .99
% it detects the change. Assumes drop is not prior to the index win-1
dropFound = false; % search flag
i = 1; %starting index
while ~dropFound
dropFound = y(i+win-1)/mean(y(i:i+win-2)) < 0.99;
i = i+1;
if i == numel(y)-win
% if you get to the end and haven't found a drop,
% quit the loop and throw a warning
warning('Drop not found')
end
end
yChangeIdx = i+win-2; % Index of coordinate that drops
xline(x(yChangeIdx)) % Draw a vertical line at the drop

6 Comments

Hi,
I would like to thank you for your reponse. Effectively this method can work only on some cases. In the attached file of his comment i put all the data and you will see that somme cases there is an unxpected decrease and then the trajectory return to the normal way.
Can you please see the data attached in this comment and help me on an other way if it is possible.
Note with your method i tried to change the threshold and use std instead of mean if it will be more accurate bu it does not work.
Thank you verry much for your assistance and you help
Best regards
Adam Danz
Adam Danz on 9 Nov 2019
Edited: Adam Danz on 9 Nov 2019
Maybe you could share a screen shot so we can easily see the example you're describing or at least provide copy-paste code that we can apply to the data in your mat file. That way we aren't spending a lot of time creating plots so we can understand your question.
This is the figure of all the data (trajectories) in matlab figure. From this figure you will see there is some decreses at the beguinin, but what interests me is the starting decresing between 100 until 150.
Is this figure screm helps you to understand my problem ?
The variable i in my code controls where the window starts. If you're interested in drops that start after x=100, have you tried setting i to something like 95 (assuming the window size is 5)?
it's works verry well. Thank you very much.
Glad it's working for you to find only relevant decreasing segments. At first you said decreasing, which means that the next point was lower than the prior point, which is solved a different way.
By the way, including screenshots means using the image icon to insert a PNG file so we can see it immediately in your post. If you attach a fig file, then there is extra work. We have to right click then save it somewhere, then we have to use MATLAB to find the file and open it - that's not as quick and easy.
fileName = 'data_threshold.mat';
s = load('data_threshold.mat')
numArrays = length(s.XTrain)
for k = 1 : numArrays
thisVector = s.XTrain{k};
plot(thisVector, '-', 'LineWidth', 2);
hold on;
end
grid on;
caption = sprintf('%d vectors in %s', numArrays, fileName);
title(caption, 'FontSize', 15, 'Interpreter', 'none');
xlabel('Index', 'FontSize', 15);
ylabel('XTrain', 'FontSize', 15);
0000 Screenshot.png

Sign in to comment.

More Answers (1)

Can you post a screenshot of your plot? In the meantime, check out findchangepts() and diff.
% Find index where vec starts to decrease
d = diff(vec);
index = find(d<0, 1, 'first') + 1;

1 Comment

Thank you for your help, but i'm sorry it does not work in this case, i tried this kind of strategy before.

Sign in to comment.

Categories

Community Treasure Hunt

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

Start Hunting!