Definition of a function |
function [out1,out2,..]=functionname(in1,in2,..)
statements
end
or
function (out1,out2,..)=functionname(in1,in2, ..)
statements
end
Here in1, in2,
etc. are the input arguments and
out1,out2, etc. are
the output arguments. There is no explicit
limit on the number of input arguments or output arguments. The statements obviously use the values of the inputs to compute the
outputs.
If a function does not need any inputs or outputs, the corresponding clauses of the the leading line of the function may be omitted. Thus, for example
function myfunction(x,y) disp(x,y) endjust displays the inputs, and the function
function [y,z]=readinput
y=input('what is y')
z=input('what is z')
end
prompts the user to input the values of the outputs.
It is also possible to define the so-called inline functions. The definitiona=@(in1,in2,...)(expression)
is equivalent, in the more elaborate form above, to
function (y)=a(in1,in2,...) y=expression endThe inline form is convenient for defining simple functions, especially for calling functions that require a function as an argument.
>>x=fzero(@(x)sin(x)*x-1,rand(1,1))
>>x
1.1142
>>sin(x)*x
1.0000
Importing methods of Java objects as functions |
The function importStatic may be called to import all static methods of a class which have public access. The methods are imported into the current context as functions of the same names.
>>// import the static methods of the class java.lang.Integer
>>importStatic(Integer.class)
>>// Equivalent to java.lang.Integer.reverseBytes(10)
>>a=reverseBytes(10)
>>a
167772160
>>reverseBytes(a)
10
>>// Equivalent to java.lang.Integer.parseInt("23")
>>parseInt("23")
23
>>// Equivalent to java.lang.Integer.parseInt("23",4)
>>parseInt("23",4)
11
The construct func=@aclass.methodname imports the named static
method with public access of the specified class as the function func in the current
context.
>>func=@Double.class.parseDouble
>>// Equivalent to Double.parseDouble("2.34e3")
>>func("2.34e3")
2340
The construct objectMethod=@object.methodname
imports the named
method (with public access ) of the class of the specified object as the function objectMethod in the current
context. Obviously, when called, the method is evaluated in the context
of the object that was used to import the function (i.e. object in the example).
>>a=new Vector();
>>addToVector=@a.add
>>addToVector(10)
>>a
[10]
>>addToVector("Element 2")
>>a
[10, Element 2]
>>b=new Hashtable();
>>putInHash=@b.put
>>putInHash("First","Element 1")
null
>>putInHash("Second",2)
null
>>b
{Second=2, First=Element 1}
Calling a function |
[argout1,argout2,..]=functionname(argin1,argin2, ..)
or
(argout1,argout2,..)=functionname(argin1,argin2, ..)
The inputs to a function are passed by value. What this means is that if you have defined a function which modifies an input in any way, when the function is called the modification is not made to the variable used as the input argument. The following trivial example illustrates this:
>>function [y]=myfunction(x) > x=x+10 > y=x >end >>u=20; >>[v]=myfunction(u) >>v 30 >>u 20Thus, even though the function modifies the value of the input, the value of the input argument in the call,i.e.,
u, is retained even after the call.
The outputs to a function are passed by reference. For example:
>>function [y]=defaulty(x) > if(y==null);y=x;end >end >>u=20; >>[u]=defaulty(10) >>u 20 >>u=null; >>[u]=defaulty(10) >>u 10Thus, the initial value of an output argument during the execution of a function is its value in the context of the caller immediately prior to the call, and any modifications in the value during the execution of the function are are retained when the function terminates.
Fixing the number of input arguments |
All the inputs and outputs to a function as defined above are optional. Thus the number of inputs in the call to a function may be less than the number of inputs in the function definition. If such is the case, all the remaining inputs are undefined on entry to the function.
The number of input arguments used in
the call to a function are available as
the value of the variable nargin
and, likewise, nargout is set to the number of outputs.
>>function [u,v]=func(x,y,z)
>nargin,nargout,NL
>end
>>[u]=func()
0 1
>>[u, v]= func(2,3)
2 2
>>[u] = func(2,3,4)
3 1
>>[u] = func(2,3,4,5)
Error The function func needs at most 3 input arguments but given 4
Thus typically it is necessary to check if the caller has specified
the necessary number of input arguments. To avoid having to do this explicitly,
the input arguments can be divided into two parts: the required input arguments
and the optional inputs, and the two can be separated by a vertical bar in
the function definition.
>>function func1(x, y | u)
> nargin,NL
>end
>>func1(2,3)
2
>>func1(2,3,4)
3
>>func1(2)
Error The function func1 needs at least 2 input arguments but only 1 is specified
The return statement. |
The return
statement may be used to terminate the execution of
the statements in a function, and return the thread of execution to the
caller's context. The return expression statement also
has the same effect, except that it additionally sets the value of the
first output of the function to expression.
>>function [y]=defaulty(x) > if(y==null);y=x;end >end >>// Same as defaulty above, but uses return expression. >>function [y]=defaulty1(x) > if(y==null);return x;end >end >>// Same as defaulty above, but uses both return expression >>// and return >>function [y]=defaulty2(x) > if(y!=null);return;end > return x; >end
Functions are like any other data type. |
@ or $ to suppress the
interpretation of the name as a function call with no inputs.
>>// This function returns a function.
>>function func(fname)
>if(fname=="sin")
> return $sin
>else if(fname=="cos")
> return @cos
>else if(fname=="tan")
> return $tan
>else
> error("Invalid function name")
>end
>end
>>func("sin")(pi/3)
0.866
>>func("cos")(pi/3)
0.5
>>func("tan")(pi/3)
1.7321
>>// This function assumes the first input to be a function.
>>function myfeval(func,x)
> return func(x)
>end
>>myfeval($sin,pi/3)
0.866
>>myfeval($cos,pi/3)
0.5
>>myfeval($tan,pi/3)
1.7321
>>myfeval(@tan,pi/4)
1
Creating function objects. |
myfuc and use @myfunc as the requisite argument.
>>function myfunc(x)
>return x*sin(x)-1;
>end
>>fzero(@myfunc,rand(1,1))
1.1142
>>fzero(@(x)sin(x)*x-1,rand(1,1))
1.1142
>>// Solves sin(x)=0
>>fzero(@Math.sin,rand(1,1))
-1.7756e-007
>>showfile('utilclasses\\Example.java')
public class Example
{
private double p;
public Example(double p)
{
this.p=p;
}
public double exampleFunction(double x)
{
return Math.sin(x)*x-p;
}
}
>>addClassPath('utilclasses')
>>a=new Example(1)
>>// Use the '@object.method' syntax to construct a function object.
>>fzero(@a.exampleFunction,rand(1,1))
1.1142
>>x=fzero(@a.exampleFunction,rand(1,1))
>>a.exampleFunction(x)
-8.6211e-012
sin(x)*x-p=0 for various values
of the parameter p.
>>class A
> var p
> function A(p);this.p=p;end
> function ()(x);return Main.sin(x)*x-p;end
>end
>>fzero(new A(1),rand(1,1))
1.1142
>>x=fzero(new A(2),rand(1,1))
>>x
-6.5915
>>(new A(2))(x)
1.5991e-007
>>function createFunction(p)
> return @func
> function func(x)
> return x*sin(x)-p
> end
>end
>>fzero(createFunction(1),rand(1,1))
1.1142
>>fzero(createFunction(2),rand(1,1))
-6.5915
Function definition in m-files |
If a function myfunction is defined in a file called
myfunction.m (as is the recommended practice)
and the directory of this file is added to the search path of the interpreter
by calling addpath, the function
is automatically included in the current global context, and the call to the function, even
if it is not defined at the time,
will result in the execution of the file myfunction.m to load the function.
Subfunctions and nested functions |
An m-file may contain more than one function definition. However, only the first function in the file is available in the global context. All the other functions are subfunctions, available only in the context of the functions defined in the file.
A function may be defined within another function. A nested function is available only within the context of the function in which it is defined. Note that arbitrary levels of nesting are not allowed: a nested function may not be defined within another nested function.
>>showfile("func1.m")
function func1(x) # This function is visible golobally.
return func2(x)
end
function func2(x) # This is a subfunction, visible only to func1 and func2.
return @func3
function func3() # This is a nested function, visible only to func2.
return x+10;
end
end
>>a=func1(10)
>>a(2)
12
>>// Note that func2 (a subfunction) and func3 (a nested function) are undefined
>>// in the global context.
>>func2
null
>>func3
null
static/persistent and global variables in functions |
Normally, any variables defined within a function are not visible outside the function. However, this behavior can be overridden by declaring a variable to be global.
>>function func(x) > global u > u=x+10 >end >>function func1() > global u > return u+2 >end >>func(10) >>func1() 22 >>u 20
It is not a good programming practice to use too many global variables, and so they should be used sparingly and with care.
A variable can be declared to be static or, equivalently, persistent, to retain its value during successive calls.
>>function currentDate()
>import java.text.*
>// The dateformatter object is created only the first time
>// the function is called, and it retains its value for successive
>// calls.
> static dateformatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
> return dateformatter.format(Calendar.getInstance().getTime())
>end
>>currentDate()
2008-03-29 20:36:38
>>currentDate()
2008-03-29 20:36:40