2

I have a function

Multivariate function that I want to simplify and differentiate in Python, defined as**

def u(x, t):
    return math.erf((x + 1) / (2 * (k * t) ** (1 / 2)))

** Please correct me if I am wrong.

I have all the necessary imports as follows:

import math
import scipy
import matplotlib
from sympy import *

As well as defining the symbols

x, k, t = symbols('x k t')

This works perfectly fine:

def f(x):
     return x ** 4

diff(f(x))

Which returns the correct answer,

4x^3

However, this

diff(u(x, t))

or this

diff(u(x, t), t)

returns an error as follows

TypeError Traceback (most recent call last) in () ----> 1 diff(u(x, t))

in u(x, t) 1 def u(x, t): ----> 2 return math.erf((x + 1) / (2 * (k * t) ** (1 / 2)))

C:\Anaconda\lib\site-packages\sympy\core\expr.py in float(self) 223 if result.is_number and result.as_real_imag()1: 224 raise TypeError("can't convert complex to float") --> 225 raise TypeError("can't convert expression to float") 226 227 def complex(self):

TypeError: can't convert expression to float

In Matlab I could easily do it:

syms x;
syms k;
syms t;
u = erf((x + 1)/(2 * sqrt(k * t)));
LHS = simplify(diff(u, t))
RHS = k * simplify(diff(u, x, 2))

My question is, how can I differentiate and/or simplify a mathematical function of more than one variable in Python?

AnonymousAngelo
  • 996
  • 3
  • 15
  • 37
  • 3
    Did you read [this documentation](http://docs.sympy.org/dev/tutorial/calculus.html#derivatives)? – BrenBarn Aug 28 '15 at 18:19
  • Yes, I have read the SymPy documentation, however I am not sure how the syntax works regarding the following: `expr = exp(x*y*z)` `diff(expr, x, y, y, z, z, z, z)` – AnonymousAngelo Aug 28 '15 at 18:35
  • Also, if I define my own function as such `expr = math.erf((x + 1) / (2 * (k * t) ** (1 / 2)))` and attempt to differentiate with respect to t `diff(expr, t)` I get an error. – AnonymousAngelo Aug 28 '15 at 18:37

2 Answers2

3

Use sympy like this:

>>> from sympy import symbols, diff
>>> x, y = symbols('x y', real=True)
>>> diff( x**2 + y**3, y)
3*y**2
>>> diff( x**2 + y**3, y).subs({x:3, y:1})
3

You have to specify which variable you're differentiating with respect to.

cadams
  • 1,299
  • 1
  • 11
  • 21
  • I do import `from sympy import *`. Also, `diff(u(x, t), t)` also returns an error. – AnonymousAngelo Aug 28 '15 at 18:25
  • 2
    I think the issue may be with the constant `k`. I am not sure how that can be resolved, I would consult the documentation @BrenBarn provided. – cadams Aug 28 '15 at 18:26
  • 3
    OH! I think your issue may be caused by using `k` as a symbol. Try removing it from your symbol list. – cadams Aug 28 '15 at 18:29
  • `x, t = symbols('x t')` followed by `diff(u(x, t), t)` still returns an error :/ Also, keep in mind I am trying to differentiate symbolically, so even though `k` is a constant, I think it still counts as a 'symbol' in Python. I tested in Matlab, and removing `syms k;` does not make a difference. – AnonymousAngelo Aug 28 '15 at 18:38
  • 1
    @EfVonZee: Did you redefine `u` after doing that (if you're doing this interactively)? – BrenBarn Aug 28 '15 at 18:40
  • @BrenBarn, yes I did. – AnonymousAngelo Aug 28 '15 at 18:41
3

You need to use sympy.erf, not math.erf:

>>> import sympy
>>> x, k, t = sympy.symbols('x k t')
>>> def u(x, t):
...     return sympy.erf((x + 1) / (2 * (k * t) ** (1 / 2)))
>>> sympy.diff(u(x, t), x, t)
(0.25*(k*t)**(-1.5)*(x + 1)**2 - 0.5*(k*t)**(-0.5))*exp(-(k*t)**(-1.0)*(x + 1)**2/4)/(sqrt(pi)*t)
BrenBarn
  • 242,874
  • 37
  • 412
  • 384
  • I don't get an error anymore! Thank you so much! However, my answer returns as 0. How did you import `sympy` and define the symbols? – AnonymousAngelo Aug 28 '15 at 18:48
  • 1
    I just did `import sympy` and then your same `x, k, t = symbols('x k t')`. – BrenBarn Aug 28 '15 at 18:49
  • mine still returns 0. I have no idea why. `import sympy x, k, t = symbols('x k t') def u(x, t): return sympy.erf((x + 1) / (2 * (k * t) ** (1 / 2))) sympy.diff(u(x, t), x, t)` – AnonymousAngelo Aug 28 '15 at 18:51
  • @EfVonZee: That is strange. I edited my answer to show my complete interpreter session. Are you saying if you run that exact code in a newly-started interpreter, you get 0 at the end? – BrenBarn Aug 28 '15 at 18:53
  • @EfVonZee: That's pretty baffling. But just to double-check. . . you're running it in a brand-new interpreter session, with no other code before or after it? If that's the case it's hard to know what could be going on. – BrenBarn Aug 28 '15 at 18:58
  • @EfVonZee: That's doesn't look like it's in a fresh interpreter session, because it says `In [206]:`. Try restarting your Python session and then trying it. – BrenBarn Aug 28 '15 at 19:01
  • [link](http://i62.tinypic.com/k1yw55.jpg) I've tried it directly in terminal running `python` as well. – AnonymousAngelo Aug 28 '15 at 19:06
  • 2
    @EfVonZee: Oh, I bet it's because of the `1/2`. Try adding `from __future__ import division` to the top of the code. – BrenBarn Aug 28 '15 at 19:08
  • 1
    You are my hero. Thank you so much! – AnonymousAngelo Aug 28 '15 at 19:10