I'm trying to fit two connected lines to noisy data with a robust method, the goal is to find the interconnection (vertical dashed red line in image below).
One approach was to detect the step in derivative (diff
) but this would require filtering, estimating the threshold and could give ambiguity.
My current approach is to use fminbnd
and polyfit
but I wonder if there is a more performant or straight-forward way to do this:
% create sample data
x = linspace (0, 3);
y = 1.37 * x;
r = x > 1.7;
y(r) = y(r) + (x(r) - x(find (r, 1))) * 4;
y = y + 0.2 * randn (size (y));
% plot it
plot (x, y)
grid on
function ret = d (s, x, y)
assert (s <= 1.0 && s >= 0);
k = round (s * numel (x));
[~, s1] = polyfit (x(1:k), y(1:k), 1);
[~, s2] = polyfit (x(k+1:end), y(k+1:end), 1);
ret = s1.normr + s2.normr;
end
da = @(s) d(s,x,y);
[X, FVAL, INFO, OUT] = fminbnd (da, 0, 1)
xp = x(round (X * numel (y)))
line ([xp xp], [min(y) max(y)], 'linestyle', '--', 'color', 'red')
This code was written for GNU Octave but I tried to be MATLAB compatible. Please comment if it doesn't run on Matlab