L-16 MCS 320 Wednesday 28 September 2005
| > | restart; |
1. Procedures returning procedures
In Maple we can execute a procedure numerically or symbolically, giving numbers or symbols on input. We can also give procedures on input.
| > | newtonstep := proc(f::procedure) |
| > | local ix; |
| > | ix := x -> x; |
| > | ix - eval(f)/D(eval(f)); |
| > | end proc; |
| > | g := x -> cos(x) -1/2; |
| > | gstep := newtonstep(g); |
| > | gstep(0.4); # numerical execution |
| > | gstep(a); # symbolic execution |
| > | y := 0.4: # start point in the Newton iteration |
| > | Digits := 32: |
| > | for i from 1 to 7 do |
| > | y := gstep(y); |
| > | end do; |
2. Indexed Procedures
| > | evalf[33](Pi); |
The evalf is a procedure with an index. The "33" in the call above is an index, the Pi is the argument to the function. We use indices as parameters to functions.
We can test if a name has an index or not:
| > | b := A[3]; |
| > | op(b); # select the index of A |
| > | type(b,`indexed`); # verify if A is indexed |
In the definition of a procedure we can test if the name of the procedure is indexed. If so we can so the value of the index, selected via the op command, or we can use a default.
As example consider the function f(t) = b + (70 - b)*exp(-0.2*t), where b is an index, by default we take b = 32. The meaning of b is that this is the outside temperature, 70 is the starting temperature.
| > | cool := proc(t)
description "an illustration of an indexed procedure": local b: if type(procname,`indexed`) # see if cool is called with an index then b := op(procname); # b takes the value of the index else b := 32; # if no index, use the default value end if: return b + (70-b)*exp(-0.2*t); end proc: |
| > | cool(4.3); |
| > | cool[32](4.3); |
| > | cool[64](4.3); |
3. Efficient Recursive Procedures
Recursion is a powerful method to define functions. Let us consider the Fibonacci sequence:
F(0) = 0, F(1) = 1, F(n) = F(n-1) + F(n-2), for n > 1.
| > | F := proc(n::nonnegint)
description "returns the n-th Fibonacci number": |
| > | option remember; # crucial for an efficient execution !!!
if n = 0 then return 0: elif n = 1 then return 1: else return F(n-1) + F(n-2): end if: |
| > | end proc: |
| > | for i from 1 to 10 do F(i); end do; |
| > | F(20); |
| > | F(40); |
| > | T := op(4,eval(F)); |
![]()
![]()
![]()
![]()
![]()
We can change the remember table as follows:
| > | F(39) := 1: # change the outcome of the function |
| > | F(41); |
The following command destroys the remember table:
| > | forget(F); |
| > | F(41); |
So we now get the correct Fibonacci number.