Waldek Hebisch <[EMAIL PROTECTED]> writes:
> > below is a patch that has the behaviour as you described it, with the
> > exception
> > of polygamma, which now throws an error. If you prefer that polygamma also
> > allows differentiation with respect to the first argument, the change is
> > trivial. I don't have time to modify sttaylor right now.
> >
>
> I tried the patch and I see a problem.
Wow! I love your scrutinity! Could you add this as a test, maybe? Here is a
better patch.
Index: combfunc.spad.pamphlet
===================================================================
--- combfunc.spad.pamphlet (revision 580)
+++ combfunc.spad.pamphlet (working copy)
@@ -41,11 +41,6 @@
++ formal product;
@
-The latest change allows Axiom to reduce
-\begin{verbatim}
- sum(1/i,i=1..n)-sum(1/i,i=1..n)
-\end{verbatim}
-to reduce to zero.
<<package COMBF CombinatorialFunction>>=
)abbrev package COMBF CombinatorialFunction
++ Provides the usual combinatorial functions
@@ -690,6 +685,7 @@
OP ==> BasicOperator
K ==> Kernel F
SE ==> Symbol
+ SPECIALDIFF ==> "%specialDiff"
Exports ==> with
belong? : OP -> Boolean
@@ -818,29 +814,90 @@
-- Default behaviour is to build a kernel
evaluate(opGamma, iiGamma)$BasicOperatorFunctions1(F)
evaluate(opabs, iiabs)$BasicOperatorFunctions1(F)
+@
+\subsection{differentiation of special functions}
+
+In the following we define the symbolic derivatives of the special functions we
+provide. The formulas we use for the Bessel functions can be found in Milton
+Abramowitz and Irene A. Stegun, eds. (1965). Handbook of Mathematical
+Functions with Formulas, Graphs, and Mathematical Tables. New York: Dover. ISBN
+0-486-61272-4, Equations~9.1.27 and 9.6.26. Up to [[patch--50]] the formula
+for $K$ missed the minus sign. (Issue~\#355)
+
+We do not attempt to provide formulas for the derivative with respect to the
+first argument currently. Instead, we leave such derivatives unevaluated.
+
+<<package FSPECF FunctionalSpecialFunction>>=
import Fraction Integer
ahalf: F := recip(2::F)::F
athird: F := recip(2::F)::F
twothirds: F := 2*recip(3::F)::F
+@
- lzero(l: List F): F == 0
+We need to get hold of the differentiation operator as modified by
+[[FunctionSpace]]. Otherwise, for example, display will be ugly. We accomplish
+that by differentiating an operator, which will certainly result in a single
+kernel only.
- iBesselJGrad(l: List F): F ==
+<<package FSPECF FunctionalSpecialFunction>>=
+ dummyArg: SE := new()$SE
+ opdiff := operator first kernels D((operator(new()$SE)$BasicOperator)
+ (dummyArg::F), dummyArg)
+@
+
+The differentiation operator [[opdiff]] takes three arguments corresponding to
+$$
+F_{,i}(a_1,a_2,\dots,a_n):
+$$
+\begin{enumerate}
+\item $F(a_1,...,dm,...a_n)$, where the $i$\textsuperscript{th} argument is a
+ dummy variable,
+\item $dm$, the dummy variable, and
+\item $a_i$, the point at which the differential is evaluated.
+\end{enumerate}
+
+In the following, it seems to be safe to use the same dummy variable
+troughout. At least, this is done also in [[FunctionSpace]], and did not cause
+problems.
+
+The operation [[symbolicGrad]] returns the first component of the gradient of
+[[op l]].
+
+<<package FSPECF FunctionalSpecialFunction>>=
+ dm := new()$SE :: F
+
+ iBesselJ(l: List F, t: SE): F ==
n := first l; x := second l
- ahalf * (besselJ (n-1,x) - besselJ (n+1,x))
- iBesselYGrad(l: List F): F ==
+ differentiate(n, t)*kernel(opdiff, [opBesselJ [dm, x], dm, n])
+ + differentiate(x, t) * ahalf * (besselJ (n-1,x) - besselJ (n+1,x))
+
+ iBesselY(l: List F, t: SE): F ==
n := first l; x := second l
- ahalf * (besselY (n-1,x) - besselY (n+1,x))
- iBesselIGrad(l: List F): F ==
+ differentiate(n, t)*kernel(opdiff, [opBesselY [dm, x], dm, n])
+ + differentiate(x, t) * ahalf * (besselY (n-1,x) - besselY (n+1,x))
+
+ iBesselI(l: List F, t: SE): F ==
n := first l; x := second l
- ahalf * (besselI (n-1,x) + besselI (n+1,x))
- iBesselKGrad(l: List F): F ==
+ differentiate(n, t)*kernel(opdiff, [opBesselI [dm, x], dm, n])
+ + differentiate(x, t)* ahalf * (besselI (n-1,x) + besselI (n+1,x))
+
+ iBesselK(l: List F, t: SE): F ==
n := first l; x := second l
- ahalf * (besselK (n-1,x) + besselK (n+1,x))
- ipolygammaGrad(l: List F): F ==
- n := first l; x := second l
- polygamma(n+1, x)
+ differentiate(n, t)*kernel(opdiff, [opBesselK [dm, x], dm, n])
+ - differentiate(x, t)* ahalf * (besselK (n-1,x) + besselK (n+1,x))
+
+@
+
+For the moment we throw an error if we try to differentiate [[polygamma]] with
+respect to the first argument.
+
+<<package FSPECF FunctionalSpecialFunction>>=
+ ipolygamma(l: List F, x: SE): F ==
+ member?(x, variables first l) =>
+ error "cannot differentiate polygamma with respect to the first argument"
+ n := first l; y := second l
+ differentiate(y, x)*polygamma(n+1, y)
iBetaGrad1(l: List F): F ==
x := first l; y := second l
Beta(x,y)*(digamma x - digamma(x+y))
@@ -849,20 +906,36 @@
Beta(x,y)*(digamma y - digamma(x+y))
if F has ElementaryFunctionCategory then
- iGamma2Grad(l: List F):F ==
+ iGamma2(l: List F, t: SE): F ==
a := first l; x := second l
- - x ** (a - 1) * exp(-x)
- derivative(opGamma2, [lzero, iGamma2Grad])
+ differentiate(a, t)*kernel(opdiff, [opGamma2 [dm, x], dm, a])
+ - differentiate(x, t)* x ** (a - 1) * exp(-x)
+ setProperty(opGamma2, SPECIALDIFF, iGamma2@((List F, SE)->F)
+ pretend None)
+@
+Finally, we tell Axiom to use these functions for differentiation. Note that
+up to [[patch--50]], the properties for the Bessel functions were set using
+[[derivative(oppolygamma, [lzero, ipolygammaGrad])]], where [[lzero]] returned
+zero always. Trying to replace [[lzero]] by a function that returns the first
+component of the gradient failed, it resulted in an infinit loop for
+[[integrate(D(besselJ(a,x),a),a)]].
+
+<<package FSPECF FunctionalSpecialFunction>>=
derivative(opabs, abs(#1) * inv(#1))
derivative(opGamma, digamma #1 * Gamma #1)
derivative(opBeta, [iBetaGrad1, iBetaGrad2])
derivative(opdigamma, polygamma(1, #1))
- derivative(oppolygamma, [lzero, ipolygammaGrad])
- derivative(opBesselJ, [lzero, iBesselJGrad])
- derivative(opBesselY, [lzero, iBesselYGrad])
- derivative(opBesselI, [lzero, iBesselIGrad])
- derivative(opBesselK, [lzero, iBesselKGrad])
+ setProperty(oppolygamma, SPECIALDIFF, ipolygamma@((List F, SE)->F)
+ pretend None)
+ setProperty(opBesselJ, SPECIALDIFF, iBesselJ@((List F, SE)->F)
+ pretend None)
+ setProperty(opBesselY, SPECIALDIFF, iBesselY@((List F, SE)->F)
+ pretend None)
+ setProperty(opBesselI, SPECIALDIFF, iBesselI@((List F, SE)->F)
+ pretend None)
+ setProperty(opBesselK, SPECIALDIFF, iBesselK@((List F, SE)->F)
+ pretend None)
@
\section{package SUMFS FunctionSpaceSum}
Martin
_______________________________________________
Axiom-developer mailing list
[email protected]
http://lists.nongnu.org/mailman/listinfo/axiom-developer