How can I perform a piecewise linear fit to data?

73 ビュー (過去 30 日間)
Ranjan Sonalkar
Ranjan Sonalkar 2015 年 5 月 19 日
コメント済み: Tong Zhao 2022 年 6 月 11 日
I have y-axis data that varies linearly in three regions over 0-1 on the x-axis. I would like to obtain a simple piecewise linear fit to get the 2-break points and the three linear fits. Is there a function that I could use? I have found nlhw that might do it, but I cannot figure out how to use it from the documentation. Would appreciate any help in using it or any other alternative.

回答 (2 件)

Greg Dionne
Greg Dionne 2016 年 7 月 8 日
If you have the R2016a Signal Processing Toolbox, you can try FINDCHANGEPTS.
  1 件のコメント
Tong Zhao
Tong Zhao 2022 年 6 月 11 日
Good idea Greg. I assume the function can also be used to reverse-find the individual clothoid segment parameters in a Frenet-fitted curve? That is, after fitting a sequence of waypoints with FrenetReferencePath(waypoints) class constructor, one has the [x,y,theta,k,dk,s] sequence of the fitted curve.If one wish to find the length and dkappa/ds of each clothoid piece component programmatically, one can plot the dk-s curve and perform a FINDCHANGEPTS on that dk-s curve to find the length of each clothoid segment, right? Or do you think there can be a more direct method of reverse-finding the parameters of each clothoid component of a multi-clothoid curve without having to use FINDCHANGEPTS?
A piece of example is the following:
waypoints = ...
[-1.20, -0.30;
-3.70, -15.90;
-2.90, -35.10;
5.90, -52.40;
24.50, -66.90;
41.80, -70;
64.30, -67.20;
78.50, -57.60;
87.30, -47.80;
93.40, -30.70;];
frenetFit = nav.algs.internal.FrenetReferencePath(waypoints);
pathPoints = frenetFit.interpolate(0:0.01:100); % first 100 meters of fitted curve
x = pathPoints(:,1);
y = pathPoints(:,2);
% plot the waypoints and fitted frenet curve
figure();plot(waypoints(:,1),waypoints(:,2),'ro');hold on; plot(x,y,'b-');
% plot the dkds-s curve
dkds = pathPoints(:,5);
s = pathPoints(:,6);
% now we use findchangepts() to find the corner points on the above figure
% by observation, there are 5 such corner points in the first 100 meters,
% so a MaxNumChanges of 5 is sufficient
ipt = findchangepts(dkds,'MaxNumChanges',5)
ipt = 5×1
1582 3514 5469 7856 9621
% then using the indices found by findchangepts, we can find the arclength
% locations where two adjacent clothoids connect
ans = 5×1
15.8100 35.1300 54.6800 78.5500 96.2000


Image Analyst
Image Analyst 2015 年 5 月 19 日
Do you have the location of the breakpoints? If so, simply use polyfit(). If not, then you should fit a line through some number of points, like 3 or 5, and scan that across your data. You can get the estimates slope at every location. Then plot the slopes and look for where it changes a lot. You can use diff() to find out where the slope changes substantially. Attach some sample data if you want people to kindly help you by writing code for you.
  3 件のコメント
Priyank Pathak
Priyank Pathak 2021 年 6 月 23 日
okay @Image Analyst ......
i will try
thank you


Community Treasure Hunt

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

Start Hunting!

Translated by