0. Introduction : parameters vs arguments f(x) = x**2 is a Calculus function x is the parameter f(10) 10 is the (input) argument x is the variable/indeterminate used to describe the function and in computing we call it the parameter of f 10 is a value assigned to x and we call 10 the (input) argument to function f if in MATLAB we have >> y=10; >> f(y); then y is still the argument 1. Anonymous functions in MATLAB >> f = @ (x) (x^2) creates an ANONYMOUS function in MATLAB The result is f = @(x) (x^2) f is the handle , x is the parameter. We can have more than one params separated with commas >> g= @(x,y) (x^2 + y^2) Why the name ANONYMOUS ? To distinguish this definition from an EPONYMOUS function that in MATLAB is called a primary function (or by dropping the primary, simply a function). >> f(10) ans =100 >> g(10,20) ans = 500 >> z=10;w=20; >> f(w) ans = 400 >> a=g(w,z) a= 500 WHO CALLS A FUNCTION ? WHAT DOES THE FUNCTION RETURN ? - The caller of function f,g is the command window ! - Function invocation f(10) returns a values. Thus f(10) is being replaced by a value 100 that becomes the value of ans - In the last line a=g(w,z) the value returned by g(w,z) is assigned to variable a, which is also known as the output argument. 2. (Primary) functions in MATLAB [ Code f.m] i. A primary function is defined in a file whose name is the function name plus the .m ii. Thus function f is defined in file f.m iii. The M-file for f.m look like ******** PRIMARY FUNCTION : Syntax ************* >> type f.m % Hi.. This is my function f function y=f(x) y=x*x; return end A : The first few lines starting with % contain comments. Comments are important because they provide information about the file. When one types >> help f then all the comments prior to the line containing function will be printed as follows (no comment symbol is printed). >> help f Hi.. This is my function f >> B : function keyword : Indicates that a function is to be defined. This M-file does not contain abritrary MATLAB statements but the DEFINITION of a function C : end : Function end with keyword end. This keyword is mostly optional, unless a nested function is defined (to be explained). In such case all function in the .m file must use end for a function terminal symbol whether it is the primary function of the file (the one whose name is the file name followed by .m) or a nested function or a subfunction... D : return : it's a keyword that stop the execution of the statement in a MATLAB function. Subsequently controls returns to the calling program (eg. command window) that called the function (with values returned appropriately by the called function). E : The function defined in f.m is the name of the file without the .m This identifies the first function defined in the file. The first function defined in the file is the one beginning with the first function keyword. So far the f.m contains one function only. Later on we shall see more complicated examples. It is not an error to contain in file f.m a function definition that looks like function y= ff(x) y=x*x; return end MATLAB will know only function f (based on the file name) not function ff ! MAKE SURE THAT THE FIRST FUNCTION IN THE FILE HAS A NAME COINCIDING WITH THE FILE NAME (minum the .m) CASE IS IMPORTANT AS WELL. F : function y = f(x) x is the parameter. Additional parameters can exist and are separated by commas (as in function y=f(x,z,w)) G : return value . In function y = f(x) the return value is the one on the left of = symbol. In this case, the value of y is returned as the value of function f. One could have written also function [y] = i.e. the return value is a single element row vector containing y. More than one values can be returned in that case they form a vector function [y z] = Thus in this example y z are the return values H : Any MATLAB statement can appear between the function keyword and the end indicating the end of the function. If an end keyword is missing, the end is the last line of the file (implied). ******** PRIMARY FUNCTION : Local variables ************* >> x= 10; >> y= 20; >> b=3; >> a= f(b) ; >> a a = 9 >> x x = >> y y = - In the command window we define three variable x,y, a. x is set to 10, y to 20, and a to the value of f(b) x, y, a are variable in the MATLAB command window - Function f has its own variable defined. These are x,y x is for parameter passing y is the return value - The x,y of function f in f.m ARE DIFFERENT FROM the x,y,a of the COMMAND WINDOW. x,y of f are LOCAL VARIABLES: They come into existence when f is called and disappear after the return value is sent back to the main program ******** PRIMARY FUNCTION : Function invocation ********* >> a= f(b); function y = f(x) y=x*x; return; end When a= f(b) is executed. - The argument of f is evaluated i.e. b is evaluated to 3 - f(3) is then invoked i.e. the function f is called with argument 3 - The 3 of the argument is passed to function f - Space is allocated for all local variables in f such as x,y. - The value of argument 3 is assigned to local variable x the first (and only in our case) parameter of f. - The sequence of statements in f are being executed, thus y=x*x; changes the value for y to be equal to 9. - The return statement is encountered that terminates the function. This means - the return variable and value are retrieved. They are y and 9 respectively. - the return value is returned, and function f dies i.e. local variable x,y disappear (cease to exist) - that is f(b) is being replaced by 9 - The return value 9 is assigned to a because of the statement a= f(b); That is, a has value 9 - The values of x,y in the command window were NOT affected by the function f invocation ! THat is they are still are 10, 20! ******** PRIMARY FUNCTION : Operator Overload : Be careful! ********* - f([ 1 2; 3 4]) ans = 7 10 15 22 Note that x can be assigned a value that is an array. In that case * is to mean matrix multiplication not number multiplication! ******** PRIMARY FUNCTION : Other examples************* Function h has no parameters no return values ! A Simple function ! h.m Function k has no return statement. It is implied. The end could also be out k.m A function with two parameters f1.m >> x=10; >> y=20; >> z = f1(y,x); >> z z=50 >> x x=10 >> y y=20 Note that the value of y (20) is copied to be the value of local variable x and the value of x (10) is copied to be the value of local variable y A one-to-one correspondence between argument and parameters is used! - ff.m >> x=10; >> a=ff(10); >> x x=10 The local variable is zeroes before the return. This does not affect the x of the command window. - Fibonacci fib.m - The only return value is written as [ value ] This is the same as value - g.m MIN-MAX function. Finds the min and max of x,y - abs1.m In abs1.m when one of y=-x and y=x is executed the if exits and control goes to statement following if's end. There is nothing between if's end and function's end, but yet control goes there before termination! - abs2.m In abs2.m the if never completes. After y=-x; the function terminates immediately! - abs3.m Compare abs3.m - abs4.m to abs4.m abs3.m is correct but abs4.m is incorrect! What is the value of >> abs4(-4) ******** PRIMARY FUNCTION : Messy filenames *********** - Look at confused.m that defines primary function con >> confused(10) returns 100 the value of y. MATLAB reads the function name confused and look for file confused.m In file confused.m it consider the first function (with the keyword function) to be the primary function. Thus con becomes function confused MATLAB does not do integrity checking to compare con to confused of confused.m In other words, it ignores the con name! 3. Subfunctions - Is a subordinate function to a primary function. - It appears after a primary function in a file - It is local to the file of the primary function - Average of values of vector x avg.m - Implementation of avg.m with a subfunction of sum avg1.m - instead of using sum directly in avg, we call mysum and define a subfunction mysum that avg1 uses to call sum! - Primary function is the first one avg1 of avg1.m - Primary function extends to where the second function keyword appears. - Second keyword function defines mysum, a subordinate function known as a subfunction! - return and end are optional in primary function with or without the presence of a subfunction ! 4. Nested functions. - Are nested within primary or subfunctions ! - end is required for all functions in file (primary, nested , subfunctions) - The existence of a nested function : USE end to indicate end of all functions - avg2 is primary, and mysum , mylen are nested functions avg2.m mysum is defined as a nested function vs mysum of avg1.m that was subfunction mylen is another nested function - The code for avg2 starts after the second end of mylen and avg2 has only one line of code! (if space is ignored) - Local variables avg22.m Each function of the three has its own LOCAL COPY of x - Nested + Subfunction with a primary function avg3.m Mix and match - mysum is a subfunction - mysym is a nested function - line 1 of avg3 calls mysum. WHich one is it? What do you get printed out? ****** Nested has priority over subfunction of same name ************************* - avg31.m avg31.m contains function avg3 . The avg3 is inconsequential and ignored! - avg4.m or avg3 ? avg4.m - Nested function in subfunction avg44.m - Subfunctions can have nested functions as well! - The code y= mysum(x) / mylen(x) of avg44 is executed - Which mysum is executed ? The nested of avg44 - Which mylen is executed ? The nested of avg44 - Nested function in subfunction avg45.m - Subfunctions can have nested functions as well! - The code y= mysum(x) / mylen(x) of avg45 is executed - Which mysum is executed ? The nested of avg45 is my2sum! But subfunction mysum calls itself recursively through z=mysum(x). Recursion never terminates and generates an error! - Which mylen is executed ? The nested of avg45 would have been executed had recursion terminated! - Nested function in subfunction avg5.m Same as avg3.m - Nested function in subfunction avg6.m - Which mylen and mysum get executed? - avg6 : primary function - mysum nested of avg6 - mylen nested of avg6 -mylen subfunction of avg6 - zvg5 subfunction of avg6 Code executed is from avg6.m y=zvg5(x)/mylen(x); - zvg5 is the subfunction that calls a - sum (a system MATLAB function) - mylen <<< This one would be the subfunction. The nested mylen is only visible to avg6 - mylen of avg6 is of nested mylen of avg6 ! >> which f.m >> which abs >> which f 6. (6 is before 5!) Function Functions ! >> g= @ (x) (x^2 -4) g= @(x) (x^2 -4) g become a function handle for anonymoys function g. >> type k.m Function k is defined similarly to g. It's a primary function! What happens if someone says >> k ??? Input argument "x" is undefined. Error in ==> k at 2 y= x^2 -4; But @k is the handle of primary function k >> a= @k % copies handle of k to a >> a(10) ans =96 >> k(10) ans=96 - What is a function functions? - A function that is parameter of another function ! >> a=fzero('x^2 -4', [ 0 4]); a=2 % The string 'x^2 -4' defines a function with parameter x >> b =fzero(@(x)(x^2 -4), [ 0 4]); b=2 % Same thing but now there is an anonymous function defined ! >> c =fzero(g, [ 0 4]); c=2 % Same thing but now there is an anonymous function handle used (this is g) earlier defined >> d =fzero(@k, [ 0 4]); d=2 % Same thing with a primary function handle! 5. (Now we are in section 5) Private functions Are functions residing in a subfolder with the special name private . The functions in the subfolder private are visible by i. a primary function or a subfunction/nested function of that primary function that calls the private function in directory private! ii. a script that calls a primary function that calls the private function - a private function cannot be otherwise called by a script (other than the cases explained before) NOTE: In directory private local copies of primary functions can be created. These private copies will be executed by a primary function in the subfolder containing private. The private copies are thus of higher priority over same named subfolder functions. However to call the private function you need to follow the rules i and ii above. Thus in directory private one can define experimental not fully debuged code! However one can call this code only by following rules i and ii. Consider a directory containing files f.m , tpriv.m and directory private. The directory private contains f.m and bpriv.m f.m tpriv.m private f.m bpriv.m - Function tpriv of tpriv.m calls f . Which of the two f is to be executed? The one in private ! ----- apriv.m : calls private/bpriv bpriv.m : calls bpriv primary not private/bpriv cpriv.m : script calling primary apriv that calls private/bpriv bpriv calls primary bpriv dpriv.m : subfunction mypriv subf mypriv calls private/bpriv epriv.m : nested mypriv calls private/bpriv calls mypriv 7. SUMMARY : SCOPE OF FUNCTIONS mymy ? Which one 1. Is there a nested function mymy ? Call it! 2. Is there a subfunction mymy ? Call it! 3. Is there a private function mymy ? Call it! 4. Is there a (primary) function mymy in directory ? Call it! 5. Is there a (primary) function mymy elsewhere in MATLAB ? Call it! 6. then, ERROR! Function does not exist Example whoami.m z.m ---------------------------------------- 8. Other SPECIAL functions nargin : # of actual arguments supplied by caller nargout : # of return values supplied by caller nargchk : validate # of args, (min,max,nargin) checks if arg number is ok nargoutchk : validate # of nargout Last two are used in conjunction with error : detect and stop warning : detect and inform and continue execution nargin nargout allow for zeros(n), zeros(n,m) etc ********************* sub8narg.m x = [10 40 20 30 50 60]; >> sub8narg(x); Number of arguments/parameters used by caller is 1 Number of return values used by caller is 0 >> z = sub8narg(x); Number of arguments/parameters used by caller is 1 Number of return values used by caller is 1 z=35 >> [z d]=sub8narg(x) Number of arguments/parameters used by caller is 1 Number of return values used by caller is 2 z=35 d= 6 ********************* sub8nargc.m Check how nargchk and nargoutchk are being used to make sure that exactly 1 input argument exists (but if not only a warning is given) but at least 1 and at most 2 output values are returned (but if not, then an error is being generated). >> sub8nargc(x) Number of arguments/parameters used by caller is 1 Number of return values used by caller is 0 ??? Error using ==> sub8nargc Not enough output arguments. >> z= sub8nargc(x) Number of arguments/parameters used by caller is 1 Number of return values used by caller is 1 z = 35 >> [ z d] = sub8nargc(x) Number of arguments/parameters used by caller is 1 Number of return values used by caller is 2 z = 35 d = 6 >> z= sub8nargc() Number of arguments/parameters used by caller is 0 Number of return values used by caller is 1 Warning: Incorrect number of input argument\n > In sub8nargc at 7 z = 0 9. MATLAB Variables : Local, Global, and persistent 1. Local variables - standard MATLAB variables >> whos % defined + size info >> who % defined >> clear % variables cleared - functions : cleared automatically at termination and all its local variable s are also get wiped out - Also use : clear , clear all, clear functions 2. Global variables - whos and whos global - clear and clear global and clear all - A variable defined as global can be accessed from within a function / multiple functions and the command windows ************** sub8g.m - Defines two global variables global g1 , g2 >> sub8g() g1=-1 g2=-1 >> g1 ??? Undefined function or variable 'g1'. >> g2 ??? Undefined function or variable 'g2'. >> whos >> whos global >> whos global Name Size Bytes Class g1 1x1 8 double array (global) g2 1x1 8 double array (global) Grand total is 2 elements using 16 bytes >> global g1 g2 % connect to sub8g global variables >> g1 g1 = -1 >> g2 g2 = -1 >> g1=100 >> g2=200 >> sub8g(1000) g1=100 g2=1000 >> whos ? >> clear g1 g2 >> g1 ? >> g2 ? >> global g1 g2 >> g1 g1=100 >> g2 g2=1000 >> clear global >> g1 >> g2 *********************** glob1.m glob2.m >> glob1 >> glob2 >> glob1(10) ? >> glob1(20) >> glob2 >> glob2(40) >> glob1 >> my_global ??? Undefined function or variable 'my_global'. >> clear my_global >> my_global >> global my_global >> my_global my_global = 81 >> glob1 >> glob2 >> clear global my_global >> global my_global >> my_global my_global = [] >> whos 3. Persistent Variables : clear all, clear function A form of a local variable that persists a function's demise Example: Count how times a function is called ****************** pers1.m >> pers1 Filename : pers1 ** my_pers : >> pers1(-1) Filename : pers1 ** my_pers : 0 >> pers1(10) Filename : pers1 ** my_pers : 1 >> pers1(2000) Filename : pers1 ** my_pers : 2 >> pers1() Filename : pers1 ** my_pers : 2 >> pers1(30) Filename : pers1 ** my_pers : 3 >> clear >> pers1() Filename : pers1 ** my_pers : 3 >> clear all >> pers1() Filename : pers1 ** my_pers : >> pers1(-1); >> pers1(10) >> pers1(20) >> clear functions clear clear all clear global clear function clear variables 10. Review sub8seed.m sub8random.m sub8seed.m creates a random seed as in sub8seed(1000); to then use sub8random0(n) or sub8random0(m,n) >> sub8seed(10); >> sub8random0(1,5); >> sub8random0(1,5) >> sub8seed(10); >> sub8random0(1,5); >> sub8seed(10); >> sub8random0(1,5) >> sub8seed(10); >> sub8random0(1,5) >> sub8random0(1,5) whoami.m % Tue DiARY starts here DIARY_STARTS_HERE f = @ (x) ( x*x) f = @(x)(x*x) ff = @ (x,y) ( x * y) ff = @(x,y)(x*y) f (10) ans = 100 a=10; f(a) ans = 100 f f = @(x)(x*x) ff ff = @(x,y)(x*y) b= [ 1 2 ; 1 2] b = 1 2 1 2 f(b) ans = 3 6 3 6 ff(b,b) ans = 3 6 3 6 cd CS101 cd F12 cd Sub8 h Hi type h.m function h disp('Hi'); end h Hi h() Hi type f.m % Hi.. This is my function f function y=f(x) y=x*x; return end clear type f.m % Hi.. This is my function f function y=f(x) y=x*x; return end type f1.m function x=f1(x,y) x= 2*x+y; return end type f2.m % Hi.. This is my function f function x=f2(x) x=x*x; return end help f2 Hi.. This is my function f type f.m % Hi.. This is my function f function y=f(x) y=x*x; return end clear a=10; b=f(10); a a = 10 b b = 100 x= 10; y= 5; a= f(5); x x = 10 y y = 5 clear x= 10; y=10; x = f(y ); x x = 100 y y = 10 type k.m function y=k(x) y= x^2 -4; end k(10) ans = 96 k(10); ans ans = 96 type f1.m function x=f1(x,y) x= 2*x+y; return end clear x=10; clear type f1.m function x=f1(x,y) x= 2*x+y; return end x=10; y=10; z=f1(x,y); z z = 30 x x = 10 y y = 10 type g.m function [min max] = g(x,y) if (x < y) min= x; max= y; return; else min= y; max= x; return; end end clear type abs1.m function y=abs1(x) if (x<0) y=-x; else y=x; end end abs1(10) ans = 10 abs1(-10) ans = 10 type abs3.m function y=abs3(x) if (x<0) y=-x; return; end y=x; end abs3(10) ans = 10 abs3(-10) ans = 10 type abs3.m function y=abs3(x) if (x<0) y=-x; return; end y=x; end type abs4.m function y=abs4(x) if (x<0) y=-x; end y=x; end abs4(-10) ans = -10 abs4(10) ans = 10 type abs3.m function y=abs3(x) if (x<0) y=-x; return; end y=x; end type abs4.m function y=abs4(x) if (x<0) y=-x; end y=x; end type abs1.m function y=abs1(x) if (x<0) y=-x; else y=x; end end type abs6.m function y=abs1(x) if (x<0) y=-x; else y=x; end end abs6(10) ans = 10 datestr(now) ans = 04-Dec-2012 14:23:44 % Thu DiARY starts here DIARY_STARTS_HERE type avg.m function y=avg(x) % avg.m y=sum(x)/length(x); end x= [ 200 100 400 300] x = 200 100 400 300 avg(x) ans = 250 type avg.m function y=avg(x) % avg.m y=sum(x)/length(x); end type avg2.m function y=avg2(x) %avg2.m function z= mysum(x) z= sum(x) ; end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end type avg1.m function y=avg1(x) % avg1.m y=mysum(x)/length(x); function y=mysum(x) % subfunction mysum y=sum(x); avg1(x) ans = 250 type avg1.m function y=avg1(x) % avg1.m y=mysum(x)/length(x); function y=mysum(x) % subfunction mysum y=sum(x); type avg.m function y=avg(x) % avg.m y=sum(x)/length(x); end type avg3.m function y=avg3(x) % avg3.m function z= mysum(x) z= sum(x) ; fprintf('You are in the nested funtion\n'); end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end function z=mysum(x) z=sum(x); fprintf('You are in the subfunction\n'); end type avg2.m function y=avg2(x) %avg2.m function z= mysum(x) z= sum(x) ; end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end type avg3.m function y=avg3(x) % avg3.m function z= mysum(x) z= sum(x) ; fprintf('You are in the nested funtion\n'); end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end function z=mysum(x) z=sum(x); fprintf('You are in the subfunction\n'); end avg3(x) You are in the nested funtion ans = 250 type avg22.m function x=avg22(x) function x= mysum(x) x= sum(x) ; end function x=mylen(x) x= length(x) ; end x=mysum(x)/mylen(x); end type avg31.m function y=avg3(x) function z= mysum(x) z= sum(x) ; fprintf('You are in the nested funtion\n'); end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end function z=mysum(x) z=sum(x); fprintf('You are in the subfunction\n'); end avg31(x) You are in the nested funtion ans = 250 type avg31.m function y=avg3(x) function z= mysum(x) z= sum(x) ; fprintf('You are in the nested funtion\n'); end function z=mylen(x) z= length(x) ; end y=mysum(x)/mylen(x); end function z=mysum(x) z=sum(x); fprintf('You are in the subfunction\n'); end type avg4.m %The file is avg4.m but the function name is avg3 : You are looking for TROUBBBBBBBLE function y=avg3(x) function z= my2sum(x) z= sum(x) ; fprintf('You are in the nested function mysum\n'); end function z=mylen(x) z= length(x) ; fprintf('You are in the nested function mylen\n'); end y=mysum(x)/mylen(x); end function z=mysum(x) z=sum(x); w=mylen(x); fprintf('You are in the subfunction mysum\n'); end clear type avg6.m function y=avg6(x) function z= mysum(x) z= sum(x) ; fprintf('You are in the nested function mysum\n'); end function z=mylen(x) z= length(x) ; fprintf('You are in the nested function mylen\n'); end y=zvg5(x)/mylen(x); end function z=mylen(x) z= length(x) ; fprintf('You are in the subfunction function mylen\n'); end function z=zvg5(x) z=sum(x); w=mylen(x); fprintf('You are in the subfunction mysum\n'); end clear g = @ (x) (x^2 -4 ) g = @(x)(x^2-4) g(10) ans = 96 m = g m = @(x)(x^2-4) m(10) ans = 96 whos Name Size Bytes Class Attributes ans 1x1 8 double g 1x1 32 function_handle m 1x1 32 function_handle type f.m % Hi.. This is my function f function y=f(x) y=x*x; return end f(10) ans = 100 m = f Error m = @ f m = @f m(10) ans = 100 f(10) ans = 100 clear g = @ (x) (x^2 -4 ) g = @(x)(x^2-4) a = fzero('x^2- 4', [ 0 4] ) a = 2 b= fzero(@(x) (x^2 -4), [ 0 4 ]) b = 2 c= fzero(g,[0 4 ]) c = 2 d= fzero(@f, [0 4 ]) d = 0 type k.m function y=k(x) y= x^2 -4; end d= fzero(@k, [0 4 ]) d = 2 dir ls private bpriv.m f.m dir private . .. bpriv.m f.m cd private type bpriv.m function bpriv fprintf('Hi. This is private/bpriv.m\n'); end type f.m function y=f(x) fprintf('The private function f \n'); fprintf('Overrides the primary function f that squares its argument\n'); fprintf('This private function returns x, not square of x\n'); y=x; end cd .. f(10) ans = 100 quit