Need help to code the power Low fit using least square regression
Mostrar comentarios más antiguos
I have the following data:
X = [0.17,0.17,0.5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3.5,3.5,4,4,4.5,6,6,10,10,10,12,15,18,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,37,49,72,72,72,96,96,120,192];
Y = [30,30,60,50,15,40,40,30,100,30,17,29,44,40,125,52,102,64,52,85,34,12.7,62.3,12.8,50,169,33.3,40,15,20,25,10.4,12.7,17.8,6.25,7.5,12.5,6.25,6.33,5.29,7.42,17.7,16.7,19.4,28.6,6.25,10.21,4.46,5.5,30,8.42,13.96,6.53,6.56,6.94,6.72,2.65,2.94,4.17,4.18];
I need a code to deriv the power law as Y= 14.82 X^(-0.39) (which is of the form y=b. x.^m) using constrained least squares. Could you please help me with the code how to get the b and m as 14.82 and -.39 respectively? I think we need to apply some optimization for getting the exact values.
Any help will be much appreciated.
Respuesta aceptada
Más respuestas (2)
Michael Madelaire
el 2 de En. de 2019
Here is my attempt. But it does not use a non linear fit as the suggestion above.
Instead I fit the log.
%% Init
clear all; close all; clc;
%% Data
X = [0.17,0.17,0.5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3.5,3.5,4,4,4.5,6,6,10,10,10,12,15,18,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,37,49,72,72,72,96,96,120,192];
Y = [30,30,60,50,15,40,40,30,100,30,17,29,44,40,125,52,102,64,52,85,34,12.7,62.3,12.8,50,169,33.3,40,15,20,25,10.4,12.7,17.8,6.25,7.5,12.5,6.25,6.33,5.29,7.42,17.7,16.7,19.4,28.6,6.25,10.21,4.46,5.5,30,8.42,13.96,6.53,6.56,6.94,6.72,2.65,2.94,4.17,4.18];
y_log = log(Y);
x_log = log(X);
%% Plot data
figure;
subplot(2,1,1);
plot(X, Y, '.', 'MarkerSize', 10);
grid on;
title('True data');
subplot(2,1,2);
plot(x_log, y_log, '.', 'MarkerSize', 10);
grid on;
title('Log of data');
%% build data kernel
G = ones(length(X),2);
G(:,2) = x_log;
%% Solve LSQ
model = G\y_log';
%% Extract model coefficients
b = exp(model(1));
m = exp(model(2));
fprintf('\nThe fit to your function is Y=%.3f*X^{%.3f}\n',b,m)
%% Predict
x_pred = -2:0.01:6;
G_pred = ones(length(x_pred), 2);
G_pred(:, 2) = x_pred;
y_pred = G_pred*model;
%% Plot fit
figure;
subplot(2,1,1);
plot(X, Y, '.', 'MarkerSize', 10);
hold on;
plot(exp(x_pred), exp(y_pred));
grid on;
title('True data - x truncated at 200');
legend('Data', 'Fit');
xlim([0,200]);
subplot(2,1,2);
plot(x_log, y_log, '.', 'MarkerSize', 10);
hold on;
plot(x_pred, y_pred);
grid on;
title('Log of data');
legend('Data', 'Fit');
%% Residuals
G = ones(length(X),2);
G(:,2) = x_log;
r_my_model = exp(y_log-G*model);
your_model = [14.82; -.39];
r_your_model = Y-your_model(1)*X.^your_model(2);
figure;
subplot(2,1,1);
histogram(r_my_model, 'binWidth', 0.5);
grid on;
title('My model - residuals');
subplot(2,1,2);
histogram(r_your_model, 'binWidth', 0.5);
grid on;
title('Your model - residuals');


1 comentario
geethu th
el 2 de En. de 2019
Torsten
el 2 de En. de 2019
0 votos
function main
X = [0.17,0.17,0.5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3.5,3.5,4,4,4.5,6,6,10,10,10,12,15,18,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,37,49,72,72,72,96,96,120,192];
Y = [30,30,60,50,15,40,40,30,100,30,17,29,44,40,125,52,102,64,52,85,34,12.7,62.3,12.8,50,169,33.3,40,15,20,25,10.4,12.7,17.8,6.25,7.5,12.5,6.25,6.33,5.29,7.42,17.7,16.7,19.4,28.6,6.25,10.21,4.46,5.5,30,8.42,13.96,6.53,6.56,6.94,6.72,2.65,2.94,4.17,4.18];
% Fit data
p0 = [14.82,-0.39];
p = fmincon(@(p)fun(p,X,Y),[],[],[],[],[],[],@(p)nonlcon(p,X,Y))
end
function obj = fun(p,X,Y)
obj = sum((p(1)*X.^p(2) - Y).^2);
end
function [c,ceq] = nonlcon(p,X,Y)
c = p(1)*X.^p(2) - Y;
ceq = [];
end
12 comentarios
Geethu T H
el 2 de En. de 2019
Thanks Torsten.
But, I think you are didnt understand the problem. And dont use b=14.82, m=-.39 directly as you used in the program(ie. p0 = [14.82,-0.39]). Because our aim is to code for getting b=14.82 and m=-.39.
Let me make it more clear.
I have some X and Y values as:
X=[0.17,0.17,0.5,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,3,3.5,3.5,4,4,4.5,6,6,10,10,10,12,15,18,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,24,37,49,72,72,72,96,96,120,192];
Y = [30,30,60,50,15,40,40,30,100,30,17,29,44,40,125,52,102,64,52,85,34,12.7,62.3,12.8,50,169,33.3,40,15,20,25,10.4,12.7,17.8,6.25,7.5,12.5,6.25,6.33,5.29,7.42,17.7,16.7,19.4,28.6,6.25,10.21,4.46,5.5,30,8.42,13.96,6.53,6.56,6.94,6.72,2.65,2.94,4.17,4.18];
I want to fit the data in the form of
.
And I know that, b=14.82, m=-.39. But I dont know how to get b=14.82, m=-.39 from the above X and Y. So I need a code to get this b and m.
Image Analyst
el 2 de En. de 2019
'fmincon' requires Optimization Toolbox.
Since I don't have that toolbox, what is the p you got?
p(1) = his "b" variable.
p(2) = his "m" variable.
Geethu T H
el 2 de En. de 2019
Actually I dont know how to get optimised solution of b and m. I need help in that only. I know X-Y value and will get Y = 14.82 X^(-0.39). But I dont know how can I get it and need a code for the same. ie, after running the code(which may contain the concept of regression and optimization), I need to get b=14.82 and m= -.39 as output.
Torsten
el 2 de En. de 2019
What do you get for p if you run my code ? Isn't it p(1) = 14.82 and p(2) = -0.39 approximately ?
Geethu T H
el 2 de En. de 2019
It is p(1) = 14.82 and p(2) = -0.39. But you are using p0 = [14.82,-0.39] in your code. This is the required solution which we need to find by applying some regression and optimization(iterate for n times for getting optimised solution. I have only this much idea). so we cannot use p0 = [14.82,-0.39].
Image Analyst
el 2 de En. de 2019
It looks like you're doing a fit through ALL the data. Geethu doesn't want that. He wants a fit through only two points. The two bottom most ones. And those two points are the ones such that a line drawn through them is below all other points.
So first you need to draw lines between every pair of points to determine which pair is on a line below all other points. Then, and only then, get the b and m from only that one pair of points.
Torsten
el 2 de En. de 2019
No. As clearly stated, Geethu wants to impose the constraint that
Yi > k1*Xi^k2
for all data points (Xi,Yi).
I define this constraint in the c-vector (c <= 0) , not in the ceq-vector (ceq = 0).
Image Analyst
el 2 de En. de 2019
Geethu, can you run his code (I can't) and tell us what you get for p?
geethu th
el 4 de En. de 2019
Torsten
el 4 de En. de 2019
Use
p = fmincon(@(p)fun(p,X,Y),p0,[],[],[],[],[],[],@(p)nonlcon(p,X,Y));
Categorías
Más información sobre Get Started with Curve Fitting Toolbox en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


