- Define FunModel as a separate function or as an anonymous function that accepts the parameters and the independent variable (x) as inputs and returns the dependent variable (J_mod).
- Pass a handle to this function as the first argument to lsqcurvefit.
Multi-Parameter Curve Fitting --- How to use lsqcurvefit ?
16 views (last 30 days)
Show older comments
Hello!
I am major in chemistry and inexperience with Matlab.
Currently, I'm trying to fit a nonlinear curve with my model, so I use lsqcurvefit to get the parameters of my function. After finishing the code, I obtain this output:
"Error using lsqfcnchk (line 80)
FUN must be a function, a valid character vector expression, or an inline function object.
Error in lsqnsetup (line 46)
funfcn = lsqfcnchk(FUN,caller,lengthVarargin,funValCheck,flags.grad);"
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
My curve fitting problem can be described as follows:
In order to display my code in a simple way, I set N=2, and I make a fake Objective function J_aim for testing. My code is as follows:
global Dim_N
Dim_N = 2;
%--------Objective Function (Curve)---------------
x = linspace(1.4,1.9,1000);
J_aim = 0.01./((x-1.6).^2+0.01^2)+0.05./((x-1.7).^2+0.05^2);
plot(x,J_aim);
hold on
%-----It is just a test, not the real curve I want to fit-----------
%-------Fitting Parameters----------------
gT = [0.5,0.2];
g = transpose(gT);
w = [1.6,0 ; 0, 1.7];
kappa = [0.01,0.05];
%-------Reshape these Parameters----------
para = [gT, kappa, reshape(w,[1,Dim_N^2])];
%-------Initial Gauss---------------------
g0 = [0.3,0.3]; w0 = [1,0; 0, 1]; kappa0 = [0.1, 0.1];
para0 = [gT, kappa, reshape(w,[1,Dim_N^2])];
para_opt = lsqcurvefit(FunModel(para0,x),para0,x,J_aim); % lsqcurvefit fitting method
%-------Fitting Model---------------------
function [J_mod] = FunModel(para,x)
global Dim_N
gT = para(1:Dim_N);
kappa = para(Dim_N+1:2*Dim_N);
w = zeros(Dim_N);
%-------Reconstruct the w matrix----------
point = 0;
for index = 2*Dim_N+1: length(para)
point = point + 1;
i = fix( (point-1)/Dim_N ) + 1;
j = point - (i-1)*Dim_N;
w(i,j) = para(index);
end
%-------My fitting model "J_mod"----------
J_mod = zeros(1,length(x));
g = transpose(gT);
Ht = w - 0.5i*diag(kappa);
for i=1:length(x)
temp = Ht - x(i)*eye(Dim_N);
J_mod(i) = imag( gT*inv(temp)*g ); % J_mod = imag( g^T.(1/(Ht-x)).gT )
end
end
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
So my question is that why is Matlab telling me that the code is wrong? How can I fix my code and return the fitting parameters I want?
Any help will be appreciated. Thanks!
0 Comments
Answers (1)
Vaibhav
on 17 Apr 2024
Hi Siwei
The error is due to lsqcurvefit expecting a function handle as its first input.
Here is a way to modify the code:
Here is a code snippet to help you get started:
global Dim_N
Dim_N = 2;
%--------Objective Function (Curve)---------------
x = linspace(1.4,1.9,1000);
J_aim = 0.01./((x-1.6).^2+0.01^2)+0.05./((x-1.7).^2+0.05^2);
plot(x,J_aim);
hold on
%-------Fitting Parameters----------------
gT = [0.5,0.2];
g = transpose(gT);
w = [1.6,0 ; 0, 1.7];
kappa = [0.01,0.05];
%-------Reshape these Parameters----------
para = [gT, kappa, reshape(w,[1,Dim_N^2])];
%-------Initial Gauss---------------------
g0 = [0.3,0.3]; w0 = [1,0; 0, 1]; kappa0 = [0.1, 0.1];
para0 = [g0, kappa0, reshape(w0,[1,Dim_N^2])]; % Fixed to use initial guesses
% Define the model function as an anonymous function
FunModel = @(para,x)modelFunction(para, x);
% Use lsqcurvefit with the function handle
para_opt = lsqcurvefit(FunModel, para0, x, J_aim);
%-------Fitting Model---------------------
function J_mod = modelFunction(para, x)
global Dim_N
gT = para(1:Dim_N);
kappa = para(Dim_N+1:2*Dim_N);
w = zeros(Dim_N);
%-------Reconstruct the w matrix----------
point = 0;
for index = 2*Dim_N+1: length(para)
point = point + 1;
i = fix( (point-1)/Dim_N ) + 1;
j = point - (i-1)*Dim_N;
w(i,j) = para(index);
end
%-------My fitting model "J_mod"----------
J_mod = zeros(1,length(x));
g = transpose(gT);
Ht = w - 0.5i*diag(kappa);
for i=1:length(x)
temp = Ht - x(i)*eye(Dim_N);
J_mod(i) = imag( gT*(temp\g) ); % Corrected to use matrix left division
end
end
0 Comments
See Also
Categories
Find more on Interpolation in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!