Changes http://wiki.axiom-developer.org/RecSpad/diff
--

??changed:
-This page was renamed to rec.spad.pamphlet. You can delete this one if no 
longer needed.
-
+Here is the source code 'rec.spad'
+
+\begin{spad}
+)abbrev package RECOP RecurrenceOperator
+++ Author: Martin Rubey
+++ Description:
+++ This package provides an operator for the n-th term of a recurrence and an
+++ operator for the coefficient of x^n in a function specified by a functional
+++ equation.
+RecurrenceOperator(R, F): Exports == Implementation where
+  R: Join(OrderedSet, IntegralDomain, ConvertibleTo InputForm)
+  F: Join(FunctionSpace R, AbelianMonoid, RetractableTo Integer, _
+          RetractableTo Symbol, PartialDifferentialRing Symbol)
+--RecurrenceOperator(F): Exports == Implementation where
+--  F: Join(ExpressionSpace, AbelianMonoid, RetractableTo Integer,
+--          RetractableTo Symbol, PartialDifferentialRing Symbol) 
+
+  Exports == with
+
+    evalRec: (BasicOperator, Symbol, F, F, F, List F) -> F
+      ++ \spad{evalRec(u, dummy, n, n0, eq, values)} creates an expression that
+      ++ stands for u(n0), where u(n) is given by the equation eq. However, for
+      ++ technical reasons the variable n has to be replaced by a dummy
+      ++ variable dummy in eq. The argument values specifies the initial values
+      ++ of the recurrence u(0), u(1),...
+      ++ For the moment we don't allow recursions that contain u inside of
+      ++ another operator.
+
+    evalADE: (BasicOperator, Symbol, F, F, F, List F) -> F
+      ++ \spad{evalADE(f, dummy, x, n, eq, values)} creates an expression that
+      ++ stands for the coefficient of x^n in f(x), where f(x) is given by the
+      ++ functional equation eq. However, for technical reasons the variable x
+      ++ has to be replaced by a dummy variable dummy in eq. The argument
+      ++ values specifies f(0), f'(0), f''(0),...
+
+-- should be local
+    numberOfValuesNeeded: (Integer, BasicOperator, Symbol, F) -> Integer
+
+-- should be local
+    if R has Ring then
+      getShiftRec: (BasicOperator, Kernel F, Symbol) -> Union(Integer, 
"failed")
+
+      shiftInfoRec: (BasicOperator, Symbol, F) -> 
+                     Record(max: Union(Integer, "failed"), 
+                            ord: Union(Integer, "failed"),
+                            ker: Kernel F)
+
+  Implementation == add
+
+    oprecur := operator("rootOfRec"::Symbol)$BasicOperator
+
+    opADE := operator("rootOfADE"::Symbol)$BasicOperator
+
+    setProperty(oprecur, "%dummyVar", 2 pretend None)
+    setProperty(opADE, "%dummyVar", 2 pretend None)
+
+-- this implies that the second and third arguments of oprecur are dummy
+-- variables and affects tower$ES:
+-- the second argument will not appear in tower$ES, if it does not appear in
+-- any argument but the first and second.
+-- the third argument will not appear in tower$ES, if it does not appear in any
+-- other argument. (%defsum is a good example)
+
+-- The arguments of these operators are as follows:
+
+-- 1. eq, i.e. the vanishing expression
+
+    eqAsF: List F -> F
+    eqAsF l == l.1
+  
+-- 2. dummy
+
+    dummy: List F -> Symbol
+    dummy l == retract(l.2)@Symbol
+
+    dummyAsF: List F -> F
+    dummyAsF l == l.2
+
+-- 3. variable, i.e., for display              
+
+    displayVariable: List F -> F
+    displayVariable l == l.3
+
+-- 4. operatorname(argument)
+
+    operatorName: List F -> BasicOperator
+    operatorName l == operator(kernels(l.4).1)
+
+    operatorNameAsF: List F -> F
+    operatorNameAsF l == l.4
+
+    operatorArgument: List F -> F
+    operatorArgument l == argument(kernels(l.4).1).1
+
+-- rootOfADE: note that although we have arg as argument of the operator, 
+--            it is intended to indicate the coefficient, not the argument 
+--            of the power series
+
+-- 5.- values in reversed order
+-- rootOfRec:
+-- maybe "values" should be preceded by the index of the first given
+-- value. Currently, the last value is interpreted as f(0)
+
+-- rootOfADE:
+-- values are the first few coefficients of the power series expansion in order
+
+    initialValues: List F -> List F
+    initialValues l == rest(l, 4)
+
+    if R has Ring then
+      getShiftRec(op: BasicOperator, f: Kernel F, n: Symbol)
+                 : Union(Integer, "failed") ==
+          a := argument f
+          if every?(freeOf?(#1, n::F), a) then return 0
+
+          if #a ~= 1 then error "RECOP: operator should have only one argument"
+
+          p := univariate(a.1, retract(n::F)@Kernel(F))
+          if denominator p ~= 1 then return "failed"
+          
+          num := numer p
+
+          if degree num = 1 and coefficient(num, 1) = 1
+             and every?(freeOf?(#1, n::F), coefficients num)
+          then return retractIfCan(coefficient(num, 0))
+          else return "failed"
+
+
+      shiftInfoRec(op: BasicOperator, argsym: Symbol, eq: F): 
+                   Record(max: Union(Integer, "failed"), 
+                          ord: Union(Integer, "failed"),
+                          ker: Kernel F) ==
+
+-- ord and ker are valid only if all shifts are Integers
+-- ker is the kernel of the maximal shift.
+        maxShift: Integer
+        minShift: Integer
+        nextKernel: Kernel F
+
+-- We consider only those kernels that have op as operator. If there is non, we
+-- raise an error. For the moment we don't allow recursions that contain op
+-- inside of another operator.
+
+        error? := true
+
+        for f in kernels eq repeat
+          if is?(f, op) then
+            shift := getShiftRec(op, f, argsym)
+            if error? then
+              error? := false
+              nextKernel := f
+              if shift case Integer then
+                maxShift := shift
+                minShift := shift
+              else return ["failed", "failed", nextKernel]
+            else
+              if shift case Integer then 
+                if maxShift < shift then
+                  maxShift := shift
+                  nextKernel := f
+                if minShift > shift then
+                  minShift := shift
+              else return ["failed", "failed", nextKernel]
+
+        if error? then error "evalRec: equation does not contain operator"
+
+        [maxShift, maxShift - minShift, nextKernel]
+
+-- try to evaluate:
+      evalRec(op, argsym, argdisp, arg, eq, values) == 
+        if ((n := retractIfCan(arg)@Union(Integer, "failed")) case "failed")
+           or (n < 0)
+        then
+          shiftInfo := shiftInfoRec(op, argsym, eq)
+
+          if (shiftInfo.ord case "failed") or ((shiftInfo.ord)::Integer > 0) 
+          then
+            kernel(oprecur, 
+                   append([eq, argsym::F, argdisp, op(arg)], values))
+          else
+            p := univariate(eq, shiftInfo.ker)
+            num := numer p
+            if degree num = 1 then
+              eval(-coefficient(num, 0)/coefficient(num, 1), argsym::F, arg::F)
+            else 
+              kernel(oprecur, 
+                     append([eq, argsym::F, argdisp, op(arg)], values))
+        else 
+          len: Integer := #values
+          if n < len
+          then values.(len-n)
+          else
+            shiftInfo := shiftInfoRec(op, argsym, eq)
+  
+            if shiftInfo.max case Integer then
+              p := univariate(eq, shiftInfo.ker)
+
+              num := numer p
+  
+[143 more lines...]

--
forwarded from http://wiki.axiom-developer.org/[EMAIL PROTECTED]

Reply via email to