Not enough input arguments

2 views (last 30 days)
Jack
Jack on 11 Jul 2024
Commented: Jack on 11 Jul 2024
Hi all, I am a little perplexed by this warning from matlab: "Not enough input arguments" for my following code. I've looked for documentation to see the problem, but it none of them proved to be helpful to my problem. This warning occured at the line "P = z.p" line 47
tic
%% Preparation
clc; clear
data = importdata("FCPIB-293K-2.5mW-400nm-Jan072021 -ibg -bg -chirp.csv"); % insert file path within parenthesis
load Steady_State_Parameter_Values.mat
z = load("Steady_State_Parameter_Values.mat");
%% Preamble
% Fundamental constants
h = 4.1356677*10^-15; % units: eV/ Hz
c = 3*10^8; % SI units
kB = 8.617333268*10^-5; % units: eV/ K
% Parameters from steady state fitting
A1 = p(1,1);
A2 = p(1,2);
Eg = p(1,3);
Eb = p(1,4);
R = p(1,5);
g = p(1,6);
% Data
Wavelength = data(:, 1);% units: nm
E = (h*c)./(Wavelength*10^-9);
delay_t = data(1, :);
carrier_T = [1198.8, 816.7, 446.8, 328.7];
col1 = 56;
col2 = 63;
col3 = 74;
col4 = 87;
% Data for fitting
Range_E = E >= 1.5 & E <= 2.0;
Range_W = Wavelength >= (h*c)/(2.0*10^-9) & Wavelength <= (h*c)/(1.5*10^-9);
E_p = E(Range_E); % selected probe energies
data_new2 = data(Range_W, [col1,col2,col3,col4]);
delta_Abs1 = data(Range_W,col1);
delta_Abs2 = data(Range_W,col2);
delta_Abs3 = data(Range_W,col3);
delta_Abs4 = data(Range_W,col4);
% Fitting function: Elliott's Model for Transient Absorption
function F = EM_TA_wR1(x, e_p, z)
P = z.p;
kB = 8.617333268*10^-5; % units: eV/ K
A1 = P(1,1);
A2 = P(1,2);
Eg = P(1,3);
Eb = P(1,4);
R = P(1,5);
g = P(1,6);
carrier_T = [1198.8, 816.7, 446.8, 328.7];
for i = numel(e_p)
E_p = e_p(i);
F(i) = x(5)*A1.*((2.*pi.*sqrt(x(2)))./E_p).*1/g.*(integral(@(E)sech(((E_p - E)./g)).*(1 + 10.*R.*(E - x(1)) + ...
126.*(R).^2.*(E - x(1)).^2)./(1 - exp(-2.*pi.*sqrt(x(2)./(E - x(1))))), x(1), Inf, 'ArrayValued', 1)).*(1 - 1./(1 + exp((E_p - x(4))./(kB.*carrier_T(1,1))))).^2 - ...
A1.*(2.*pi.*sqrt(Eb)/E_p).*(1/g).*...
(integral(@(e)sech(((E_p - e)./g)).*(1 + 10.*R.*(e - Eg) + ...
126.*(R).^2.*(e - Eg).^2)./(1 - exp(-2.*pi.*sqrt(Eb./(e - Eg)))), Eg, Inf, 'ArrayValued', 1)) + ...
x(6).*A2.*(4.*pi.*(x(2)).^3/2).*1/x(3).*(...
(1/1^3).*sech((E_p - x(1) + x(2)./1^2)./x(3)) + ...
(1/2^3).*sech((E_p - x(1) + x(2)./2^2)./x(3)) + ...
(1/3^3).*sech((E_p - x(1) + x(2)./3^2)./x(3)) + ...
(1/4^3).*sech((E_p - x(1) + x(2)./4^2)./x(3)) + ...
(1/5^3).*sech((E_p - x(1) + x(2)./5^2)./x(3)) + ...
(1/6^3).*sech((E_p - x(1) + x(2)./6^2)./x(3)) + ...
(1/7^3).*sech((E_p - x(1) + x(2)./7^2)./x(3))) - ...
A2.*(4.*pi.*Eb.^3/2).*1/g.*(...
(1./1.^3).*sech((E_p - Eg + Eb./1.^2)./g) + ...
(1./2.^3).*sech((E_p - Eg + Eb./2.^2)./g) + ...
(1./3.^3).*sech((E_p - Eg + Eb./3.^2)./g) + ...
(1./4.^3).*sech((E_p - Eg + Eb./4.^2)./g) + ...
(1./5.^3).*sech((E_p - Eg + Eb./5.^2)./g) + ...
(1./6.^3).*sech((E_p - Eg + Eb./6.^2)./g) + ...
(1./7.^3).*sech((E_p - Eg + Eb./7.^2)./g));
end
F = F(:);
end
% Solver
lb = [Eg, Eb, g, 0.3, 0.5, 0.2]; ub = [55, 0.05, 0.05, 20, 2, 1];
x0 = [1.65, 0.03, 0.03, 1.3, 1, 0.3];
optim_lsq = optimoptions('lsqcurvefit', 'Algorithm', 'levenberg-marquardt', 'MaxFunctionEvaluations',10^5, 'MaxIterations', 10^5, 'FunctionTolerance',10^-10, 'StepTolerance', 10^-10);
delta_Abs(:, 1) = data_new2(:, 1);
carrierT = carrier_T(1, 1);
x(1, :) = lsqcurvefit(@(x, e_p) EM_TA_wR1, x0, E_p, delta_Abs(:, 1), lb, ub, optim_lsq);
Not enough input arguments.

Error in solution>EM_TA_wR1 (line 47)
P = z.p;

Error in solution>@(x,e_p)EM_TA_wR1 (line 89)
x(1, :) = lsqcurvefit(@(x, e_p) EM_TA_wR1, x0, E_p, delta_Abs(:, 1), lb, ub, optim_lsq);

Error in lsqcurvefit (line 272)
initVals.F = feval(funfcn_x_xdata{3},xCurrent,XDATA,varargin{:});

Caused by:
Failure in initial objective function evaluation. LSQCURVEFIT cannot continue.
plot(E_p, delta_Abs(:, 1), 'o')
hold on
plot(E_p, EM_TA_wR1(x(1, :), E_p, Z), 'LineWidth', 4.0)
hold off
for n = 2:4
delta_Abs(:, n) = data_new2(:,n);
carrierT = carrier_T(1, n);
[x(n, :), residualnorm, residual, exitflag, output, lambda, jacobian] = lsqcurvefit(@(x, E_p) EM_TA_wR(x, E_p, Z), x(n-1, :), E_p, delta_Abs(:, n), lb, ub, optim_lsq);
plot(E_p, delta_Abs(:, n), 'o')
hold on
plot(E_p, EM_TA_wRn(x(n, :), E_p, Z), 'LineWidth', 4.0)
xlabel('Probe Photon Energy (eV)')
ylabel('\Delta A (O.D.)')
legend('0.5 ps', '1.0 ps', '2.0 ps', '4.0 ps', 'Location', 'southeast')
end

Accepted Answer

Stephen23
Stephen23 on 11 Jul 2024
"I am a little perplexed by this warning from matlab: "Not enough input arguments" for my following code"
Lets take a look at how you call the function here:
x(1, :) = lsqcurvefit(@(x, e_p) EM_TA_wR1, x0, E_p, delta_Abs(:, 1), lb, ub, optim_lsq);
% ^ zero inputs here
Although you wrote the function EM_TA_wR1 to require three inputs, when you defined that anonymous function you call it with zero inputs. That clearly will not work, you need to call it with all of its required inputs, probably something like this:
@(x, e_p) EM_TA_wR1(x,e_p,z)
  2 Comments
Stephen23
Stephen23 on 11 Jul 2024
Edited: Stephen23 on 11 Jul 2024
Lets try it with your uploaded data.
Note that I also:
  • replaced the very unfortunate IMPORTDATA with the much more reliable, recommended READMATRIX
  • removed duplicate LOAD calls
  • marked unused variables
Now the anonymous function is correctly defined it does not throw an error when it is called. However you have problems due to the fact that your initial conditions lead to lots of NaNs in the objective function output. You will have to debug those.
data = readmatrix("FCPIB-293K-2.5mW-400nm-Jan072021 -ibg -bg -chirp.csv");
z = load("Steady_State_Parameter_Values.mat");
%% Preamble
% Fundamental constants
h = 4.1356677*10^-15; % units: eV/ Hz
c = 3*10^8; % SI units
kB = 8.617333268*10^-5; % units: eV/ K !!!! this is unused !!!!
% Parameters from steady state fitting
A1 = z.p(1,1); % !!!! this is unused !!!!
A2 = z.p(1,2); % !!!! this is unused !!!!
Eg = z.p(1,3);
Eb = z.p(1,4);
R = z.p(1,5); % !!!! this is unused !!!!
g = z.p(1,6); % !!!! this is unused !!!!
% Data
Wavelength = data(:, 1);% units: nm
E = (h*c)./(Wavelength*10^-9);
delay_t = data(1, :); % !!!! this is unused !!!!
carrier_T = [1198.8, 816.7, 446.8, 328.7];
col1 = 56;
col2 = 63;
col3 = 74;
col4 = 87;
% Data for fitting
Range_E = E >= 1.5 & E <= 2.0;
Range_W = Wavelength >= (h*c)/(2.0*10^-9) & Wavelength <= (h*c)/(1.5*10^-9);
E_p = E(Range_E); % selected probe energies
data_new2 = data(Range_W, [col1,col2,col3,col4]);
delta_Abs1 = data(Range_W,col1); % !!!! this is unused !!!!
delta_Abs2 = data(Range_W,col2); % !!!! this is unused !!!!
delta_Abs3 = data(Range_W,col3); % !!!! this is unused !!!!
delta_Abs4 = data(Range_W,col4); % !!!! this is unused !!!!
% Solver
lb = [Eg, Eb, g, 0.3, 0.5, 0.2];
ub = [55, 0.05, 0.05, 20, 2, 1];
x0 = [1.65, 0.03, 0.03, 1.3, 1, 0.3];
optim_lsq = optimoptions('lsqcurvefit', 'Algorithm', 'levenberg-marquardt', 'MaxFunctionEvaluations',10^5, 'MaxIterations', 10^5, 'FunctionTolerance',10^-10, 'StepTolerance', 10^-10);
delta_Abs(:, 1) = data_new2(:, 1);
carrierT = carrier_T(1, 1);
fnh = @(x, e_p) EM_TA_wR1(x, e_p, z);
% calling the function now works without error...
fnh(x0, E_p) % but do you expect MATLAB to curve-fit NaNs ????
ans = 345x1
NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
% You need to debug why your calculation produces NaNs:
out = lsqcurvefit(fnh, x0, E_p, delta_Abs(:, 1), lb, ub, optim_lsq);
Error using lsqncommon (line 35)
Objective function is returning Inf or NaN values at initial point. lsqcurvefit cannot continue.

Error in lsqcurvefit (line 322)
lsqncommon(funfcn,xCurrent,lb,ub,options,defaultopt,optimgetFlag,caller,...
% Fitting function: Elliott's Model for Transient Absorption
function F = EM_TA_wR1(x, e_p, z)
P = z.p;
kB = 8.617333268*10^-5; % units: eV/ K
A1 = P(1,1);
A2 = P(1,2);
Eg = P(1,3);
Eb = P(1,4);
R = P(1,5);
g = P(1,6);
carrier_T = [1198.8, 816.7, 446.8, 328.7];
F = nan(size(e_p));
for i = numel(e_p)
E_p = e_p(i);
F(i) = x(5)*A1.*((2.*pi.*sqrt(x(2)))./E_p).*1/g.*(integral(@(E)sech(((E_p - E)./g)).*(1 + 10.*R.*(E - x(1)) + ...
126.*(R).^2.*(E - x(1)).^2)./(1 - exp(-2.*pi.*sqrt(x(2)./(E - x(1))))), x(1), Inf, 'ArrayValued', 1)).*(1 - 1./(1 + exp((E_p - x(4))./(kB.*carrier_T(1,1))))).^2 - ...
A1.*(2.*pi.*sqrt(Eb)/E_p).*(1/g).*...
(integral(@(e)sech(((E_p - e)./g)).*(1 + 10.*R.*(e - Eg) + ...
126.*(R).^2.*(e - Eg).^2)./(1 - exp(-2.*pi.*sqrt(Eb./(e - Eg)))), Eg, Inf, 'ArrayValued', 1)) + ...
x(6).*A2.*(4.*pi.*(x(2)).^3/2).*1/x(3).*(...
(1/1^3).*sech((E_p - x(1) + x(2)./1^2)./x(3)) + ...
(1/2^3).*sech((E_p - x(1) + x(2)./2^2)./x(3)) + ...
(1/3^3).*sech((E_p - x(1) + x(2)./3^2)./x(3)) + ...
(1/4^3).*sech((E_p - x(1) + x(2)./4^2)./x(3)) + ...
(1/5^3).*sech((E_p - x(1) + x(2)./5^2)./x(3)) + ...
(1/6^3).*sech((E_p - x(1) + x(2)./6^2)./x(3)) + ...
(1/7^3).*sech((E_p - x(1) + x(2)./7^2)./x(3))) - ...
A2.*(4.*pi.*Eb.^3/2).*1/g.*(...
(1./1.^3).*sech((E_p - Eg + Eb./1.^2)./g) + ...
(1./2.^3).*sech((E_p - Eg + Eb./2.^2)./g) + ...
(1./3.^3).*sech((E_p - Eg + Eb./3.^2)./g) + ...
(1./4.^3).*sech((E_p - Eg + Eb./4.^2)./g) + ...
(1./5.^3).*sech((E_p - Eg + Eb./5.^2)./g) + ...
(1./6.^3).*sech((E_p - Eg + Eb./6.^2)./g) + ...
(1./7.^3).*sech((E_p - Eg + Eb./7.^2)./g));
end
F = F(:);
end
Jack
Jack on 11 Jul 2024
Hi Stephen, I've made the amendments that you've suggested and now my code could run. Thanks so much!

Sign in to comment.

More Answers (0)

Categories

Find more on MATLAB in Help Center and File Exchange

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!