Lsqnonlin to determine coefficient

3 visualizaciones (últimos 30 días)
Anand Ra
Anand Ra el 7 de Jun. de 2021
Respondida: Nipun el 16 de Mayo de 2024
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 comentarios
Star Strider
Star Strider el 7 de Jun. de 2021
Should I use lscurvefit for my problem?
I would. It’s simply easier.
Matt J
Matt J el 7 de Jun. de 2021
Editada: Matt J el 7 de Jun. de 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.

Iniciar sesión para comentar.

Respuestas (1)

Nipun
Nipun el 16 de Mayo de 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

Categorías

Más información sobre Solver Outputs and Iterative Display en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by