Curve fitting with Levenberg-Marquardt algorithm

조회 수: 16 (최근 30일)
GreenValleyB
GreenValleyB 2022년 8월 2일
편집: Infinite_king 2023년 9월 26일
I want to fit a custom function to a dataset with the following values:
%This data is collected from the data below. It comes from a 10x10 matrix
%and I need the rows [1 4 5] for specific purposes. That is why the codes
%looks too big, but is in fact a restribution of data.
x_data = [1.68995000000000 1.67356950000000 1.69012730000000 1.69841930000000 1.70660157500000 1.72105803000000 1.73417499500000 1.74831049750000 1.77170521600000 1.78799623600000 ; ...
0.845360000000000 0.751521500000000 0.761509900000000 0.756846750000000 0.755428325000000 0.752491960000001 0.752734425000001 0.756773460000004 0.761931829999993 0.766921715000000 ; ...
2.60905500000000 2.52328050000000 2.53137270000000 2.54665280000000 2.57327365000000 2.61874219000000 2.65582985000000 2.68521748250000 2.71079400200000 2.69824300800000 ]
y_data = [0.219970548869443 0.815706518602178 1.39509549501506 1.71961499263378 2.11330719376825 2.92533458286614 3.87232815557023 5.26474561602075 7.86182243535394 10.5374746473838 ; ...
0.0642339602535873 0.169476385473391 0.333488789915357 0.386605265203827 0.440998338154743 0.538448868958661 0.620497982025440 0.725751134956693 0.922329295454408 1.20273021731183 ; ...
0.721637615151627 2.37225924529110 4.21538558708732 5.33208295040392 6.79868950885182 9.65661324356717 12.5494793161649 16.2135119764150 22.1717696376411 27.3348431675366 ]
eave_data = [0.511623450000000 0.510701460000000 0.509541980000000 0.508871890500000 0.508029996750000 0.506469197900000 0.504673369800000 0.502044141175002 0.496770950180000 0.490995012415000 ; ...
0.508641150000000 0.508465500000000 0.508151158000000 0.507993901000000 0.507816865000000 0.507554680200001 0.507337630400000 0.507106704825006 0.506744231299999 0.506337948470000 ; ...
0.502123600000000 0.500216710000000 0.497755699000000 0.496243499500000 0.494246570250000 0.490432166300000 0.486290536300001 0.480809998450000 0.471233465220000 0.462093520630000]
Ce_data = [0.485782500000000 0.484491450000000 0.483157650000000 0.482326400000000 0.481256700000000 0.479023250000000 0.476403150000000 0.472544250000000 0.465113350000000 0.457141900000000 ; ...
0.483133900000000 0.482860300000000 0.482498350000000 0.482327350000000 0.482136400000000 0.481847600000000 0.481619600000000 0.481382100000000 0.480901400000000 0.480256350000000 ; ...
0.476538050000000 0.473938850000000 0.470942550000000 0.468958000000000 0.466260950000000 0.460949500000000 0.455317900000000 0.448167250000000 0.436138350000000 0.425210500000000]
%Original dataset, which came from an even bigger one. But these are
%important for the this curve fitting.
epsilonampl = [1.68995000000000 1.67356950000000 1.69012730000000 1.69841930000000 1.70660157500000 1.72105803000000 1.73417499500000 1.74831049750000 1.77170521600000 1.78799623600000 ;
1.80913500000000 1.77612850000000 1.77461040000000 1.77382280000000 1.77118812500000 1.76756418000000 1.76984687500000 1.77848557500001 1.80125089100001 1.80059083500000 ;
1.42231000000000 1.41365750000000 1.44327620000000 1.45454830000000 1.46592077500000 1.49942036000000 1.52881787500000 1.56116331500000 1.60480011299999 1.63390681050000 ;
0.845360000000000 0.751521500000000 0.761509900000000 0.756846750000000 0.755428325000000 0.752491960000001 0.752734425000001 0.756773460000004 0.761931829999993 0.766921715000000 ;
2.60905500000000 2.52328050000000 2.53137270000000 2.54665280000000 2.57327365000000 2.61874219000000 2.65582985000000 2.68521748250000 2.71079400200000 2.69824300800000 ;
1.25974500000000 1.15777800000000 1.18113270000000 1.17785195000000 1.17870765000000 1.19160369000000 1.21128859000000 1.23377914250000 1.26779698600000 1.29254151900000 ;
2.06843000000000 1.96272550000000 1.98881510000000 2.00038080000000 2.01178252500000 2.03431910000000 2.06737115500000 2.10785441250000 2.16685295800000 2.19641107850000 ;
1.59727500000000 1.56965400000000 1.61065480000000 1.61401480000000 1.62046692500000 1.63481720000000 1.64983897000000 1.67536094750000 1.71700520600000 1.75151178850000 ;
1.65214500000000 1.64498350000000 1.65268200000000 1.66672140000000 1.68123452500000 1.70255762000000 1.72431821000000 1.75237155500000 1.78956005300000 1.81168614150000 ;
1.31446500000000 1.34041950000000 1.36544320000000 1.37398980000000 1.38366432500000 1.39477109000000 1.40866851000000 1.43014082750000 1.46985591700000 1.50364010100000]
eliminierung_campl = [0.219970548869443 0.815706518602178 1.39509549501506 1.71961499263378 2.11330719376825 2.92533458286614 3.87232815557023 5.26474561602075 7.86182243535394 10.5374746473838 ;
0.178212538524405 0.610891612212584 1.05873240345686 1.32057490932360 1.66272908653406 2.35017757341005 3.19217848022701 4.39544605838876 6.71506858407999 8.97745161731723 ;
0.317374045573957 1.31533503453183 2.27416029843252 2.77867550745613 3.34090395849249 4.39157279755229 5.59916994226081 7.39821805023363 11.0712000028568 14.9433243509966 ;
0.0642339602535873 0.169476385473391 0.333488789915357 0.386605265203827 0.440998338154743 0.538448868958661 0.620497982025440 0.725751134956693 0.922329295454408 1.20273021731183 ;
0.721637615151627 2.37225924529110 4.21538558708732 5.33208295040392 6.79868950885182 9.65661324356717 12.5494793161649 16.2135119764150 22.1717696376411 27.3348431675366 ;
0.277387135970351 0.816199784223801 1.62796170470247 1.79429210358029 2.03003583146033 2.61988161812730 3.42571414878310 4.66549357115017 7.24569141698775 10.0756212106590 ;
0.433664540530333 1.04389545903620 1.70366206417345 2.02840711616856 2.44663548568462 3.26670408509225 4.29006082136354 5.75289862637344 8.54605544601133 11.4817886043978 ;
0.296289880737664 0.825906844633911 1.47891262699295 1.73375721380982 2.07105831778929 2.79606909732602 3.67809507974306 5.01795852014047 7.74596871737049 10.6915272467139 ;
0.228770613022142 0.718261535758381 1.20754669762319 1.50052534533639 1.90133688008586 2.72047090926408 3.70024032220998 5.11856065180731 7.81320857170644 10.4566681534346 ;
0.234908809894484 0.636085998286533 1.00600951455756 1.22645349625657 1.48142020124878 1.94632942267008 2.41887607337860 3.17720915635447 4.91836945589996 7.00981003502703]
eave = [0.511623450000000 0.510701460000000 0.509541980000000 0.508871890500000 0.508029996750000 0.506469197900000 0.504673369800000 0.502044141175002 0.496770950180000 0.490995012415000 ;
0.510243700000000 0.509318530000000 0.508121999000000 0.507421250500000 0.506506232000000 0.504705086500001 0.502566729650001 0.499390536075001 0.493113976700001 0.486402081405000 ;
0.493188850000000 0.492474695000000 0.491534898000000 0.491014827500000 0.490374352750000 0.489270044900000 0.488091355500000 0.486388426150000 0.482883968699999 0.478827431860000 ;
0.508641150000000 0.508465500000000 0.508151158000000 0.507993901000000 0.507816865000000 0.507554680200001 0.507337630400000 0.507106704825006 0.506744231299999 0.506337948470000 ;
0.502123600000000 0.500216710000000 0.497755699000000 0.496243499500000 0.494246570250000 0.490432166300000 0.486290536300001 0.480809998450000 0.471233465220000 0.462093520630000 ;
0.500206750000000 0.499500520000000 0.498217855000000 0.497682240500000 0.497130307250000 0.496112222700000 0.494860150099999 0.492905573300000 0.488731526790002 0.483871039955000 ;
0.497748500000000 0.496921155000000 0.495837435000000 0.495266439500000 0.494578131500000 0.493339576300000 0.491938604200000 0.489877810925001 0.485673815829998 0.480839703225000 ;
0.481535600000000 0.480925235000000 0.480061888000000 0.479630788000000 0.479123975250000 0.478177226500000 0.477058980900000 0.475361809474999 0.471749224670001 0.467555096565000 ;
0.531027100000000 0.530124655000000 0.528954710000000 0.528237271000000 0.527313733250000 0.525530434900000 0.523419833000000 0.520284491225000 0.513938645160002 0.507106289950000 ;
0.437652600000000 0.437408155000000 0.437121344000000 0.436952670000000 0.436748043750000 0.436399650500000 0.436042361900000 0.435518252075002 0.434288406240004 0.432692610370000 ]
Ce_0 = [ 0.485782500000000 0.484491450000000 0.483157650000000 0.482326400000000 0.481256700000000 0.479023250000000 0.476403150000000 0.472544250000000 0.465113350000000 0.457141900000000 ;
0.484469600000000 0.483170000000000 0.481786800000000 0.480892850000000 0.479655000000000 0.477003550000000 0.473775450000000 0.469086250000000 0.460372850000000 0.451540700000000 ;
0.468333850000000 0.467309750000000 0.466249550000000 0.465606400000000 0.464813150000000 0.463397650000000 0.461735150000000 0.459228100000000 0.454050600000000 0.448238500000000 ;
0.483133900000000 0.482860300000000 0.482498350000000 0.482327350000000 0.482136400000000 0.481847600000000 0.481619600000000 0.481382100000000 0.480901400000000 0.480256350000000 ;
0.476538050000000 0.473938850000000 0.470942550000000 0.468958000000000 0.466260950000000 0.460949500000000 0.455317900000000 0.448167250000000 0.436138350000000 0.425210500000000 ;
0.475024700000000 0.473995850000000 0.472436900000000 0.472030300000000 0.471371950000000 0.469909900000000 0.467929150000000 0.464934750000000 0.458702750000000 0.451766800000000 ;
0.472596500000000 0.471450800000000 0.470242400000000 0.469574550000000 0.468711000000000 0.467009550000000 0.464953750000000 0.461921350000000 0.455826150000000 0.448861700000000 ;
0.457238800000000 0.456438900000000 0.455411950000000 0.454946450000000 0.454328950000000 0.452952400000000 0.451262350000000 0.448671700000000 0.443308000000000 0.437285950000000 ;
0.504230550000000 0.502981300000000 0.501583850000000 0.500667100000000 0.499423550000000 0.496834800000000 0.493668450000000 0.489073300000000 0.480056850000000 0.470997650000000 ;
0.415623100000000 0.415323850000000 0.414980900000000 0.414779500000000 0.414529650000000 0.414098350000000 0.413593900000000 0.412770250000000 0.410770500000000 0.408280550000000 ]
Here ist the code of my plot:
%A for loop in order to do the fitting for each cycle.
i_vals = 1:10
j_vals = [1 4 5]
x_data = zeros(length(j_vals), length(i_vals))
y_data = zeros(length(j_vals), length(i_vals))
eave_data = zeros(length(j_vals), length(i_vals))
Ce_data = zeros(length(j_vals), length(i_vals))
figure
for i = 1:length(i_vals)
for j = 1:length(j_vals)
x_data (j,i) = epsilonampl(j_vals(j), i)
y_data (j,i) = eliminierung_campl(j_vals(j), i)
eave_data (j,i) = eave(j_vals(j), i)
Ce_data (j,i) = Ce_0(j_vals(j), i)
fun = @(x,x_data)x(1)*exp(x(2)*x_data);
x0 = [100,-1];
x = lsqcurvefit(fun,x0,x_data,y_data)
times = linspace(x_data(1),x_data(end));
plot(x_data,y_data,'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')
hold on
end
end
This code creates the plot which is seen. I want to use the following function to fit the curve:
%fun = k .* (Ce_data - eave_data) .^2 ./ (1 + eave_data)
%k is a factor for the function so that the curve fitting is adapted to the
%function. Therwise the function is the same and the curve cannot be fitted
%to the data correctly.
It should look like that:
I would appreciate the help!

답변 (1개)

Infinite_king
Infinite_king 2023년 9월 26일
편집: Infinite_king 2023년 9월 26일
Hi,
I understand that you want to fit a subset of the dataset using the selected non-linear function. The 'lsqcurvefit' function is not fitting the curve properly, possibly due to not including all the data points or, in some cases, including data points from other datasets.
To resolve this problem, you can try the following fixes,
  • Copy all the datapoints before calling “lsqcurvefit"
num_columns = 10; % number of columns of dataset
selected_rowns = j_vals;
for j = 1:num_columns
x_data (:,j) = epsilonampl(selected_rowns, j); %copy j'th column of selected rows
y_data (:,j) = eliminierung_campl(selected_rowns, j); %copy j'th column of selected rows
end
  • Fit the curve by passing the set of datapoints
for j = 1:num_columns
x = lsqcurvefit(fun,x0,x_data(:,j),y_data(:,j)); % fit the curve for only j'th column
times = linspace(min(x_data(:,j)),max(x_data(:,j))); % find the lowest and highest to calculate the range of plot
plot(x_data(:,j),y_data(:,j),'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')
hold on
end
Please find the complete code and its output below,
i_vals = 1:10;
j_vals = [1 4 5];
x_data = zeros(length(j_vals), length(i_vals));
y_data = zeros(length(j_vals), length(i_vals));
eave_data = zeros(length(j_vals), length(i_vals));
Ce_data = zeros(length(j_vals), length(i_vals));
figure
% ------------- Modified -------------
num_columns = 10;
selected_rowns = j_vals;
for j = 1:num_columns
x_data (:,j) = epsilonampl(selected_rowns, j); %copy j'th column of selected rows
y_data (:,j) = eliminierung_campl(selected_rowns, j); %copy j'th column of selected rows
end
fun = @(x,x_data)x(1)*exp(x(2)*x_data);
x0 = [100,-1];
% ------------- Modified -------------
for j = 1:num_columns
x = lsqcurvefit(fun,x0,x_data(:,j),y_data(:,j)); % fit the curve for only j'th column
times = linspace(min(x_data(:,j)),max(x_data(:,j))); % find the lowest and highest to calculate the range of plot
plot(x_data(:,j),y_data(:,j),'ko',times,fun(x,times),'b-')
legend('Data','Fitted exponential')
title('Data and Fitted Curve')
hold on
end
For more information, please refer the following resources -
Hope this is helpful.

카테고리

Help CenterFile Exchange에서 Linear and Nonlinear Regression에 대해 자세히 알아보기

제품


릴리스

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by