I am trying to implement a method that requires traversing the expression tree. I have no problem with arithmetic functions, but I can't figure out how to deal with derivatives. Take this simple implementation for example:
sage: from sage.symbolic.expression_conversions import ExpressionTreeWalker
....: class ShowTree(ExpressionTreeWalker):
....: def __init__(self, ring):
....: self.ring = ring
....: def arithmetic(self, ex, op):
....: r = reduce(op, map(self, ex.operands()))
....: print(['>>',ex, ex.operands(),op])
....: return r
....: def derivative(self, ex, op):
....: r = operator(*map(self, ex.operands()))
....: print(['d>>',ex, ex.operands(),op])
....: return r
If you run it in the following:
var("a,b,x")
f = function('f')(x)
ShowTree(SR)(a*b+b*f(x).diff(x,2))
The following error occurs:
['>>', a*b, [a, b], <function mul_vararg at 0x34863e8c8>]
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
....
<ipython-input-217-df4a3880d6a1> in derivative(self, ex, op)
8 return r
9 def derivative(self, ex, op):
---> 10 r = operator(*map(self, ex.operands()))
11 print(['d>>',ex, ex.operands(),op])
12 return r
TypeError: 'module' object is not callable
If that line is changed to:
r = reduce(op,map(self, ex.operands()))
The result becomes:
(a, b, x)
['>>', a*b, [a, b], <function mul_vararg at 0x342dacbf8>]
['d>>', diff(f(x), x, x), [x], D[0, 0](f)]
['>>', b*diff(f(x), x, x), [b, diff(f(x), x, x)], <function mul_vararg at 0x342dacbf8>]
['>>', a*b + b*diff(f(x), x, x), [a*b, b*diff(f(x), x, x)], <function add_vararg at 0x342dacb70>]
a*b + b*x
That is the derivative operator is removed and substituted for the argument of the operator.
ExpressionTreeWalker is poorly documented at best, and I can't figure out what is expected as a return value from the derivative method (my first attempt comes from looking at the existing implementation). What am I missing?