Bi-linear (piecewise) curve fitting
古いコメントを表示
Can someone explain how to plot the two linear lines (Billinear curve fiiting) from the existing curve?

20 件のコメント
Mathieu NOE
2023 年 3 月 6 日
hello
the first is fairly simple : take your data first two samples and you have a slope + origin
the second could be obtained with first order polynomial fit (using polyfit) with the remaining data (i.e. without the first two samples).
Mark Cuanan
2023 年 3 月 6 日
@Mark Cuanan there is nothing in the range of 0 - 0.25. Plus the shape does not look like what you showed.
t = readtable('pushx.xlsx')
x = t.Displacement;
y = t.BaseForce;
% Get rid of nans
badRows = any(isnan([x, y]), 2);
x(badRows) = []; % Remove NaN rows.
y(badRows) = []; % Remove NaN rows.
% Plot data
plot(x, y, '-', 'LineWidth', 2);
grid on;
fontSize = 14;
xlabel('Displacement', 'FontSize',fontSize);
ylabel('BaseForce', 'FontSize',fontSize);
Plus, at what point are you dividing your data into the left part and the right part? It looks like it's 0.002. How did you decide on that location?
Mark Cuanan
2023 年 3 月 7 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mathieu NOE
2023 年 3 月 7 日
移動済み: John D'Errico
2024 年 1 月 30 日
hello
see my answer below
cheers
Star Strider
2023 年 3 月 7 日
@Mark Cuanan — Thank you for not posting the required information originally (instead posting it in the middle of the night my time, 12 hours after the original post), and then asking a question originally that had absolutely nothing to do with the actual problem.
Mark Cuanan
2023 年 3 月 11 日
Mark Cuanan
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mathieu NOE
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
hello again
simply change the code lines to access the right columns of your excel file

T1 = readtable('testdata.xlsx');
% x = T1.Displacement;
% y = T1.BaseForce;
x = T1.Var3;
y = T1.Var4;
% top flat curve (apex)
[m,idy] = max(y);
ym = m*ones(size(y));
xm = x(idy);
figure(1)
% red curve ( "yellow" net area must be zero)
% origin = 0,0 (first data point)
x1 = x(1);
y1 = y(1);
% let's find out which second point of the curve let us find the min area
xx = x(1:idy);
yy = y(1:idy);
for ck = 2:idy
x2 = x(ck);
y2 = y(ck);
slope = (y2-y1)/(x2-x1);
yl = y1 + slope*(xx - x1);
% compute yellow area A
A(ck) = trapz(xx,(yy-yl));
% remove small triangle area above green line
% first find intersection point (lines red / green) coordinates
yint = m; % obvious
xint = (yint-y1)/slope + x1;
% plot(xint,yint,'dk',xx,yl,'r','Linewidth',1.5); % debug plot
b = xm - xint; % triangle base
h = yl(end) - m; % triangle height
At(ck) = - 0.5*b*h; % triangle area (NB : must be a negative number to be consistent with my
% definition of area A = integral of (yy-yl)
% as written above : A(ck) = trapz(xx,(yy-yl));
end
% plot A , At vs iteration index (for loop above)
figure(2)
plot(A);
hold on
plot(At);
A = A - At; % actually remove that extra triangle area (At)
plot(A);
legend('A before correction','At','A after correction');
% find zero crossing value for A (with linear interpolation)
threshold = 0;
xx_zc = find_zc(xx,A,threshold);
yy_zc = interp1(xx,yy,xx_zc);
slope = (yy_zc-y1)/(xx_zc-x1);
yl = y1 + slope*(xx - x1);
% coordinates on the intersection of the red and green line
threshold = m;
xx_intersect = find_zc(xx,yl,threshold)
yy_intersect = interp1(xx,yl,xx_intersect)
figure(1)
plot(x,y,'*-',x,ym,'g','Linewidth',2);
hold on
plot(xint,yint,'dm',xx_intersect,yy_intersect,'dk',xx,yl,'r','Linewidth',2);
text(xx_intersect,1.1*yy_intersect,['X intersect = ' num2str(xx_intersect)]);
text(xx_intersect,1.05*yy_intersect,['Y intersect = ' num2str(yy_intersect)]);
% display the area values
% compute yellow area A
Ac = cumtrapz(xx,(yy-yl));
% remove small triangle area above green line
b = xm - xx_intersect; % triangle base
h = yl(end) - m; % triangle height
At = - 0.5*b*h; % triangle area (NB : must be a negative number to be consistent with my
% definition of area A = integral of (yy-yl)
Ac = Ac - At; % actually remove that extra triangle area (At)
area_value = interp1(xx,Ac,xx_zc); % area_value is the value of Ac for x = xx_zc (point where red line crosses the data line)
text(xx_zc*0.4,y1 + slope*(xx_zc*0.5 - x1),['Area = ' num2str(area_value,'%.2e')]);
text(xx_intersect*0.97,yy_intersect*0.95,['Area = ' num2str(-area_value,'%.2e')]);
% figure(3) % debug plot for me
% plot(xx_zc,area_value,'dk',xx,Ac,'r','Linewidth',2);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Zx] = find_zc(x,y,threshold)
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
Zx = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end
Mark Cuanan
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mark Cuanan
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
Star Strider
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
... and the target keeps moving!
Mark Cuanan
2023 年 3 月 13 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mathieu NOE
2023 年 3 月 14 日
移動済み: John D'Errico
2024 年 1 月 30 日
hello again
well , ok , I don't mind continuing this work but I need more precise explanations :
And the green line must be under the curve...
where exactly ?
the red line touches about 60% of the baseforce value?
you mean the red line stil start at the origin an then crosses the experimental data at y = 60 % of the peak value ?
Mark Cuanan
2023 年 3 月 14 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mathieu NOE
2023 年 3 月 15 日
移動済み: John D'Errico
2024 年 1 月 30 日
for the red line I have no issue - this is very simple
but for the green line , I miss another constraint or input ; I cannot solve a problem with only one constraint (both areas must be equal) while I must find 2 unknowns a & b (y = a x + b )
how did you choose the slope in the example shown above ?
Mark Cuanan
2023 年 3 月 15 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mathieu NOE
2023 年 3 月 15 日
移動済み: John D'Errico
2024 年 1 月 30 日
it(s not a manner of programming (with or without loop) it's basically a 2 degree of freedom equation with only one constraint / data . You are still capable to find multiple solutions that fullfills the equal area constraint
without any programming, simply visually you can find a horizontal green line that can have both areas equal
as well as a slight positive sloped green line that also has equal areas
so which one do you want ?
do you have some publications to refer to ? or standard ? maybe that info is available there
Mark Cuanan
2023 年 3 月 15 日
移動済み: John D'Errico
2024 年 1 月 30 日
Mark Cuanan
2023 年 4 月 2 日
移動済み: John D'Errico
2024 年 1 月 30 日
採用された回答
その他の回答 (1 件)
Mathieu NOE
2023 年 4 月 3 日
hello
here you are
all the best
for this data file the max point of the red curve is displayed on the graph
xred_max = 662.0233
yred_max = 15500;

T1 = readtable('New sample Pls open.xlsx');
x = T1.Var3;
y = T1.Var4;
% remove NaN's
idx = isnan(x);
idy = isnan(y);
id = idx & idy;
x(id) = [];
y(id) = [];
% find max force point (apex)
[m,idy] = max(y);
% ym = m*ones(size(y));
xm = x(idy);
% create the red curve for y going up to 15500
% origin = 0,0 (first data point)
x1 = x(1);
y1 = y(1);
% find 60% of max value crossing value for A (with linear interpolation)
threshold = 0.6*m;
x_c = find_zc(x,y,threshold);
y_c = interp1(x,y,x_c);
slope = (y_c-y1)/(x_c-x1);
yred_max = 15500;
xred_max = x1 + (yred_max-y1)/slope;
xred = linspace(x1,xred_max,10);
yred = y1 + slope*(xred - x1);
figure(1)
plot(x,y,'*-',xred,yred,'r','Linewidth',2);
text(xred_max*1.01,yred_max*1.01,['X = ' num2str(xred_max) ' / Y = ' num2str(yred_max)]);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [Zx] = find_zc(x,y,threshold)
% positive slope "zero" crossing detection, using linear interpolation
y = y - threshold;
zci = @(data) find(diff(sign(data))>0); %define function: returns indices of +ZCs
ix=zci(y); %find indices of + zero crossings of x
ZeroX = @(x0,y0,x1,y1) x0 - (y0.*(x0 - x1))./(y0 - y1); % Interpolated x value for Zero-Crossing
Zx = ZeroX(x(ix),y(ix),x(ix+1),y(ix+1));
end
2 件のコメント
Mark Cuanan
2023 年 4 月 4 日
Mathieu NOE
2023 年 4 月 4 日
hello
I wish I could be again, same remark as before , how would you solve a two unknowns problem with only one input ? the area must be equal but that is not enough to give the green line a slope and an origin
I could simply decide that the slope is zero or what is your suggestion ? how did you do in the excel file ? for me it seems you simply draw a line but how did you decide for the slope ?
all the best
カテゴリ
ヘルプ センター および File Exchange で Polar Plots についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!





