Skip to content

Commit d527738

Browse files
committed
symengine_wrapper.pyx: Calculate the zero-th derivative
This is useful for more general, albeit sometimes inefficient, summation code. Just copying some taylor expansion code from the internet worked with sympy but not symengine due to the following error: Traceback (most recent call last): File "example.py", line 32, in <module> taylor(symengine.sympify('1/(1-x-x^2)'), 0, 15) File "example.py", line 27, in taylor p = p + (function.diff(x, i).subs(x, x0))/(factorial(i))*(x - x0)**i File "symengine_wrapper.pyx", line 923, in symengine.lib.symengine_wrapper.Basic.diff File "symengine_wrapper.pyx", line 4020, in symengine.lib.symengine_wrapper.diff OverflowError: can't convert negative value to size_t There are a number of inconsistencies compared to the regular sympy library: 1. Takes no argument: >>> symengine.sympify('x**2').diff() 2*x This actually seems helpful, except when you have #2 misleading you. This is not accepted in sympy, but doesn't necessarily need a fix. 2. Takes a standalone integer argument and returns a nonsense answer: >>> symengine.sympify('x**2').diff(1) x**2 This is simply not accepted in the regular sympy library. 3. Takes multiple integer arguments and aggregates: diff(x, 1, 1) == diff(x, 2) This does not occur with the sympy library, and does not seem useful. It can easily be replaced with diff(x, x), if repetition was necessary. 4. Takes only integer arguments > 1: diff(x, 0) returns integer overflow This is accepted in sympy. In this patch, 2-4 are all fixed. #1 seems like a potentially useful (and likely used) feature. Signed-off-by: Garming Sam <[email protected]>
1 parent b209fde commit d527738

File tree

1 file changed

+42
-5
lines changed

1 file changed

+42
-5
lines changed

symengine/lib/symengine_wrapper.pyx

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4056,18 +4056,55 @@ atexit.register(module_cleanup)
40564056

40574057
def diff(ex, *args):
40584058
ex = sympify(ex)
4059-
prev = 0
4059+
prev = None
40604060
cdef Basic b
40614061
cdef size_t i
4062-
for x in args:
4062+
length = len(args)
4063+
4064+
if not length:
4065+
return ex
4066+
4067+
l = 0
4068+
x = args[l]
4069+
b = sympify(x)
4070+
l += 1
4071+
4072+
while l <= length:
4073+
# Assume symbol 'x' or 'y' currently in b
4074+
# Pointer to next arg l is either derivative order or a separate symbol
4075+
4076+
prev = b
4077+
4078+
if l == length:
4079+
# No next argument, differentiate with no integer argument
4080+
if isinstance(b, Integer):
4081+
raise ValueError("Unexpected integer argument")
4082+
ex = ex._diff(b)
4083+
break
4084+
4085+
x = args[l]
40634086
b = sympify(x)
4087+
# Check if the next arg was derivative order
40644088
if isinstance(b, Integer):
4065-
i = int(b) - 1
4089+
i = int(b)
40664090
for j in range(i):
40674091
ex = ex._diff(prev)
4092+
4093+
# Move forward to point at next symbol
4094+
l += 1
4095+
if l == length:
4096+
break
4097+
4098+
x = args[l]
4099+
b = sympify(x)
4100+
if isinstance(b, Integer):
4101+
raise ValueError("Unexpected double integer argument")
40684102
else:
4069-
ex = ex._diff(b)
4070-
prev = b
4103+
# Separate symbol and no derivative order, differentiate now
4104+
ex = ex._diff(prev)
4105+
4106+
l += 1
4107+
40714108
return ex
40724109

40734110
def expand(x, deep=True):

0 commit comments

Comments
 (0)