Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

How to implement 'derivative' in ExpressionTreeWalker

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?

click to hide/show revision 2
retagged

How to implement 'derivative' in ExpressionTreeWalker

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?