Lsqnonlin to determine coefficient

조회 수: 4 (최근 30일)
Anand Ra
Anand Ra 2021년 6월 7일
답변: Nipun 2024년 5월 16일
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
Star Strider
Star Strider 2021년 6월 7일
Should I use lscurvefit for my problem?
I would. It’s simply easier.
Matt J
Matt J 2021년 6월 7일
편집: Matt J 2021년 6월 7일
@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.

댓글을 달려면 로그인하십시오.

답변 (1개)

Nipun
Nipun 2024년 5월 16일
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

카테고리

Help CenterFile Exchange에서 Solver Outputs and Iterative Display에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by