
How to divide the curve into two sections and then fit straight line for both sections separately and get intersection of the lines?
    12 views (last 30 days)
  
       Show older comments
    
The curve is a continuous data set with around 2000 or so data points in excel. I want to import it first and then divide the curve into two sections and fit the staright line for each section separately.Then get a point of intersection of two straight lines and get intersection co-ordinates.
0 Comments
Answers (4)
  Image Analyst
      
      
 on 7 Mar 2020
        Sorry for the delay.  I'm sure you definitely figured it out by now, but for what it's worth, here it is for the first data set:
% Initialization steps:
clc;    % Clear the command window.
close all;  % Close all figures (except those of imtool.)
clearvars;
workspace;  % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
markerSize = 15;
% Read in data from Excel workbook.
[numbers, strings, raw] = xlsread('combined_data.xlsx')
% Get first data set.  Eliminate nan values.
x = numbers(:, 1);
x(isnan(x)) = [];
y = numbers(:, 2);
y(isnan(y)) = [];
numPoints = length(x)
hFig = figure;
subplot(2, 2, 1);
plot(x, y, 'b-', 'LineWidth', 2);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
title('Original Data', 'FontSize', fontSize);
hFig.WindowState = 'maximized'; % Maximize window.
% Assume the crossing point will be somewhere in the middle 80% of the points.
% Fit a line through the right and left parts and get the slopes.
% Keep the point where the slope difference is greatest.
index1 = round(0.1 * numPoints); % 10% of the way through.
index2 = round(0.9 * numPoints); % 90% of the way through.
% In other words, assume that we need at least 10 percent of the points to make a good estimate of the line.
% Obviously if we took only 2 or 3 points, then the slope could vary quite dramatically,
% so let's use at least 10% of the points to make sure we don't get crazy slopes.
% Initialize structure array
for k = 1 : numPoints
	lineData(k).slopeDifferences = 0;
	lineData(k).line1 = [0,0];
	lineData(k).line2 = [0,0];
end
for k = index1 : index2
	% Get data in left side.
	x1 = x(1:k);
	y1 = y(1:k);
	% Fit a line through the left side.
	coefficients1 = polyfit(x1, y1, 1); % The slope is coefficients1(1).
	% Get data in right side.
	x2 = x(k+1:end);
	y2 = y(k+1:end);
	% Fit a line through the left side.
	coefficients2 = polyfit(x2, y2, 1); % The slope is coefficients2(1).
	% Compute difference in slopes, and store in structure array along with line equation coefficients.
	lineData(k).slopeDifferences = abs(coefficients1(1) - coefficients2(1));
	lineData(k).line1 = coefficients1;
	lineData(k).line2 = coefficients2;
end
% Find index for which slope difference is greatest.
slopeDifferences = [lineData.slopeDifferences]; % Extract from structure array into double vector of slope differences only
% slope1s = struct2table(lineData.line1); % Extract from structure array into double vector of slopes only
% slope2s = [lineData.line2(1)]; % Extract from structure array into double vector of slopes only
[maxSlopeDiff, indexOfMaxSlopeDiff] = max(slopeDifferences)
% Plot slope differences.
subplot(2, 2, 2);
plot(slopeDifferences, 'b.', 'MarkerSize', markerSize);
xlabel('Index', 'FontSize', fontSize);
ylabel('Slope Difference', 'FontSize', fontSize);
grid on;
caption = sprintf('Slope Differences Maximum at Index = %d, x value = %.2f', indexOfMaxSlopeDiff, x(indexOfMaxSlopeDiff));
title(caption, 'FontSize', fontSize);
% Mark it with a red line.
line([indexOfMaxSlopeDiff, indexOfMaxSlopeDiff], [0, maxSlopeDiff], 'Color', 'r', 'LineWidth', 2);
% Show everything together all on one plot.
% Plot lines.
subplot(2, 2, 3:4);
plot(x, y, 'b.', 'MarkerSize', markerSize);
grid on;
xlabel('x', 'FontSize', fontSize);
ylabel('y', 'FontSize', fontSize);
hold on;
% Use the equation of line1 to get fitted/regressed y1 values.
slope1 = lineData(indexOfMaxSlopeDiff).line1(1);
intercept1 = lineData(indexOfMaxSlopeDiff).line1(2);
y1Fitted = slope1 * x + intercept1;
% Plot line 1 over/through data.
plot(x, y1Fitted, 'r-', 'LineWidth', 2);
% Use the equation of line2 to get fitted/regressed y2 values.
slope2 = lineData(indexOfMaxSlopeDiff).line2(1);
intercept2 = lineData(indexOfMaxSlopeDiff).line2(2);
y2Fitted = slope2 * x + intercept2;
% Plot line 2 over/through data.
plot(x, y2Fitted, 'r-', 'LineWidth', 2);
% Mark crossing with a magenta line.
xc = (intercept2 - intercept1) / (slope1 - slope2);
xline(xc, 'Color', 'm', 'LineWidth', 2);
title('Data with left and right lines overlaid', 'FontSize', fontSize);
message1 = sprintf('Left  Equation: y = %.3f * x + %.3f', slope1, intercept1);
message2 = sprintf('Right Equation: y = %.3f * x + %.3f', slope2, intercept2);
message = sprintf('%s\n%s', message1, message2);
fprintf('%s\n', message);
text(27, 7, message, 'Color', 'r', 'FontSize', 15, 'FontWeight', 'bold');
uiwait(helpdlg(message));

You'll notice that I picked a splitting point at every index from 10% of the way through until 90% of the way through and computed lines on each side of that split point.  Then I looked at, and plotted in the upper left graph, the difference in slopes between the right line and left line.  The best intersection point will be where the difference in slopes is greatest.  You'll see this printed out:
maxSlopeDiff =
         0.292467879717763
indexOfMaxSlopeDiff =
   167
Left  Equation: y = 0.003 * x + 4.042
Right Equation: y = 0.295 * x + -5.968
so you can see that at index 167, which is x=34.3, is the best place to split the curve up into two linear segments, and the equation of the lines on each side are given.
Did this match what you got for the two line equations?  It should.  Then you repeated it for the other two data sets, right?  How did that work out?
0 Comments
  Star Strider
      
      
 on 7 Mar 2020
        And of course — 
T1 = readtable('combined_data.xlsx');
A = str2double(table2array(T1(2:end,:)));
figure
Cm = lines(fix(size(A,2)/2));
hold on
for k = 1:fix(size(A,2)/2)
    x = A(:,1+2*(k-1));
    y = A(:,2+2*(k-1));
    cp{k} = ischange(y, 'linear', 'Threshold',0.25);                            % Find Change Points
    cpidx{k} = find(cp{k}, 2, 'first');                                         % Change Point Indices
    hl{k} = plot(x, y, ':', 'Color',Cm(k,:));                                   % Plot Raw Data
    C = hl{k}.Color;
    idxrng = {1:cpidx{k}(1); cpidx{k}(1):cpidx{k}(2)};                          % Index Range For This Data Set
    xr1 = x(idxrng{1});                                                         % Data For Linear Regression
    yr1 = y(idxrng{1});                                                         % Data For Linear Regression
    xr2 = x(idxrng{2});                                                         % Data For Linear Regression
    yr2 = y(idxrng{2});                                                         % Data For Linear Regression
    B{k,1} = [xr1(:) ones(size(xr1(:)))] \ yr1(:);                              % Estimate Parameters: First Set
    B{k,2} = [xr2(:) ones(size(xr2(:)))] \ yr2(:);                              % Estimate Parameters: Second Set
%     plot(x(cpidx{k}), y(cpidx{k}), '^', 'MarkerFaceColor',C, 'MarkerSize',10)   % Plot Change Points (Un-Comment This Line To See Them)
    yf1 = [xr1(:) ones(size(xr1(:)))] * B{k,1};                                 % Fit First Regression Line
    yf2 = [xr2(:) ones(size(xr2(:)))] * B{k,2};                                 % Fit Second Regression Line
    plot(xr1, yf1, 'Color',C, 'LineWidth',2)                                    % Plot First Regression Line
    plot(xr2, yf2, 'Color',C, 'LineWidth',2)                                    % Plot Second Regression Line
    xint(k,:) = (B{k,1}(2)-B{k,2}(2)) / (B{k,2}(1)-B{k,1}(1));                  % Solve For ‘x’ Intersection
    yint(k,:) = [xint(k) 1] * B{k,1};                                           % Solve For ‘y’ Intersection
%     pause(5)
end
hold off
grid
legend([hl{:}], {'Columns 1:2','Columns 3:4','Columns 5:6'}, 'Location','E')
Regressions = array2table([B{:,1};B{:,2}], 'VariableNames',{'Cols_12','Cols_34','Cols_56'}, 'RowNames',{'Slope_1','Intercept_1','Slope_2','Intercept_2'})
Intersections = table(xint, yint, 'VariableNames',{'X_Intersect','Y_Intersect'}, 'RowNames',{'Cols_12','Cols_34','Cols_56'})
producing: 
Regressions =
                    Cols_12      Cols_34     Cols_56 
                   _________    _________    ________
    Slope_1        0.0027788    0.0022421    0.003146
    Intercept_1       4.0321       4.0616      4.0364
    Slope_2          0.32669      0.30598     0.64086
    Intercept_2      -6.9594      -7.1488     -19.264
Intersections =
               X_Intersect    Y_Intersect
               ___________    ___________
    Cols_12      33.933         4.1264   
    Cols_34      36.908         4.1444   
    Cols_56      36.537         4.1513  
and: 

0 Comments
  KSSV
      
      
 on 6 Mar 2020
        - Load the excel file into MATLAB using xlsread.
- Divide the data into sections using data1 = data(1:1000,:) ; data2 = data(1001:2000,:) ;
- Fit the staright line to each data/ curve using polyfit. Evaluate the values using polyval.
- Find the intersection of lines using InterX available from the link: https://in.mathworks.com/matlabcentral/fileexchange/22441-curve-intersections?focused=5165138&tab=function
9 Comments
  KSSV
      
      
 on 6 Mar 2020
				Did you copy the function in the working folder? The error clearly says it is unable to find the function InterX. 
  Image Analyst
      
      
 on 6 Mar 2020
        How is this different than your duplicate question that I answered here:
4 Comments
  KSSV
      
      
 on 6 Mar 2020
				Download the function which is give in the link.......copy the file InterX.m into the present working directory. 
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


