# MatLab function question

Hi pf

I have a question that I have not been able to find. The below function accepts outside scalar inputs but not vectors. The code is below.

Also, ## a, b, delta,FA,Hi,vHnew,iv## are all scalars defined outside the function. The vector I would like to add as an input is ##x##, which I've commented below what it could be. However, even if I add this to the function line and ##fa, fb##, and ##fc##, along with the ##fx## function at the end, I still receive "Error Not enough input arguments." Please help me so this function can operate on ##x## when it is defined outside the function.

Any help is greatly appreciated!

Code:
function c = mshvol(a, b, delta,FA,Hi,vHnew,iv)
fa = f(a,FA,Hi,vHnew,iv);
fb = f(b,FA,Hi,vHnew,iv);
while ( abs(b - a) > 2*delta )
c = (b + a)/2;
fc = f(c,FA,Hi,vHnew,iv);
if sign(fc) ~= sign(fb)
a = c; fa = fc;
else
b = c; fb = fc;
end% end if
end

function fx = f(zbulk,FA,Hi,vHnew,iv)
dx=.001;
% x=0:dx:5;
y=25-x.^2;
diff = abs(x-zbulk);
[~, idx] = min(diff); %index of closest value
z=y(idx:end);
fx = zbulk*15+trapz(z)*dx-70; %% Volume balance
return;

kreil
Gold Member
Using these test values for the variables:
Code:
delta = 1;
FA = 1;
Hi = 1;
vHnew = 1;
iv = 1;
x = 1:10;
a = 10;
b = 5;

This code ran for me:

Code:
function c = mshvol(a, b, delta, FA, Hi, vHnew, iv, x)
fa = f(a, FA, Hi, vHnew, iv, x);
fb = f(b, FA, Hi, vHnew, iv, x);
while ( abs(b - a) > 2*delta )
c = (b + a)/2;
fc = f(c, FA, Hi, vHnew, iv, x);
if sign(fc) ~= sign(fb)
a = c; fa = fc;
else
b = c; fb = fc;
end% end if
end

function fx = f(zbulk, FA, Hi, vHnew, iv, x)
dx=.001;
% x=0:dx:5;
y=25-x.^2;
diff = abs(x-zbulk);
[~, idx] = min(diff); %index of closest value
z=y(idx:end);
fx = zbulk*15+trapz(z)*dx-70; %% Volume balance
return;

Code:
c = mshvol(a, b, delta, FA, Hi, vHnew, iv, x)

c =

8.7500

I added x in all the places you did, though, so I'm wondering why this doesn't run for you?

Can you copy/paste the entire error message you are seeing? It should be giving a line number where the error occurs that will be helpful.

That's weird that it's not working for me. The error I get is: Error using mshvol (line 35) Not enough input arguments. I have a lot of comments in my code, so my line 35 corresponds to line 2 from the code you posted, the one that works for you.

I defined ##x## from the command window, which seems like you did too, right?

Thanks a ton for helping!

kreil
Gold Member
Yes I defined x at the command line, along with the other variables in the first code block, before calling the function.

Can you just copy and paste your entire code verbatim so I can try to reproduce the error you're getting?

Definitely. It's below. In the command window I defined the following too:

dx=.01;
x=0:dx:5;
a=0;
b=5;
delta=.00001;
FA=1;
Hi=1;
vHnew=1;
iv=1;

Code:
function c = mshvol(a, b, delta,FA,Hi,vHnew,iv,x)
% Remember that the function statement must be at the top of
%
%
% mshvol.m
%
% Implements the bisection method
%
% Input:     a     the left endpoint of the interval
%         b     the right endpoint of the interval
%         delta    the tolerance/accuracy we desire
%
% Output:    c     the approxmiation to the root of f
%
% Syntax:    bisect(a, b, delta)
%
% Notes:
%        1. The code defining f comes after the code defining
%            bisect, since bisect depends on f.
%        2. By default, MATLAB only displays 5 digits.  You can
%            change this by issuing the command "format long".
%            See "help format" for more details.
%% Initial Guess and Tolerance
clear zbulk;        %this is so zbulk is treated as a variable in the function
fa = f(a,FA,Hi,vHnew,iv,x);%% compute initial values of f(a) and f(b)
fb = f(b,FA,Hi,vHnew,iv,x);

% if  sign(fa) == sign(fb)    %% sanity check: f(a) and f(b) must have different
%                 %% signs
%                 %% the error function prints an error message and
%                 %% exits
%     error('f must have different signs at the endpoints a and b.  Aborting.')
% end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%                                                                       %%
%% main routine                                                          %%
%%                                                                       %%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

while ( abs(b - a) > 2*delta )    %% While the size of the interval is
%% larger than the tolerance

c = (b + a)/2;        %% Set c to be the midpoint of the interval

fc = f(c,FA,Hi,vHnew,iv,x);        %% Calculate the value of f at c

if sign(fc) ~= sign(fb)    %% If f(c) and f(b) are of different sign, then
%% f must have a zero between c and b (by the
%% Intermediate Value Theorem).
a = c;     fa = fc;
else             %% This is the case where f(a) and f(c) are of
%% different sign
b = c;    fb = fc;
end
end
function fx = f(zbulk,FA,Hi,vHnew,iv,x)
y=25-x.^2;
diff = abs(x-zbulk);
[~, idx] = min(diff); %index of closest value
z=y(idx:end);
fx = zbulk*15+trapz(z)*dx-70;  %% Volume balance
return;

kreil
Gold Member
I don't get the error you mentioned. The only thing immediately wrong with the code you posted is that you define dx in the command window, but dx is used again in the nested function for f, so I got this error:

Code:
c = mshvol(a, b, delta, FA, Hi, vHnew, iv, x)
Undefined function or variable 'dx'.

Error in mshvol>f (line 62)
fx = zbulk*15+trapz(z)*dx-70;  %% Volume balance

Error in mshvol (line 26)
fa = f(a,FA,Hi,vHnew,iv,x);%% compute initial values of f(a) and
f(b)

So I added dx=0.01 to that nested function, and then the code ran:

Code:
c = mshvol(a, b, delta, FA, Hi, vHnew, iv, x)

c =

4.6198

Some general observations:

1. The value assigned to fa is unused in this code.
2. The function f is defined to accept 6 input arguments. But it does not use the values of FA, Hi, vHnew, or iv in any computations, so it really just needs zbulk and x. These variables aren't used anywhere else, either: so I'm wondering why mshvol needs 8 inputs instead of 4?
3. diff is the name of a MATLAB function, so when you assign a value to a variable named diff in the nested function f, you override that functionality.

Do you have multiple files named mshvol on the MATLAB path? Line 35 in the code you sent is in a comment, so I don't see how that error could be attributed to the code you sent. I suspect it is running a different file with the same name.

• joshmccraney
I'm sorry, I actually am getting the following error (line 35 was when the variables were defined in the code):

Error using mshvol (line 26)
Not enough input arguments.

I'm defining all variables outside the function in the command window. For some reason this code works fine for scalars but then ##x## throws the entire thing off. As for the unused variables, I was planning on adding them in after I get the above code to work.

But any idea why this error NOT ENOUGH INPUT ARGUMENTS is showing up?

Thanks so much, you're very helpful!

It's working now! The issue was I was simply pressing "run" when i should have instead typed from the script of command window mshvol(a, b, delta,FA,Hi,vHnew,iv,x).

Thanks so much for your concern!

kreil
Gold Member
Ahhh ok that makes sense!

The run button is best reserved for simple scripts that are self contained. Since functions require inputs, you need to use the command window to explicitly specify those inputs.

I'm glad you figured it out.

Cheers,
Josh

• joshmccraney
Thanks kreil!