How to improve precision of lsqnonlin analysis
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I used lsqnonlin annlysis to fit a model to two sets of data. The results showed that the differences between original data and fitted line are rather huge (see in Figure1). How to improve this analysis to obtain better results? Thanks! Below are my codes.
function Result = myfunc1(a,p,G,m,fraction)
totalconcentration = 0.0000254;
n = 2;
K = exp(-((G + m .* fraction)./(8.314*298)));
opts = optimoptions('fsolve','Algorithm', 'levenberg-marquardt','FunctionTolerance',1.0000e-12);
monomerconcentration = fsolve(@denaturationfun,0.999,opts);
function y = denaturationfun(x)
y = K.*totalconcentration - a.^(-1).*(((a.*x).^(n+1)).*(n.*a.*x-n-1)./((a.*x-1).^2)+a.*x./((a.*x-1).^2))+a.^(n-1).*((x^(n+1)).*(n.*x-n-1)./((x-1).^2));
end
Result = p * (1- (monomerconcentration ./ ( K * totalconcentration )));
end
clc;
clear;
close all;
fractiondata = [0.0431 0.0478 0.0525 0.0571 0.0617 0.0662 0.0707 0.0751 0.0795 0.0839 0.0882 0.0925 0.0967 0.1009 0.1051 0.1092 0.1133 0.1174 0.1253];
DegreeofAggdata = [0.86089 0.90051 0.84268 0.9543 0.98855 0.98538 1 0.98493 0.91339 0.92209 0.85817 0.78529 0.64172 0.45712 0.24855 0.11291 0.00812 0 0.0169];
fun = @(x)DegreeofAggdata - myfunc1(x(1),x(2),x(3),x(4),fractiondata);
x0 = [0.001,1,-50000,100000];
lb = [0,0.7,-150000,20000];
ub = [1,1.3,-5000,150000];
options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt');
R = lsqnonlin(fun,x0,lb,ub); %% fit model to exp data
A = 0.03:0.001:0.15;
D = zeros(length(A),1);
for i = 1:length(A)
y = myfunc1(R(1),R(2),R(3),R(4),A(i));
D(i)= y;
end
figure(1);
plot(A,D,'r-'); %% draw lines with fitted parameters
hold on;
plot (fractiondata,DegreeofAggdata,'-go');
5 comentarios
Matt J
el 18 de Sept. de 2024
Editada: Matt J
el 18 de Sept. de 2024
@Haotian The inner problem that you are solving with fsolve is a search for a root of a rational function of x. As you know, a rational function will in general have multiple discrete roots. Your code doesn't appear to have a process for deciding which of these roots to select.
Torsten
el 18 de Sept. de 2024
The solution of the inner problem using "fsolve" does not seem to work in each case. You should try to make it more reliable. And - as @Matt J mentionned - there might be multiple solutions, and "fsolve" could pick the wrong one.
clc;
clear;
close all;
fractiondata = [0.0431 0.0478 0.0525 0.0571 0.0617 0.0662 0.0707 0.0751 0.0795 0.0839 0.0882 0.0925 0.0967 0.1009 0.1051 0.1092 0.1133 0.1174 0.1253];
DegreeofAggdata = [0.86089 0.90051 0.84268 0.9543 0.98855 0.98538 1 0.98493 0.91339 0.92209 0.85817 0.78529 0.64172 0.45712 0.24855 0.11291 0.00812 0 0.0169];
fun = @(x)DegreeofAggdata - myfunc1(x(1),x(2),x(3),x(4),fractiondata);
x0 = [0.001,1,-50000,100000];
lb = [0,0.7,-150000,20000];
ub = [1,1.3,-5000,150000];
options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt');
format long
R = lsqnonlin(fun,x0,lb,ub) %% fit model to exp data
A = 0.03:0.001:0.15;
D = zeros(length(A),1);
for i = 1:length(A)
y = myfunc1(R(1),R(2),R(3),R(4),A(i));
D(i)= y;
end
figure(1);
plot(A,D,'r-'); %% draw lines with fitted parameters
hold on;
plot (fractiondata,DegreeofAggdata,'-go');
function Result = myfunc1(a,p,G,m,fraction)
totalconcentration = 0.0000254;
n = 2;
K = exp(-((G + m .* fraction)./(8.314*298)));
opts = optimoptions('fsolve','Algorithm', 'levenberg-marquardt','Display','off','FunctionTolerance',1.0000e-12);
monomerconcentration = fsolve(@denaturationfun,0.999*ones(1,numel(K)),opts);
function y = denaturationfun(x)
y = K.*totalconcentration - a.^(-1).*(((a.*x).^(n+1)).*(n.*a.*x-n-1)./((a.*x-1).^2)+a.*x./((a.*x-1).^2))+a.^(n-1).*((x.^(n+1)).*(n.*x-n-1)./((x-1).^2));
end
Result = p * (1- (monomerconcentration ./ ( K * totalconcentration )));
end
Respuestas (0)
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!