Question

I would like to compute derivative of y=Abs(0.5-0.5*sqrt(1-4*x)) in 0.1, using python. This is my code:

x=Symbol('x')
y=Abs(0.5-0.5*sqrt(1-4*x))
deriv=y.diff(x)
d=lambdify(x,deriv,'numpy')
print d(0.1)

This is what I get:

Traceback (most recent call last):
  File "/home/milossimic/g4/s1/.../optimize.py", line 100, in <module>
    print d(0.1)
  File "<string>", line 1, in <lambda>
NameError: global name 'Derivative' is not defined

I'm a newbie to sympy and numpy, so I guess I'm using the wrong method to determine derivative.

EDIT: I printed deriv and this is what I got:

enter image description here

After reading this http://docs.sympy.org/dev/modules/functions/elementary.html, I've tried fdiff():

x=Symbol('x')
y=Abs(0.5-0.5*sqrt(1-4*x))
deriv=y.fdiff()
d=lambdify(x,deriv,'numpy')
print d(0)

But after experimenting with other values to compute derivative, I figured out that the result is -1, 0 or 1 because deriv is actually sign(-0.5*sqrt(-4*x + 1) + 0.5).

What should I do?

Both numpy and sympy are imported:

from sympy import *
import numpy as np

If I try to find derivative of a function that is not under Abs, there are no problems.

Était-ce utile?

La solution 2

You probably just want the derivative of Abs to be sign. SymPy does do this, but only if it can deduce that the argument to the absolute value is real, which it can't in this case (even if x is real).

You can make your own custom version of Abs that always uses sign pretty easily by subclassing and overriding the _eval_derivative method:

class MyAbs(Abs):
    def _eval_derivative(self, x):
        return Derivative(self.args[0], x, evaluate=True)*sign(conjugate(self.args[0]))

.

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

In [111]: y = MyAbs(0.5-0.5*sqrt(1-4*x))

In [112]: deriv = y.diff(x)

In [113]: print(deriv)
1.0*sign(-0.5*conjugate(sqrt(-4*x + 1)) + 0.5)/sqrt(-4*x + 1)

In [114]: lambdify(x, deriv, 'numpy')(0.1)
Out[114]: 1.29099444874

Autres conseils

This is more a mathematical problem than anything else.

>>> import sympy
>>> x = sympy.symbols('x')
>>> def f(x):
...  return abs(x)
... 
>>> dx = f(x).diff(x)
>>> dx
(re(x)*Derivative(re(x), x) + im(x)*Derivative(im(x), x))/Abs(x)

Notice there is a real part and an imaginary part. abs(x) is differentiable at every real x, but zero. However, there are issues when it comes to complex values (which I can't explain since I don't know complex differentiation). I guess sympy doesn't have an implementation for that, and thus returns Derivative(f) instead of the actual derivative of f.

If you're working only with real numbers, then just use x = sympy.symbols('x', real=True):

>>> import sympy
>>> x = sympy.symbols('x', real=True)
>>> def f(x):
...  return abs(0.5-0.5*(1-4*x)**0.5)
... 
>>> dx = f(x).diff(x)
>>> dx
(1.0*(-0.5*re((-4*x + 1)**0.5) + 0.5)*re((-4*x + 1)**(-0.5)) - 0.5*im((-4*x + 1)**(-0.5))*im((-4*x + 1)**0.5))/Abs(-0.5*(-4*x + 1)**0.5 + 0.5)
>>> dx_ = sympy.lambdify(x, dx)
>>> dx_(0.1)
1.2909944487358056
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top