We have shown how one can tell Maple properties about a function by
coding them as a procedure. Suppose instead you wish to teach Maple to
differentiate a formula involving
.
You may want to teach Maple how to evaluate
numerically so that
can be plotted, or how to simplify expressions involving
etc.
What do you need to do?
Many Maple routines have interfaces that allow you to teach these
routines about your
function.
These include diff, evalf, expand, combine,
simplify, series, etc.
To teach Maple how to differentiate a function
one writes a routine called `diff/W`.
If the diff routine is called with an expression
which contains
then the diff routine will invoke `diff/W`(g,x) to
compute the derivative of
with respect to
.
Suppose we know that
.
Then we can write the following procedure which
explicitly codes the chain rule.
`diff/W` := proc(g,x) diff(g,x) * W(g)/(1+W(g)) end;
Hence we have
> diff(W(x),x); W(x) -------- 1 + W(x) > diff(W(x^2),x); 2 x W(x ) 2 --------- 2 1 + W(x )
As a second example, suppose we want to manipulate symbolically
the Chebyshev polynomials of the first kind . We can represent these in Maple
as T(n,x). Suppose also that for a particular value of
we want to expand T(n,x) out as a polynomial in
.
We can tell Maple's expand function how to do this by writing
the routine `expand/T`.
When expand sees T(n,x),
it will invoke `expand/T`(n,x).
Recall that
satisfies the linear recurrence
,
, and
.
Hence we can write
`expand/T` := proc(n,x) option remember; if n = 0 then 1 elif n = 1 then x elif not type(n,integer) then T(n,x) # can't do anything else expand(2*x*T(n-1,x) - T(n-2,x)) fi end;
This routine is recursive, but because we used the remember option,
this routine will compute quite quickly.
Here are some examples
> T(4,x); T(4, x) > expand(T(4,x)); 4 2 8 x - 8 x + 1 > expand(T(100,x)); 2 100 1 - 5000 x ... output deleted ... + 633825300114114700748351602688 x
One can also tell Maple how to evaluate your own function numerically by
defining a Maple procedure `evalf/f` such that
`evalf/f`(x) computes
numerically.
For example, suppose we wanted to use the Newton iteration shown
earlier for computing the square root of a numerical value.
Our function might look like
`evalf/Sqrt` := proc(a) local x,xk,xkm1; x := evalf(a); # evaluate the argument in floating point if not type(a,numeric) then RETURN( Sqrt(x) ) fi; if x<0 then ERROR(`square root of a negative number`) fi; Digits := Digits + 3; # add some guard digits xkm1 := 0; xk := evalf(x/2); # initial floating point approximation while abs(xk-xkm1) > abs(xk)*10^(-Digits) do xkm1 := xk; xk := (xk + x/xk)/2; od; Digits := Digits - 3; evalf(xk); # round the result to Digits precision end;
> x := Sqrt(3); x := Sqrt(3) > evalf(x); 1.732050808 > Digits := 50; Digits := 50 > evalf(Sqrt(3)); 1.7320508075688772935274463415058723669428052538104