Ask Your Question
2

How to implement 'derivative' in ExpressionTreeWalker

asked 2020-09-27 17:59:48 -0500

Edgar Brown gravatar image

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?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
2

answered 2020-09-28 10:59:20 -0500

tmonteil gravatar image

updated 2020-09-28 11:00:00 -0500

What if you replace

r = operator(*map(self, ex.operands()))

with

r = op(*map(self, ex.operands()))

operator is a module, here you might want to refer to the op parameter of the method derivative.

edit flag offensive delete link more

Comments

Yes!! That works. Thanks!!

Edgar Brown gravatar imageEdgar Brown ( 2020-09-28 14:31:22 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2020-09-27 17:59:48 -0500

Seen: 89 times

Last updated: Sep 28