MATLAB: Not enough input arguments

not enough input arguments

I'm new to Matlab and I can't for the love of god figure out why there's error.
What's wrong with
y1 = f(1/2,w1,w2);
How isn't there enough input??? There are precisely 3 inputs!!! I've spent 2 hours on this already… Please help!!!!
function main
x = [1;1;1;1;1;1;1];
broyden(x,@F,7,0.001);
end
function y = f(a,b,c)
y = -a + 2 * b - c + (1/8)^2 * 2 * b^3;
end
function y = F(w1,w2,w3,w4,w5,w6,w7)
y1 = f(1/2,w1,w2);
y2 = f(w1,w2,w3);
y3 = f(w2,w3,w4);
y4 = f(w3,w4,w5);
y5 = f(w4,w5,w6);
y6 = f(w5,w6,w7);
y7 = f(w6,w7,1/3);
y = [y1;y2;y3;y4;y5;y6;y7];
end
function [xv,it] = broyden(x,f,n,tol)
it = 0;
xv = x;
Br = eye(n);
fr = feval(f, xv);
while norm(fr) > tol
it = it + 1;
pr = -Br * fr;
tau = 1;
xv1 = xv + tau * pr;
xv = xv1;
oldfr = fr;
fr = feval(f,xv);
y = fr-oldfr;
oldBr = Br;
oyp = oldBr * y - pr;
pB = pr' * oldBr;
for i = 1:n
for j = 1:n
M(i,j) = oyp(i) * pB(j);
end
end
Br = oldBr - M ./ (pr' * oldBr *y);
end
end
The error I get is
Not enough input arguments.
Error in main>F (line 11)
y1 = f(1/2,w1,w2);
Error in main>broyden (line 25)
fr = feval(f, xv);
Error in main (line 3)
broyden(x,@F,7,0.001);

Best Answer

Your main function calls broyden with a seven element vector as its first input and a handle to the F function as its second input.
broyden(x,@F,7,0.001);
The broyden function calls feval to evaluate the F function with one input, the seven element vector. The f on this line does NOT refer to your f function but to the function handle stored in the variable named f.
fr = feval(f, xv);
You may have expected that MATLAB would automatically expand that vector to pass each element into F as a separate input w1 through w7.
function y = F(w1,w2,w3,w4,w5,w6,w7)
It doesn't. In this call w1 is a seven element vector and w2 through w7 do not exist. [You can add a call to the whos function as the first line inside your F function to check this; that whos output will show only w1 in the workspace.] Thus when you try to use w2 on this line inside F:
y1 = f(1/2,w1,w2);
MATLAB realizes you called F with not enough input arguments and so throws an error.
You could modify F so it accepts one input argument and refers to elements of that input argument. The first two lines would then be the following.
function y = F(w)
y1 = f(1/2,w(1),w(2));
end
Actually, I'd recommend preallocating y and filling it in as you go. Then you don't need to assemble the pieces together at the end.
function y = F(w)
y = zeros(7, 1);
y(1) = f(1/2,w(1),w(2));
end
Alternately you could modify your broyden function to pass each element of the vector into F individually. But I'd prefer the former, as among other things it's less typing.
fr = feval(f, xv(1), xv(2), xv(3), xv(4), xv(5), xv(6), xv(7));