Advanced Functions Chapter 10 Attaway MATLAB 4E
Variable # of Arguments So far in the functions that we � ve written, there has been a fixed number of input arguments and a fixed number of output arguments It is possible to have a variable number of arguments , both input arguments and output arguments A built-in cell array varargin can be used to store a variable number of input arguments a built-in cell array varargout can be used to store a variable number of output arguments These are cell arrays because the arguments could be different types, and cell arrays can store different kinds of values in the different elements.
Variable # of input arguments The cell array varargin stores a variable number of input arguments This could be used to store all of the input arguments to the function, or only some of them The function nargin returns the total number of input arguments that were passed to the function (not just the length of varargin ) Since varargin is a cell array, use curly braces to refer to the elements, which are the input arguments
Variable input function headers Two kinds of function headers All input arguments stored in varargin : function outarg = fnname(varargin) varargin stores some of the input arguments but not all: function outarg = fnname(input args, varargin)
Function header example For example, if coordinates of a point are being passed to a function, and we know x and y will always be passed, and z might, there are two possibilities: function outarg = fnname(varargin) In this case, x is stored in varargin{1}, y is stored in {2}, and if z is passed, it is in varargin{3} function outarg = fnname(x,y,varargin) In this case, x and y are stored in input arguments x and y, and if z is passed, it is in varargin{3} Note: in both cases, nargin will be 3
Variable # of output arguments The cell array varargout stores a variable number of output arguments As with input arguments, some output arguments can be built in if they are always going to be returned, or varargout can store all output arguments – so there are two kinds of function headers: function varargout = fnname(input args) function [output args, varargout] = fnname(input args) Since varargout is a cell array, use curly braces to refer to the elements, which are the output arguments To call this function: [variables] = fnname(input args);
Function nargout The function nargout returns the number of output arguments expected from the function (e.g., the number of variables in the vector in the left-hand side of the assignment statement when calling the function) For example, if the left side of the assignment statement in which the function is called is: [x, y, z] = fnname(… the value of nargout would be 3
Nested Functions A nested functions is when an outer function has within it inner function(s) When functions are nested, every function must have an end statement (much like loops) The general format of a nested function is as follows: outer function header body of outer function inner function header body of inner function end % inner function more body of outer function end % outer function The inner function can be in any part of the body of the outer function so there may be parts of the body of the outer function before and after the inner function
Anonymous Functions Anonymous functions are really, really simple, short functions that fit on one line General form: fnhanvar = @ (input arguments) functionbody The input arguments and function body are similar to other functions, except that the body is just one expression the @ returns the handle of the function, which is a way of referring to the function the variable on the left of the assignment stores the function handle
Calling Anonymous Functions Calling the function is accomplished by using the function handle, and passing arguments: fnhanvar(input arguments) An advantage of anonymous functions is that you don � t have to store them in code files However, it is useful to store groups of related anonymous functions in MAT-files (e .g. a set of functions to do temperature conversions)
Anonymous Function Example Here is an example of an anonymous function that calculates the area of a circle: >> cirarea = @ (radius) pi * radius .^ 2; Examples of calling it: >> cirarea(4) ans = 50.2655 >> areas = cirarea(1:4) areas = 3.1416 12.5664 28.2743 50.2655
No input arguments If there aren � t any input arguments, you still have to have empty () in the function definition and the function call >> prtran = @ () fprintf('%.2f\n',rand); >> prtran() 0.95 >> prtran prtran = @ () fprintf('%.2f\n',rand)
Function Handles Function handles can be created for all functions, not just anonymous functions fnhanvar = @fnname where fnname can be the name of a built-in or user- defined function This can then be used to call the function: fnhanvar(input arguments) instead of fnname(input arguments) So, why do we need that?
Function Functions Function handles make it possible to pass functions to other functions to use – instead of passing the name of a function, you pass its handle A function that receives a function handle as an argument is called a function function The function handle that is passed can be of a built-in function, anonymous function, or user- defined function
Function Function Example For example, the following function function receives as input arguments a vector x and a function handle fnhan >> type fnfn function out = fnfn(x,fnhan) out = fnhan(x); end Examples of calling this function will be shown on the next slides
Calling the Function Function First, create function handles >> type myfn % Here is a user-defined function function outy = myfn(x) outy = x .^ 3 - 4 * x + 5; end >> fnha = @myfn; % Function handle for a user-defined function >> fnhb = @(x) x .^ 2 - 3; % Function handle for an anonymous function >> fnhc = @cos; % Function handle for a built-in function Next, call the function by passing a vector and function handle: >> x = 3:.5:6; >> y = fnfn(x, fnha) y = 20.0000 33.8750 53.0000 78.1250 110.0000 149.3750 197.0000
Calling Function Function (cont) >> y = fnfn(x, fnhb) y = 6.0000 9.2500 13.0000 17.2500 22.0000 27.2500 33.0000 >> fnfn(x,fnhc) ans = -0.9900 -0.9365 -0.6536 -0.2108 0.2837 0.7087 0.9602 >> fnfn(x,@sum) ans = 31.5000
Related Functions The function str2func receives a string which is a function name, and returns a function handle to that function The function func2str converts a function handle to a string built-in function function fplot receives a function handle and a range and plots in that range (no need for x/y vectors) built-in function function feval receives a function handle and an argument and returns the execution of the function on that argument
Function timeit Function timeit can be used to time functions; it is more robust than tic / toc One argument is passed which is the handle of the function to be timed It returns the time in seconds
Recursive functions Recursion is when something is defined in terms of itself Recursive functions are functions that call themselves There has to be a way to stop this, otherwise, infinite recursion will occur Sometimes either iteration or recursion can be used to implement a solution to a problem
Factorial Example An iterative definition for the factorial of an integer n is: n! = 1 * 2 * 3 * ... * n A recursive definition is: n! = n * (n - 1)! general case 1! = 1 base case With a recursive definition, there is always a general case which is recursive, but also a base case that stops the recursion
Code for recursive factorial A function that implements the recursive definition has an if-else statement to choose between the general and base cases: function facn = fact(n) % fact recursively finds n! % Format: fact(n) if n == 1 facn = 1; else facn = n * fact(n-1); end end
Common Pitfalls Trying to pass just the name of a function to a function function; instead, the function handle must be passed Thinking that nargin is the number of elements in varargin (it may be, but not necessarily; nargin is the total number of input arguments) Forgetting the base case for a recursive function
Programming Style Guidelines Use anonymous functions whenever the function body consists of just a simple expression. Store related anonymous functions together in one MAT-file If some inputs and/or outputs will always be passed to/from a function, use standard input arguments/output arguments for them. Use varargin and varargout only when it is not known ahead of time whether other input/output arguments will be needed. Use iteration instead of recursion when possible.
Recommend
More recommend