Composing functions is slightly more complicated than combining them. Suppose that the tree structures representing the functions / ( ' ) : X and ) :
X n) have been created, and we wish to create the tree structure
representing the function / o ^ ( * ) : X"' X , where f og[x) -■ f{g{x)) . Then the tree structure of the function /(► ) is replicated, with every occurrence of a pointer to the variable Xi replaced by a pointer to the tree structure representing
m(-)
•6.4 T he A t Q U I B package
The procedures which make up the A t Q U I B package are described in this section. The procedure headings and an example call of each procedure are given in the pseudo-code of Appendix G.
The procedure define,variables , which has a head of the form
procedure def ine.variables[variable.names G — >- P^)
takes the vector of strings which are intended to make up the variable names, creates a structure of class variable corresponding to each of these names, and returns a vector of pointers, each of whose components points'to one of these structures. The names are checked for uniqueness and validity. To define a set of variables whose names are stored in the vector of strings, names , the statement
- 1 0 7 -
is used.
The procedure string,to, functdon , which has a head of the form p ro c e d u re string.to,function(variables € ^ expression 6 S — > F )
takes as input the set of variables on which we wish to define the function, and a string representation of the function. The tree representation of the function is created, and a pointer to it is returned. Assuming we have defined a set of variables with names “ $1 " , “ x2 " , “ xB " as described above, and that the variable expression ,
of type string, contains the character
string “ cos(xl + x2 :{= n;3) ” , the statement/ := stringJo,fîinction(variables, expression)
creates the tree representation of Figure 6.1 and returns a pointer to it.
The procedure function,form at , which has a head of the form p ro c e d u re f unction, f o r mai( fact or able €.P — s* F)
reverses the process of string.to,f unction , and converts a function, held in its tree representation and pointed at by factorable , into a string
ready
for output. Extensive bracketing is used to avoid ambiguity.Once the tree representation of a function has been created, it may be evaluated by the procedure evaluate , which
has
a head of the form. • , ,p ro c e d u re evaluate(fadorable E 1^,point E — >- X ).
This procedure takes, as input, a pointer to
the
tree and the point atwhich
the function is to be evaluated. The value of the function at the given point isreturned.
For example, if ulie vector point contains the point at which the function / defined as above is to be evaluated, then the statement
f . o f .point :■-= evaluate[f, point]
w ill evaluate / , Two variations of this procedure are also provided to evaluate functions from X " to X " and functions from X " to M (X ^ ) . The first
procedure vecevaluate{faciorahle G ,poi?it G X.'’" — > X ”') evaluates a vector of functions at the given point while
procedure m.atevaluate(factorable G M (P ” ),pom i G X ^ — > M(X^^')) evaluates the given m atrix of functions at the given point.
The procedure partial , which has a head of the form
procédure 2)a rtia l[f adorable, variable G F — ^ P )
takes a pointer to a function’s tree representation and a pointer to a variable. A tree representation of the derivative of the function with respect to the variable is created, and a pointer to it is returned. Thus, the statement
df.by.dxl partial{f, variaMes[l))
where variables(l) points to the A £ ^ £ X B representation of the variable ;ri , wbhld create the tree structure representing d f / d x i , and return a pointer to it. •
The procedure fim dion.op.function which has a head of the form pro ced u re f unction.op. f unction[a G F, op G S',6 G F — F)
— 109
creates the tree representation of the function formed when the two functions, a and b are combined by the given binary operator op . Thus if functions / and g had been created as described previously, and the variable, operator contained the string “ -f " , then the statement
h functîon.op.funclion[f, operator, g)
would create a tree representation of the function h(< ) — /{• ) ) . There are also two procedures which allow values to be combined with functions. They are
p ro c e d u re value.op.fiinction[a G X,op E S,b E P — F )
and
procedure function.op.vahie[a G P, op E S,b E X — j* P).
The procedure op,function which has a head of the form
p ro c e d u re op. f unction {op G S,org G F — > F )
creates the tree representation of the function which is obtained when the given operator acts on the given function. If the variable operator contains the character string “ cos ” , then the statement
g := op. f u n d ion [operator, f )
would create the tree representation of the function {/(• ) ™ c o s (/(-)) .
The procedure compose which has a head of the form
takes as input a pointer / to the tree
representation
of a function fromto
X^ , and a vector g of pointers, each of whose components points to the tree representation of one of the components of a function from X"' to X"' . A tree
representation of
the
composition f o g of / with g is returned. For example,the statement
k compose(f, g)
would create the tree representation of the function h : X ^ X^ where h(* ) — f{(i{-)) ■
The  IL Q Z IB package also contains other
procedures
which act on functions from X ^to
, and on functions from X'^ to A f(X ” ) , where M ( X ” ) is the set of matrices over X of order n .The following example is of interest since it illustrates most of the facilities of the A flQ fL IB package.
E xa m p le 6.2 s: The solution of syterns of equations of the form
Aæ-h d(2)) + c = 0 (6.11)
where A G M (R ^) is tridiagonal, d : -4- is a diagonal operator and c G Bf" , is a common problem in numerical mathematics. I f A == {«ty)„,xn • ’