How to detect the fluctuating point (cut-off point) of a signal?

Dear all,
I have a simple signal that I show below with blue color:
I want to find the point Xc. Any idea how find this point? Is it the same point which I will get from the first derivative of the signal?
Thank you very much.
Meshoo

 Réponse acceptée

dpb
dpb le 9 Déc 2014
The first derivative of your trace is a smooth positive curve that will have 2nd derivative that will approach zero at both ends. But the intersection point isn't at an inflection point, no...
Above shows how to fit the piecewise linear segments; you'll probably want to limit the fitting points to the end areas to get the better approximation to long-term slopes as you've drawn above; otherwise the slopes will tend to "sag" to the middle point by the OLS solution over the full data set.

6 commentaires

Thank you very much for your comment. I am still struggling with this problem...
So what are we to do w/ no sample data or further description? What, precisely, is the struggle?
Meshooo
Meshooo le 25 Déc 2014
Modifié(e) : Meshooo le 25 Déc 2014
At first, thank you very much for your kind help.
I will try to explain here the struggle point.
I have a noisy data that generates the following plot:
z = [147 148.3333333 149.6666667 150.3333333 151.3333333 152.3333333 155 155.6666667 156 157.3333333 158 160 162.3333333 163 164.6666667 165 167 167.6666667 170.3333333 171.6666667 173.6666667 174.6666667 175.6666667 177.3333333 179 180.6666667 181.6666667 182.6666667 185.6666667 186.3333333 187.3333333 189 190.6666667 191.6666667 193.3333333 195 196 197 199.6666667 200.3333333 202 203 204.3333333 206.3333333 208 209.6666667 212 213.3333333 215 216.6666667 217.6666667 219.6666667 221.6666667 223.3333333 225 226.6666667 228 230 231.3333333 232.6666667 235.3333333 235.6666667 237.6666667 238.3333333 240 241.6666667 243 243 244 245.3333333 246.6666667 248 249.3333333 251 253.6666667 254.3333333 254.6666667 254.6666667 256.3333333 258 258.3333333 258.6666667 260.6666667 260.6666667 261.6666667 262.3333333 265 265 265 266 266 266.3333333 266.6666667 266.6666667 266.6666667 266.6666667 267 267.6666667 267.6666667 267.6666667 267.6666667 267.6666667 267.6666667 267.6666667 268 268 268 268 268 268 268 268 268 268 268 268 268];
x = 1:117;
plot(x, z, 'r-', 'LineWidth', 2);
From the plot, I want to find the the point Xc in the X axis where the plot change its slop, maybe somewhere in the place circle I show below
First idea:
In the beginning I thought we can find Xc point using the first or second derivatives. But maybe this will not work because I need to smooth the data before applying the derivatives. Is that correct? if so then which smoothing technique to use?
Second idea:
To find the crossing point like the way you showed earlier using piecewise regression or polyfil as suggested by Imageanalyst.
So which way you think is good to find Xc?
Thank you very much.
Meshooo
dpb
dpb le 25 Déc 2014
Modifié(e) : dpb le 25 Déc 2014
Why don't you try it and see what you think suits your needs best? The piecewise takes only a few more line of code (presuming you've copied my referenced function piecewise that I linked to earlier)
>> m1=(z(end)-z(1))/(x(end)-x(1)); % first section slope estimate
>> m2=0; % second slope
>> b1=z(1); % first intercept estimate
>> c=0.8*x(end); % and breakpoint guess
>> coeff=nlinfit(x.',z.',@piecewise,[b1 m1 c m2])
coeff =
143.1515 1.4592 82.5534 0.1697
NB: The x,y input vectors to nlinfit functional must be column vectors, hence the ".'" transpose.
Now add the fitted curve to the existing plot--
>> zhat=piecewise(coeff,x); % the fitted curve result at the input points
>> hold on
>> plot(x,zhat,'b','linewidth',2)
Looks pretty good here. Only question is whether you want the best overall fit (in RMS terms) as this does or the line segments to more nearly match the end tangents to the curve. If the latter use the subset of the data points at the ends to fit instead of the whole thing. I've already showed that for the piecewise method following IA's example. As expected, the two provide the same answer given the same input as the piecewise regression is OLS linear regression for the two sections just finds the intersection as part of the model instead of separately.
It appears there's a little positive curvature at the leading portion of the curve from x=~[0:50] and then a small negative curvature until the breakpoint. Again, it's your choice as to what feature(s) you're most interested in; we have no way to know that.
OK, I understand your comment. Indeed thank you very much.
I have a further related question posted here, please check it when you have time..

Connectez-vous pour commenter.

Plus de réponses (2)

Try this code. It will produce the image that follows it.
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 25;
% Make up some demo equation.
x = 1 : 500;
y = sqrt(x);
% Plot it.
plot(x, y, 'b-', 'LineWidth', 2);
grid on;
title('Y = Sqrt(X)', 'FontSize', fontSize);
xlabel('X', 'FontSize', fontSize);
ylabel('Y', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'Units', 'Normalized', 'OuterPosition', [0 0 1 1]);
% Give a name to the title bar.
set(gcf, 'Name', 'Demo by ImageAnalyst', 'NumberTitle', 'Off')
% Extract left and right segments of the curve.
numPoints = 15; % Whatever.
x1 = x(1:numPoints);
y1 = y(1:numPoints);
x2 = x(end-numPoints : end);
y2 = y(end-numPoints : end);
% Draw a green line going down from there.
line([x1(end), x1(end)], [0, y1(end)], 'Color', [0, .5, 0], 'LineWidth', 2);
line([x2(1), x2(1)], [0, y2(1)], 'Color', [0, .5, 0], 'LineWidth', 2);
% Find the equations of the line for each segment.
leftCoefficients = polyfit(x1,y1,1)
rightCoefficients = polyfit(x2,y2,1)
% Plot the lines in red.
yl = ylim(); % Save original y axis range.
hold on;
yLeft = polyval(leftCoefficients, x);
plot(x, yLeft, 'r-', 'LineWidth', 2);
yRight = polyval(rightCoefficients, x);
plot(x, yRight, 'r-', 'LineWidth', 2);
ylim(yl);
% Then set the two equations to each other and solve for xc:
xc = (rightCoefficients (2) - leftCoefficients (2)) / (leftCoefficients(1) - rightCoefficients(1))
yc = leftCoefficients(1) * xc + leftCoefficients(2);
% Draw a green line going down from there.
line([xc, xc], [0, yc], 'Color', [0, .5, 0], 'LineWidth', 3);
plot(xc, yc, 'o', 'MarkerSize', 25, 'Color', [0, .5, 0], 'LineWidth', 3);
% Put up text
message = sprintf('(xc, yc) = (%.1f, %.1f)', xc, yc);
text(1.1*xc, 0.5*yc, message, 'Color', [0, .5, 0], 'FontSize', fontSize);

2 commentaires

Seems to be what I want and will test it soon. Thank you very very much..
dpb
dpb le 22 Déc 2014
Modifié(e) : dpb le 22 Déc 2014
I used the piecewise regression on your example dataset, IA, with initial guesses for the two slopes as
>> m1=Y(npts)/X(npts);
>> m2=(Y(end)-Y(end-npts+1))/(X(end)-X(end-npts+1));
>> b1=0;
>> c=X(end)/10;
>> coeff=nlinfit(X,Y,@piecewise,[b1 m1 c m2])
coeff =
1.1459 0.1940 58.0548 0.0225
The yc value is then
>> xc=coeff(3); yc=xc*coeff(2)+coeff(1)
yc =
12.4087
>>

Connectez-vous pour commenter.

Take the first and last 10% or so of the points and fit a line.
numPoints = 10; % Whatever.
x1 = x(1:numPoints);
y1 = y(1:numPoints);
x2 = x(end-numPoints : end);
y2 = y(end-numPoints : end);
leftCoefficients = polyfit(x1,y1,1);
rightCoefficients = polyfit(x2,y2,1);
Then set the two equations to each other and solve for xc:
xc = (rightCoefficients (2) - leftCoefficients (2)) / (leftCoefficients(1) - rightCoefficients(1));

3 commentaires

Thank you very much. I will test that after I came back from my business trip..
All right, I made it easy for you. See the code below in my other answer. Vote for my answer if it's useful to you.
I have a further related question posted here, please check it when you have time..

Connectez-vous pour commenter.

Community Treasure Hunt

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

Start Hunting!

Translated by