Writing Functions in Domains
Description
The basic idea for writing code in Domains for computing with elements of a domain(s) is to pass the domain(s) as an argument(s) to the procedure. Essentially passing a collection of routines for manipulating elements of the domain. E.g., let us write a routine to evaluate a univariate polynomial a(x) at x=b. Our routine would look like this
Evaluate := proc(P,a,b) local R,k,d,r;
if not hasCategory(P,UnivariatePolynomial) then error "..." end if;
R := P[CoefficientRing];
We pass the domain P as the first argument and check that it is a univariate polynomial domain then since we need to do coefficient operations, we get the coefficient ring and call it R.
Next, we check the argument types of a and x as follows
if not P[Type](a) then error "2nd argument must be of type P" end if;
if not R[Type](b) then error "3rd argument must be of type R" end if;
Now we can do the polynomial evaluation using Horners rule in the normal way. We need to use the Degree and Coeff functions from the univariate polynomial domain P, and the arithmetic operations `+` and `*` from the coefficient domain R.
d := P[Degree](a);
r := P[Coeff](a,d);
for k from d-1 by -1 to 0 do r := R[`+`](R[`*`](r,b),P[Coeff](a,k)) end do;
r
end proc:
Note: the overhead of the table referencing in this example is quite small. I.e. the time to access the procedures P[Degree] and R[`+`] etc. One might think to optimize this by factoring the table referencing operations out of the inner loop as follows. Define three local variables cof, add, mul, and
$\mathrm{cof}:=\mathrm{eval}\left({P}_{\mathrm{Coeff}}\right);$
$\mathrm{mul}:=\mathrm{eval}\left(R\[`*`\]\right);$
$\mathrm{add}:=\mathrm{eval}\left(R\[`+`\]\right);$
Note: P[Coeff], R[`*`], and R[`+`] are assigned to Maple procedures so eval must be used to evaluate to the procedure. Then recoding the main loop as
for k from d-1 by -1 to 0 do r := add(mul(r,b),cof(a,k)) end do;
But this saves very little time. The main overhead in Domains comes not from this table subscripting but from the fact that almost every function in Domains does a Maple procedure call. I.e. the operations P[Degree], P[Coeff], R[`+`], and R[`*`] are in general Maple procedure calls, which execute slower than builtin Maple functions. E.g. P[Degree] and P[Coeff] will execute slower on the polynomial data structure than the builtin Maple functions degree and coeff do on the builtin Maple sum-of-products data structure.
Download Help Document