0
from sympy.parsing.sympy_parser import parse_expr
import sympy as sp

def differentiate(exp, n):
    parse = parse_expr(exp)
    diff = sp.diff(parse, 'x' , n)
    answer = sp.expand(diff)
    return answer
print(differentiate("x**5 + 4*x**4 + 3*x**2 + 5", 3))
print(differentiate("x**2", 1))
print(differentiate('sin(x)', 3))

My code looks like this, and I get the expected output below.

60*x**2 + 96*x
2*x
-cos(x)

But if I test this:

print(differentiate("z**5 + 4*z**4 + 3*z**2 + 5", 3))

print(differentiate("z**2", 1))
print(differentiate('sin(z)', 3))

These outputs become 0, what should I do for this if I want a random letter to do differentiation?

Alper Kucukkomurler
  • 1,706
  • 2
  • 13
  • 19
  • Oh,I'm sorry. The original outputs are 60*x**2 + 96*x, 2*x, -cos(x) respectively. But when I change 'x' to 'z'. They all become 0. – Chen Jeremiah May 22 '20 at 13:22
  • Well, yes. The partial derivative of a function in z, with respect to x, is zero. What's unexpected? – Karl Knechtel May 22 '20 at 13:35
  • Eh, what should I do if I want to get the same results but different letters in this situation? – Chen Jeremiah May 22 '20 at 13:38
  • Well, what do you think the `'x'` is for in `diff = sp.diff(parse, 'x' , n)`? – Karl Knechtel May 22 '20 at 13:38
  • Yeah, this is my question. I found If I input 26 letters here(because I want a random letter to do differentiation), it will be an error when I debug or run it. I also tried '[a-zA-Z]+' here, but It doesn't work... I'm confusing where the problem is. – Chen Jeremiah May 22 '20 at 13:45

2 Answers2

0

You can use .diff() with no arguments to differentiate wrt a single free symbol:

In [4]: x = Symbol('x')                                                                                                           

In [5]: cos(x).diff()                                                                                                             
Out[5]: -sin(x)

In [6]: S(1).diff()                                                                                                               
Out[6]: 0

If there are multiple free symbols then this will fail:

In [7]: y = Symbol('y')                                                                                                           

In [8]: (x*y).diff()                                                                                                              
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-8-0d2ee58d5fd8> in <module>
----> 1 (x*y).diff()

~/current/sympy/sympy/sympy/core/expr.py in diff(self, *symbols, **assumptions)
   3350     def diff(self, *symbols, **assumptions):
   3351         assumptions.setdefault("evaluate", True)
-> 3352         return Derivative(self, *symbols, **assumptions)
   3353 
   3354     ###########################################################################

~/current/sympy/sympy/sympy/core/function.py in __new__(cls, expr, *variables, **kwargs)
   1262                         to differentiate %s''' % expr))
   1263                 else:
-> 1264                     raise ValueError(filldedent('''
   1265                         Since there is more than one variable in the
   1266                         expression, the variable(s) of differentiation

ValueError: 
Since there is more than one variable in the expression, the
variable(s) of differentiation must be supplied to differentiate x*y
Oscar Benjamin
  • 12,649
  • 1
  • 12
  • 14
0

If your expression is univariate and you want to differentiate once, then Oscar has given the solution. If it is univariate and you want to differentiate an arbitrary number of times (the n of your function) then you should find the free symbol first and then use it to differentiate:

def differentiate(exp, n):
  parse = parse_expr(exp)
  free = parse.free_symbols    #
  assert len(free) == 1        # x is identified
  x = free.pop()               # as the single free symbol
  diff = sp.diff(parse, x , n) #
  answer = sp.expand(diff)
  return answer

If you want to handle multivariate expressions, your function will either have to pick a random free symbol, e.g. random.choice(free), or accept that as a function input.

smichr
  • 16,948
  • 2
  • 27
  • 34