Q&A

# What do the number entries mean in the sympy poly.diff(...) tuple syntax?

+5
−1

I am looking to take a partial derivative of a sympy polynomial with respect to a symbol in the polynomial.

In the sympy documentation for poly.diff(...) it gives sample code like this:

``````from sympy import Poly
from sympy.abc import x, y

Poly(x*y**2 + x, x, y).diff((0, 0), (1, 1))
``````

There is no explanation I was able to find as to what the `(0, 0), (1, 1)` tuples refer to.

I'm really just trying to supplement the sympy documentation here, but here is my attempt at providing an MVCE for a question I already know the answer to:

``````from __future__ import print_function

from sympy import poly, symbols

from sympy.abc import x, y

base = poly(x*y**2 + x, x, y)
print('base function is', base)

# appears to be the same as doing diff(y)
deriv_mysterious1 = base.diff((0, 0), (1, 1))

print('deriv_mysterious1 is', deriv_mysterious1)

deriv_mysterious2 = base.diff(y)

print('deriv_mysterious2 is', deriv_mysterious2)

# same as base
deriv_mysterious3 = base.diff((0,0))
print('deriv_mysterious3 is', deriv_mysterious3)

# same as diff(y)
deriv_mysterious4 = base.diff((1,1))
print('deriv_mysterious4 is', deriv_mysterious4)

# same as diff(x)
deriv_mysterious5 = base.diff((0,1))
print('deriv_mysterious5 is', deriv_mysterious5)
``````

The output of which is

``````base function is Poly(x*y**2 + x, x, y, domain='ZZ')
deriv_mysterious1 is Poly(2*x*y, x, y, domain='ZZ')
deriv_mysterious2 is Poly(2*x*y, x, y, domain='ZZ')
deriv_mysterious3 is Poly(x*y**2 + x, x, y, domain='ZZ')
deriv_mysterious4 is Poly(2*x*y, x, y, domain='ZZ')
deriv_mysterious5 is Poly(y**2 + 1, x, y, domain='ZZ')
``````

How do I use this tuple syntax? What do these numbers refer to?

Why should this post be closed?

I don't really know how to interpret a downvote on this, if you found official documentation somewhere on this please link it. I had to piece this together from 5 or 6 random websites to figure it out. There's this but it has `diff(expr, <symbol>, <order>)` not `poly.diff((<mysterious symbol index>, <order>))`, and `poly.diff(...)` is not taking the partial derivative with respect to the number 0 or a symbol named 0. ‭jrh‭ 30 days ago

It's kinda funny how the "Run code block in SymPy Live" on the docs gives an error for that example ‭Moshi‭ 29 days ago

+4
−0

It appears that the tuple syntax works like this:

`(variable index, order of derivative)`

Where something like:

``````base = poly(x*y**2 + x, x, y)
deriv_mysterious5 = base.diff((0,1))
print('deriv_mysterious5 is', deriv_mysterious5)
``````

Means: "Take first derivative of `base` with respect to symbol[0]", in this case symbol 0 is x.

• I was not able to find information on how sympy determines which symbol is symbol 0.

I think I would recommend the alternative syntax instead:

``````base.diff(<symbol>)
``````

e.g.,

``````base.diff(x)
``````

Though, interestingly, it seems that for higher order derivatives, `poly.diff` has some behavior that seems to differ from `diff(expr,...)` as seen on the Calculus page.

This syntax works:

``````base.diff(y, y)
``````

I was not able to get this syntax working:

``````base.diff(y, 2)
``````

But a slightly modified version of this does work,

``````base.diff((y, 2))
``````

+3
−0

Based on the source code which delegates to this implementation among others, `base.diff((x, n))` means to compute the `n`-th derivative of `base` with respect to `x`. Any arguments to `diff` which aren't tuples get tupled with 1, e.g. `base.diff(x)` is more or less equivalent to `base.diff((x, 1))`. Multiple arguments essentially correspond to repeated differentiation, e.g. `base.diff((x, m), (y, n))` is more or less the same as `base.diff((x, m).diff((y, n))`.

Numeric arguments are indexes into the array of generators provided when the polynomial was created. That is, if `base` is defined by `Poly(..., x, y)`, then `base.diff((0, n))` and `base.diff((x, n))` are more or less the same. Similarly, `base.diff((1, n))` and `base.diff((y, n))`. This is handled by the method _gen_to_level. That method also allows negative numbers to index backwards into the array of generators, i.e. `base.diff((-1, n))` is also equivalent to `base.diff((y, n))`.

The example from the other answer of `base.diff(y, 2)` gets interpreted as `base.diff((y, 1), (2, 1))`, however, since there is only 2 generators (`x` and `y`), this should lead to an exception being thrown in `_gen_to_level` as 2 is not a valid index into the array of generators.

That said, the example in the documentation is rather cryptic, and it is a bit bizarre to have `base.diff((0,0))` which would mean "take the 0-th derivative of the first generator" which is well-defined but corresponds to doing nothing.

#### 1 comment

This is a useful answer but readers should note that generally implementation is not a strong of a source as documentation, and could in theory change at any time. Though to be fair I think this implementation is likely to stick and I doubt they would change the meaning of the parameters. I wasn't able to find any official answer to this question at all in the documentation (other than what I linked), and this is probably the best we're going to get. ‭jrh‭ 26 days ago

This site is part of the Codidact network. We have other sites too — take a look!