Topic 6: More Programming

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

Demos 1 Debugging

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

Simple Example

Copy this function (with its subfunctions) into your matlab editor and save it with name debug_demo.m. We'll want it in the editor window later.

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;
end
To trace execution in a function or script, we use echo. Set echo on in command window like
echo on
Run debug_demo like
>>debug_demo
and see what happens. The statements at the functions "top level" get echoed... not those from the recursive call, however. Also it seems not every statement is printed.... maybe just first one in function calls?? Turn echo off.
echo off

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 A, n are 0 and 9, for instance. Over in the command window you can also access (and change!) variables, as in

K>> localvar
localvar = 16
K>> localvar = -99
localvar = -99
Go 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.

Confusing Example

Copy this function into your matlab editor and save it with name my_fib.m. We'll want it in the editor window later.

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

---

Last update: 04/22/2011: RN