Why am I getting the error "not enough input arguments"?

54 views (last 30 days)
I have this code. Even though I entered all 4 input arguments necessary, I'm still getting the error "not enough input arguments". Any help will be appriciated!
function [Mtrue, H0true] = fit_disL(z, M, H0, dL)
[Mtrue, H0true] = fminsearch(@error_disL, [M, H0])
function E = error_disL(M, H0)
E = 1/length(z)*sum(((disL(z, M, H0)).^2 - dL.^2).^0.5);
end
end
This is the error message:
Not enough input arguments.
Error in fit_disL/error_disL (line 4)
E = 1/length(z)*sum(((disL(z, M, H0)).^2 - dL.^2).^0.5);
Error in fminsearch (line 201)
fv(:,1) = funfcn(x,varargin{:});
Error in fit_disL (line 2)
[Mtrue, H0true] = fminsearch(@error_disL, [M, H0])
  2 Comments
Stephen23
Stephen23 on 17 Jun 2022
Edited: Stephen23 on 17 Jun 2022
"Why am I getting the error "too many input arguments"?"
FMINSEARCH() defines that the objective function "fun is a function that accepts a vector or array x and returns a real scalar f (the objective function evaluated at x).", i.e. its must accept exactly one input argument. No less and no more.
However you wrote ERROR_DISL() to require two input arguments (named M and H0). So when FMINSEARCH() calls your function with exactly one input argument (like the documentation states), then of course an error will be thrown. What do you expect to occur when FMINSEARCH() calls your function with only one input argument?
It appears that you want to pass M and H0 directly from the parent function FIT_DISL(), in which case you should not define them as input arguments to ERROR_DISL() (that just makes things really confusing). However it is totally unclear from your code which variable, if any, you are actually trying to optimize.
Noya Linder
Noya Linder on 17 Jun 2022
Well, are you familier with the concept of curve fitting using the LSQ method? I'm trying to minimize the error, which is represented by the function error_disL(). This means I'm trying to get the values for M and H0 which will result in the smallest error. Anyway, I solved the problem thanks to some nicer comments that explained it. Thanks anyway :)

Sign in to comment.

Accepted Answer

Voss
Voss on 17 Jun 2022
The error message is actually saying there aren't enough inputs to the function error_disL (not fit_disL). That happens because error_disL is defined to take 2 inputs, M and H0, but fminsearch is giving it 1 input, which is effectively the vector [M H0].
To fix this, you can redefine error_disL to take 1 input, a vector containing both M and H0 like fminsearch will give it:
function [Mtrue, H0true] = fit_disL(z, M, H0, dL)
[Mtrue, H0true] = fminsearch(@error_disL, [M, H0])
function E = error_disL(MH0)
M = MH0(1);
H0 = MH0(2);
E = 1/length(z)*sum(((disL(z, M, H0)).^2 - dL.^2).^0.5);
end
end

More Answers (1)

Jan
Jan on 17 Jun 2022
Edited: Jan on 17 Jun 2022
The function handle provided to fminsearch must accept 1 input argument. fminsearch cannot guess, that H0 should be provided also.
You have defined error_disL as a nested function. Then it shares the value of H0 with the enclosing function. So this should work:
function [Mtrue, H0true] = fit_disL(z, M, H0, dL)
[Mtrue, H0true] = fminsearch(@error_disL, [M, H0])
function E = error_disL(x)
M = x(1);
H0 = x(2);
E = 1 / length(z) * sum(sqrt(disL(z, M, H0).^2 - dL.^2));
end
end
Alternatively:
function [Mtrue, H0true] = fit_disL(z, M, H0, dL)
fcn = @(x) error_disL(x, z, dL);
[Mtrue, H0true] = fminsearch(fcn, [M, H0]);
end
function E = error_disL(x, z, dL)
M = x(1);
H0 = x(2);
E = 1 / length(z) * sum(sqrt(disL(z, M, H0).^2 - dL.^2));
end
I've replaced the expensive ^0.5 by the cheaper sqrt().

Community Treasure Hunt

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

Start Hunting!