funcenv
-- create a function
environmentfuncenv
creates a function environment. A function
environment behaves like an ordinary function with the additional
possibility to define function attributes. These are used to overload
standard system functions such as diff
, float
etc.
funcenv(f1 <, f2> <, slotTable>)
f1 |
- | an arbitrary MuPAD object. Typically, a procedure. It handles the evaluation of a function call to the function environment. |
f2 |
- | a procedure handling the screen output of symbolic function calls |
slotTable |
- | a table of function attributes (slots) |
a function environment of type DOM_FUNC_ENV
.
Chapter ``Function Environments'' of the Tutorial.
funcenv
serves for generating a function
environment of domain type DOM_FUNC_ENV
.
From a user's point of view, function environments are similar to procedures and can be called like any MuPAD function.
However, in contrast to simple procedures, a function environment
allows a tight integration into the MuPAD system. In particular,
standard system functions such as diff
, expand
, float
etc. can be told how to act on
symbolic function calls to a function environment.
For this, a function environment stores special function attributes
(slots) in an internal table. Whenever an
overloadable system function such as diff
, expand
, float
encounters an object of type
DOM_FUNC_ENV
, its
searches the function environment for a corresponding slot. If found,
it calls the corresponding slot and returns the value produced by the
slot.
Slots can be incorporated into the function environment by creating
a table slotTable
and passing this to
funcenv
, when the function environment is created.
Alternatively, the function slot
can be used to add further slots
to an existing function environment.
See example 1 below for further information.
f1
of funcenv
determines the evaluation of function calls. With f:=
funcenv(f1)
, the call f(x)
returns the result
f1(x)
. Note that calls of the form f:=
funcenv(f)
are possible (and, in fact, typical). This call
embeds the procedure f
into a function environment of the
same name. The original procedure f
is stored internally
in the function environment f
. After this call, further
function attributes can be attached to f
via the slot
function.f2
of funcenv
determines the screen output of symbolic function calls. Consider
f:= funcenv(f1, f2)
. If the call f(x)
returns
a symbolic function call f(x)
with 0-th operand
f
, then f2
is called: the return value of
f2(f(x))
is used as the screen output of
f(x)
.
Beware: f2(f(x))
should not produce a
result containing a further symbolic call of f
, because
this will lead to an infinite recursion, causing an error message.
slotTable
of funcenv
is a table containing function attributes
(slots). The table has to use strings as indices
to address system functions. E.g.,
slotTable := table("diff" = mydiff, "float" = myfloat): f := funcenv(f1, f2, slotTable):attaches the slot functions
mydiff
and
myfloat
to f
. They are called by the system
functions diff
and
float
, respectively,
whenever they encounter a symbolic expression f(x)
with
0-th operand f
. The internal slot table can be
changed or filled with additional function attributes via the function
slot
.float
, print
, and slot
provides further examples
involving function environments.funcenv
is a function of the system kernel.We want to introduce a function f
that
represents a solution of the differential equation f'(x) = x +
sin(x)*f(x). First, we define a function f
, which
returns any call f(x)
symbolically:
>> f := proc(x) begin procname(args()) end_proc: f(x), f(3 + y)
f(x), f(y + 3)
Because of the differential equation f'(x) = x +
sin(x)*f(x), derivatives of f
can be rewritten in
terms of f
. How can we tell the MuPAD system to
differentiate symbolic functions calls such as f(x)
accordingly? For this, we first have to embed the procedure
f
into a function environment:
>> f := funcenv(f):
The function environment behaves like the original procedure:
>> f(x), f(3 + y)
f(x), f(y + 3)
System functions such as diff
still treat symbolic calls of
f
as calls to unknown functions:
>> diff(f(x + 3), x)
D(f)(x + 3)
However, as a function environment, f
can
receive attributes that overload the system functions. The following
slot
call attaches a
dummy "diff"
attribute to f
:
>> f := slot(f, "diff", mydiff): diff(2*f(x^2) + x, x)
2 2 mydiff(f(x ), x) + 1
We attach a more meaningful "diff"
attribute to f
that is based on f'(x) = x +
sin(x)*f(x). Note, that arbitrary calls diff(f(y), x1, x2,
..)
have to be handled by this slot:
>> fdiff := proc(fcall) local y; begin y:= op(fcall, 1); (y + sin(y)*f(y))*diff(y, args(2..args(0))) end_proc: f := slot(f, "diff", fdiff):
Now, as far as differentiation is concerned, the
function f
is fully integrated into MuPAD:
>> diff(f(x), x), diff(f(x), x, x)
x + f(x) sin(x), f(x) cos(x) + sin(x) (x + f(x) sin(x)) + 1
>> diff(sin(x)*f(x^2), x)
2 2 2 2 cos(x) f(x ) + 2 x sin(x) (x + f(x ) sin(x ))
Since Taylor expansion around finite points only needs
to evaluate derivatives, also Taylor expansions of f
can
be computed:
>> taylor(f(x^2), x = 0, 9)
4 / f(0) \ 8 / f(0) \ 9 f(0) + x | ---- + 1/2 | + x | ---- + 1/8 | + O(x ) \ 2 / \ 12 /
>> delete f, fdiff:
exp
, ln
etc. or abs
, Re
, Im
etc. are implemented as function
environments.func_env