Lsqnonlin to determine coefficient
3 views (last 30 days)
Show older comments
I am looking to fit data to a complex equation using lsqnonlin solver. I am not sure where I am going wrong. I keep getting a response "not enough input arguments"
% Approach
% 1. Creating the following function named fit_simp.m which uses the time and Ar data(Ar = At/Ainf).
% 2. time and Ar are passed into lsqnonlin as input arguments.
% 3. Use the time and n data to calculate values values (Ar) the diffusion equation, and subtract the original Ar data from this.
% 4. The result will be the difference between the experimental data and the calculated values.
% 5. The lsqnonlin function will minimize the sum of the squares of the differences.
% 6. Condensation of the diffusion equation:
% a=0.0008;
% n1 = 2.43;
% n2= 1.4;
% Lambda = 950;
% theta = 45;
% gama = (2*n1*pi*sqrt ((sin(theta))^2-(n2/n1)^2))/(Lambda)
% Above entered in: 1-(8*gama/pi*(1-exp(-2*gama*a)))*((exp(-D*(2*n+1)^2*pi^2*t/4*a^2))*((-1)^n*2*gama +(((2*n+1)*pi)/(2*a))*exp(-2*gama*a))/((2*n+1)*((4*gama^2)+((2*n+1)*pi/2*a)^2)));
function diff = fit_simp(x,~,~) % This function is called by lsqnonlin.
% x is a vector which contains the coefficient of the equation.
% time and Ar are the option data sets that are passed to lsqnonlin
% Defining the data sets that you are trying to fit the function to.
Ar = [0.3 0.2 0.28 0.318 0.421 0.492 0.572 0.55 0.63 0.61 0.73 0.8 0.81 0.84 0.93 0.91]';
l = length(Ar);
t = [0:l-1]';
plot(t,Ar,'ro')
title('Data points')
% D is the coefficient we are looking to determine
%*******************************************************************************
a=0.0008;
n1 = 2.43;
n2=1.4;
Lambda = 950;
theta = 45;
d= x(1);
gama = (2*n1*3.14*sqrt ((sin(theta))^2-(n2/n1)^2))/(Lambda);
time=12;
for t = 1:time
for n=0:time
r = 1-((8*gama/pi)*(1-exp(-2*gama*a)))*((exp(-d.*(2*n+1)^2*pi^2*t/4*a^2))*((-1)^n*2*gama +(((2*n+1)*pi)/(2*a))*exp(-2*gama*a))/((2*n+1)*((4*gama^2)+((2*n+1)*pi/2*a)^2)));
end
result(t) = r;
end
%*******************************
diff = result - Ar;
% Initialize the coefficients of the function.
X0=[1];
% Calculate the new coefficients using LSQNONLIN.
x=lsqnonlin(@fit_simp,X0,t,Ar);
% Plot the original and experimental data.
for t = 1:time
for n=0:time
Ar_new = 1-(8*gama/pi*(1-exp(-2*gama*a)))*((exp(-x(1).*(2*n+1)^2*pi^2*t/4*a^2))*((-1)^n*2*gama +(((2*n+1)*pi)/(2*a))*exp(-2*gama*a))/((2*n+1)*((4*gama^2)+((2*n+1)*pi/2*a)^2)))
end
Ar_newv(t)=Ar_new;
end
plot(time,Ar,'+r',time,Ar_newv,'b')
4 Comments
Matt J
on 7 Jun 2021
Edited: Matt J
on 7 Jun 2021
@Anand Rathnam Note that your loop
for n=0:time
r = 1-((8*gama/pi)*...
end
is not doing anything except repeatedly over-writing r. It is not updating r in any way. You have a similar loop later in your posted code with the same problem.
Answers (1)
Nipun
on 16 May 2024
Hi Anand,
I understand that you are trying to fit data to a complex equation using MATLAB's lsqnonlin solver and encountering an issue with "not enough input arguments". The primary issue seems to stem from how you've structured the fit_simp function and how it's called within the script. Let's address these concerns step by step.
First, ensure your fit_simp.m function is defined to accept x, t, and Ar correctly. You will likely need to use an anonymous function to pass t and Ar to fit_simp when calling lsqnonlin.
function diff = fit_simp(x, t, Ar)
% Your existing logic to calculate `diff` using `x`, `t`, and `Ar`
end
Then, when calling lsqnonlin, use an anonymous function to pass t and Ar:
% Your data initialization
Ar = [0.3 0.2 0.28 0.318 0.421 0.492 0.572 0.55 0.63 0.61 0.73 0.8 0.81 0.84 0.93 0.91]';
t = (0:length(Ar)-1)'; % Assuming this is your time vector
% Initial guess for the parameters to be optimized
X0 = [1]; % Example initial guess
% Define the anonymous function for lsqnonlin
fun = @(x) fit_simp(x, t, Ar);
% Call lsqnonlin
options = optimoptions('lsqnonlin','Display','iter'); % Optional: to display iterations
[x,resnorm,residual,exitflag,output] = lsqnonlin(fun,X0,[],[],options);
% After finding the optimal parameters, you can plot or further analyze the results
Make sure your fit_simp function only contains the logic to calculate the difference between the model and the data (diff = result - Ar;) and does not include calls to lsqnonlin or plotting commands. Those should be outside and after the optimization call, respectively.
This approach should resolve the "not enough input arguments" error by correctly structuring the function call and ensuring all necessary data is passed as arguments.
Hope this helps.
Regards,
Nipun
0 Comments
See Also
Categories
Find more on Least Squares 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!