gfun
rectoproc
convert a recurrence into a function
Calling Sequence
Parameters
Description
Examples
rectoproc(eqns,u(n), remember, list,params=[a,b,...],<options>)
eqns
-
single equation, or list or set of equations
u
name; recurrence name
n
name; index of recurrence u
remember
(optional) name; specify that returned procedure uses option remember
list
(optional) name; specify that returned procedure computes the list [u(0), ..., u(n)]
params = [a, b, ...]
(optional) names; argument names
evalfun = fname
(optional) a function applied at each iteration
preargs=[c, d, ...]
(optional) first arguments to this function
postargs=[e, f, ...]
(optional) last arguments to this function
evalinicond
(optional)
whilecond=boolean_expr
(optional) while condition
errorcond=boolean_expr
(optional) error condition
index
rhs=expression
copyright=string
(optional) copyright string to be added to the options
extralocal=[g, h, ...]
(optional) names for extra local variables
nosymbolsums
The rectoproc(eqns, u(n)) command returns a Maple procedure that, given a non-negative integer n as input, returns the nth term u(n) of the linear recurrence.
If the optional argument remember is supplied, the procedure returned will use option remember.
If list is specified, the returned procedure computes the list [u⁡0,...,u⁡n]. In this case it runs in a linear number of arithmetic operations.
One of the optional arguments remember or list should be given each time one needs a large number of values of the sequence. When the first terms of the recurrence are not explicitly supplied, they are represented symbolically.
If params=[a,b,...] is specified, the function returns a procedure that accepts n, a, b,... as input.
If the coefficients of the recurrence are nonconstant polynomials, the returned procedure runs in a linear number of arithmetic operations without using extra space if the remember option is not specified.
If the coefficients are constant, the returned procedure runs in a logarithmic number of arithmetic operations without using extra space if the remember option is not specified.
If the optional argument evalfun=fname is given, then the specified procedure is used in the generated code as an evaluation rule. Extra arguments can be passed to the procedure with options preargs= [c,d,...] and postargs= [ⅇ,f,...]. Names declared in preargs and postargs may appear in the argument sequence of the generated procedure if they are also declared with the option params. The function is mapped over initial conditions and it is evaluated before procedure generation if the option evalinicond is supplied.
The option whilecond=boolean_expr defines a condition that is checked at each iteration of the loop of the generated procedure. The condition is represented by a boolean expression that may be function of n, u⁡n−k for any positive integer k and function of the names declared in params, preargs and postargs. Execution stops when the condition turns true. This option does not impact initial conditions.
The option errorcond=boolean_expr defines a condition that is checked at each iteration of the loop of the generated procedure. The condition is represented by a boolean expression that may be function of n, u⁡n−k for any positive integer k in 0..ord - where ord is the order of the recurrence - and function of the names declared in params, preargs and postargs. An error is thrown when the condition turns true.
The option extralocal= [g,h,...] allows to declare and initialize extra local variables. g, h, ... must be either symbols or equations in the form symbol=expression, in which case the expression is used for initialization.
The option nosymbolsubs disables the name substitution that occurs for the parameters (declared with the option params). This means that the symbols that are used in the generated procedures are the same as the symbols used in the input recurrence. By default, the symbols that are used in the generated procedures are gathered in the global table gfun/rectoproc/symbol.
The option index makes the generated procedure return the list n,u⁡n. This is useful in conjunction with whilecond.
You should specify remember or list each time a large number of values for the sequence is required.
The option rhs=expression allows to specify a right hand side of the recurrence that does not have to be a polynomial. The right hand side may be function of n and of the names declared in the options params, preargs and postargs.
Fibonacci numbers
You can create different types of programs to generate Fibonacci numbers that meet certain memory or time requirements.
The most obvious procedure is recursive and "remembers" values that are already computed.
fiborec≔f⁡0=1,f⁡1=1,f⁡i=f⁡i−1+f⁡i−2
with⁡gfun:
fib1:=rectoproc(fiborec,f(i),remember);
fib1 ≔ procnoptionremember;procname⁡−2+n+procname⁡n − 1end proc
fib1⁡100
573147844013817084101
To create a program which computes and lists the first n terms of the recurrence, we use the list option.
fib2:=rectoproc(fiborec,f(i),list);
fib2 ≔ procnlocali1,loc;loc[0] ≔ 1;loc[1] ≔ 1;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc[0]elifn=1thenreturnloc[1]end if;fori1ton − 1doloc[i1+1] ≔ loc[i1 − 1]+loc[i1]end do;seq⁡loc[i1],i1=0..nend proc
fib2⁡10
1,1,2,3,5,8,13,21,34,55,89
To create a program that is more space conscious we avoid the remember option. In this case the program exploits the fact that the recurrence has constant coefficients for extra efficiency.
fib3:=rectoproc(fiborec,f(i));
fib3 ≔ procnlocali1,loc0,loc1,loc2,tmp2,tmp1,i2;ifn<=44thenloc0 ≔ 1;loc1 ≔ 1;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc0elifn=1thenreturnloc1end if;fori1ton − 1doloc2 ≔ loc0+loc1;loc0 ≔ loc1;loc1 ≔ loc2end do;loc1elsetmp2 ≔ 1110;tmp1 ≔ 11;i2 ≔ convert⁡n − 1,base,2;ifi2[1]=1thentmp1 ≔ 21end if;fori1insubsop⁡1=,i2dotmp2 ≔ LinearAlgebra:-MatrixMatrixMultiply⁡tmp2,tmp2;ifi1=1thentmp1 ≔ LinearAlgebra:-MatrixVectorMultiply⁡tmp2,tmp1end ifend do;tmp1[1]end ifend proc
fib3⁡100
fib3⁡1000
70330367711422815821835254877183549770181269836358732742604905087154537118196933579742249494562611733487750449241765991088186363265450223647106012053374121273867339111198139373125598767690091902245245323403501
An example of right-hand side: nested procedures
This example shows how terms of nested recurrences can be computed. The first sequence is first converted into a procedure:
rec_u≔u⁡n+2⁢n2+n+1+u⁡n+1⁢n−2+u⁡n⁢n,u⁡0=1,u⁡1=2
rec_u≔u⁡n+2⁢n2+n+1+u⁡n+1⁢−2+n+u⁡n⁢n,u⁡0=1,u⁡1=2
u_n := rectoproc(rec_u,u(n),remember);
u_n ≔ procnoptionremember;2*procname⁡−2+n+4*procname⁡n − 1 − procname⁡−2+n+procname⁡n − 1*n/3+−3+n*nend proc
The second sequence is defined by
rec_v≔v⁡n+3⁢n+4+v⁡n+1⁢n2+2⁢n=u⁡n+1−n⁢u⁡n
rec_v≔v⁡n+3⁢n+4+v⁡n+1⁢n2+2⁢n=u⁡n+1−u⁡n⁢n
ini_v≔v⁡0=1,v⁡1=2,v⁡2=3
The procedure computing v⁡n is now generated
v_n:=rectoproc({op(1,rec_v)}union ini_v,v(n),rhs=subs(u=u_n,op(2,rec_v)),list);
v_n ≔ procnlocali1,loc;loc[0] ≔ 1;loc[1] ≔ 2;loc[2] ≔ 3;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc[0]elifn=1thenreturnloc[1]elifn=2thenreturnloc[2]end if;fori1from2ton − 1doloc[i1+1] ≔ u_n⁡i1 − 1 − u_n⁡i1 − 2*i1 − 2 − 3+−3+i1*i1+1*loc[i1 − 1]/i1+2end do;seq⁡loc[i1],i1=0..nend proc
Computation of 10 first terms:
v_n⁡9
1,2,3,12,−75,−179,12549,68031092,−16956717199,−42369714105
Applying a function at each iteration
We illustrate several ways to compute numerical values of the sequence defined by the following recurrence:
rec≔u⁡n+2⁢n+1+u⁡n⁢n2+1,u⁡0=sin⁡1,u⁡1=cos⁡1
If hardware floating point numbers give a sufficient accuracy, then it is best to produce the procedure and then call evalhf on it:
p:=subsop(4=NULL,rectoproc(rec,u(n)));
p ≔ procnlocali1,loc0,loc1,loc2;loc0 ≔ sin⁡1;loc1 ≔ cos⁡1;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc0elifn=1thenreturnloc1end if;fori1ton − 1doloc2 ≔ −5+−3+i1*i1+1*loc0/i1;loc0 ≔ loc1;loc1 ≔ loc2end do;loc1end proc
evalhf⁡p⁡100
5.27739153869639746×1076
If more precision is required, then evalf can be applied at each iteration using
p2:=rectoproc(rec,u(n),evalfun='evalf');
p2 ≔ procnlocali1,loc0,loc1,loc2;loc0 ≔ evalf⁡sin⁡1;loc1 ≔ evalf⁡cos⁡1;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc0elifn=1thenreturnloc1end if;fori1ton − 1doloc2 ≔ evalf⁡−5+−3+i1*i1+1*loc0/i1;loc0 ≔ loc1;loc1 ≔ loc2end do;loc1end proc
Digits≔30:p2⁡100
5.27739153869639769206242956896×1076
It is also possible to give the precision as an argument:
p3 := rectoproc(rec,u(n),evalfun='evalf',params=[d],postargs=[d]);
p3 ≔ procn,b1locali1,loc0,loc1,loc2;loc0 ≔ evalf⁡sin⁡1,b1;loc1 ≔ evalf⁡cos⁡1,b1;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc0elifn=1thenreturnloc1end if;fori1ton − 1doloc2 ≔ evalf⁡−5+−3+i1*i1+1*loc0/i1,b1;loc0 ≔ loc1;loc1 ≔ loc2end do;loc1end proc
p3⁡100,40
5.277391538696397692062429568990170086821×1076
Extra local variables
The option extralocal is useful when the values of some parameters are not known until the procedure is executed. In the example below, the recurrence is provided with generic initial conditions. The values of these initial conditions are computed at execution-time.
To create a procedure which computes and lists the first n terms of the recurrence, use the list option.
rec≔u⁡n⁢n+u⁡n+2,u⁡0=A,u⁡1=B:
rectoproc(rec,u(n),params=[p],extralocal=[A='f'(p),B='g'(A,p)]);
procn,b1locali1,loc0,loc1,loc2,xloc1,xloc2;xloc1 ≔ f⁡b1;xloc2 ≔ g⁡xloc1,b1;loc0 ≔ xloc1;loc1 ≔ xloc2;ifn<0thenerrorindex must be %1 or greater,0elifn=0thenreturnloc0elifn=1thenreturnloc1end if;fori1ton − 1doloc2 ≔ −i1 − 1*loc0;loc0 ≔ loc1;loc1 ≔ loc2end do;loc1end proc
See Also
procedure
Download Help Document