Back Arrow to Return to Oheads
Demo 0 Factorial and Loops
%src/my_fac.m function nfac = my_fact( n ) %compute factorial recursively if n = 0 nfac= 1 else nfac= (n+1)*nfac(n); end end
function sum = mat_add(A) % Sum elements of A % sum is name of MatLab builtin but no conflict (scoping!) [Rows Cols] = size(A); sum = 0; % initialize for r = 1:Rows for c = 1:Cols sum = sum+A(r,c); end % cols end % rows end % mat_add
Congratulations, you're hired as a Teaching Assistant in CSC160. Your office hour is 4-5 on Tuesdays, and sure enough at 4:56 a student slouches in. What you hear:
"I'm supposed to evaluate this infinite series expression thingie for the sine of x (x is in radians):
sin(x) = x - (x^3)/3! + (x^5)/5! - (x^7)/7! + ...
I definitely understand the concept but there seem to be a few programming details to be worked out. I think it's close and I'm frustrated that I ran out of time: I slept thru most of my last class, when I was planning on doing this...sorry, I gotta take this call..."
What you see:
function sintheta= my_sin( theta ) % return sin, where theta is in radians my_sin calls my own factorial function as well sintheta= 0; term =1; n = 1; sign = 1; % implement alternating signs while term >= .001; expon= 2*n +1; germ = sign* ((theta^expon)/(my_fact(expon)) sintheta = sinthta + term; sign = (-1)*sign; end end
See if you can get this code working (assume my_fact() works)!
Demo 2: Simple Debugger Use
function debug_demo() n = 8; n_squared = n*n; some_formula = pi*2*n_squared; a_sum = 0; for kount = 1:5 a_sum = a_sum + kount; end A_answer = A_func(9); end function A = A_func(n) A = 0; localvar=16; for ice = n:2*n B_answer = B_function(10*n); A = ice + B_answer; end end function B = B_function(n) B = pi*n; B = sqrt(B); B = 100*B; endTo trace execution in a function or script, we use echo. Set echo on in command window like
Now in the editor (with debug_demo being edited), set a breakpoint at statements B_answer =... and B = pi*n; say: Do that by clicking the "-" just to the right of statements number 9 and 16 ("-"s change to red dots). Now return to command window and run debug_demo. *boom* your command prompt changes to K>> (for debugging mode), the edit window should pop up, and there's a green arrow next to the red ball where the first breakpoint is.
Hover the mouse over variables in the edit window and you can see that
are 0 and 9, for instance. Over in the command window you can also
(and change!) variables, as in
K>> localvar localvar = 16 K>> localvar = -99 localvar = -99Go hover in editor and check!
Go to edit window and thence to the debug menu and choose "step", which only executes the next statement. *boom* you're at the next breakpoint, down in the B_func. Debugging commands: check out continue, which restarts full-speed execution but stops at breakpoints. Breakpoints can be cleared by command or by klikking on them. See the documentation for more features and examples. step in steps into functions, (step does not). dbstack shows where you are in nested function calls and thus how you got there.
Notice that the same variable name n is used in all three local variable contexts (functions, "rooms"). You can't see one function's variables when you're executing in another function, and as you switch functions the values of n in that context switch appropriately. Good illustration of variable scoping!
To exit debug mode type dbquit at command window, or use Exit Debug Mode in the Debug menu.
function fib= my_fib(n) %computes fibonacci number of n<11: f(n) = f(n-2)+f(n-1), % f(1) = 1, f(2) = 1; if n>10 error('Please keep my_fib arg between 1 and 10.'); end if n < 3 fib=1; else fiba = my_fib(n-2); fibb = my_fib(n-1); fib = fiba+fibb; end
To trace execution in a function or script, we use echo.
Set echo my_fib on in command window like
echo my_fib on
Run my_fib it on a small integer, like like
>>my_fib(4) is enough -- and see what happens. Turn echo off.
echo my_fib off
To exit debug mode type dbquit at command window, or use Exit on the Debug menu.
Now in the editor (with my_fib being edited), set a breakpoint at the statement fibb = my_fib(n-1); say: Do that by clicking the "-" just to the right of the statement number 12 for that statement (get a red ball). Now return to command window and run my_fib(5) say. *boom* your command prompt changes to K>> (for debugging mode), the edit window should pop up, and there's a green arrow next to the red ball where the breakpoint is. Go to edit window and thence to the debug menu and try some commands like "step".
Also let the cursor hover over the variables "n" and "fiba". Magic, eh? you see their values: Very Useful. "fibb" doesn't have a value yet since you haven't done that statement.
Go to command window (should see K>> for debugging prompt) and do a "step" from Debug menu, then type fiba to print out value of fiba. It's not changing, because "step"ping does not enter function calls...so you never get below the 'top recursive level'. Now if you exit debug mode and then run my_fib(5) again, hit the breakpoint, and this time use "step in", you'll notice that n's value is now 2: you're down a recursive level. Go back over to command window and type dbstack to see something like
In my_fib at 4 In my_fib at 12 In my_fib at 11
This says you're at line 4, in a level of the program that was called from line 12, which was called from line 11. It's interesting to figure out why this is right!
dbdown and dbup move you through the contexts containing local variables ('workspaces', in matlab-ese: we often call them 'rooms'). You can see the values of local variables at different levels of function call just by typing their names as usual. E.g. with the breakpoint set as before, in the first level of my_fib we expect n = 5 and when it calls my_fib (itself) the first time, we expect that version of the function to be entered with n=3. You can verify all this using by printing variables after the breakpoint, choosing "Step In" from the debug tool, printing out the variables, doing dbup and dbdown, more printing,...
So if you want to know more, do the usual: help debug and matlab tutorial web pages. Also, debugging NON-recursive programs is much less mental overhead!!
Back Arrow to Return to Oheads