def _eval_derivative(self, s): try: res = 0 if self.args[0].has(s) or self.args[1].has(s): for i, p in enumerate(self._diffargs): m = self._diffargs[i].diff(s) if m != 0: res += self.fdiff((1, i)) * m return res + self.fdiff(3) * self.args[2].diff(s) except (ArgumentIndexError, NotImplementedError): return Derivative(self, s)
def test_derivative_numerically(f, z, tol=1.0e-6, a=2, b=-1, c=3, d=1): """ Test numerically that the symbolically computed derivative of f with respect to z is correct. This routine does not test whether there are Floats present with precision higher than 15 digits so if there are, your results may not be what you expect due to round-off errors. Examples ======== >>> from diofant import sin >>> from diofant.abc import x >>> from diofant.utilities.randtest import test_derivative_numerically as td >>> td(sin(x), x) true """ from diofant.core.function import Derivative z0 = random_complex_number(a, b, c, d) f1 = f.diff(z).subs(z, z0) f2 = Derivative(f, z).doit_numerically(z0) return comp(f1.n(), f2.n(), tol)
def _eval_derivative(self, x): """ Differentiate wrt x as long as x is not in the free symbols of any of the upper or lower limits. Sum(a*b*x, (x, 1, a)) can be differentiated wrt x or b but not `a` since the value of the sum is discontinuous in `a`. In a case involving a limit variable, the unevaluated derivative is returned. """ # diff already confirmed that x is in the free symbols of self, but we # don't want to differentiate wrt any free symbol in the upper or lower # limits # XXX remove this test for free_symbols when the default _eval_derivative is in if x not in self.free_symbols: return S.Zero # get limits and the function f, limits = self.function, list(self.limits) limit = limits.pop(-1) if limits: # f is the argument to a Sum f = self.func(f, *limits) if len(limit) == 3: _, a, b = limit if x in a.free_symbols or x in b.free_symbols: return df = Derivative(f, x, evaluate=True) rv = self.func(df, limit) if limit[0] not in df.free_symbols: rv = rv.doit() return rv else: return NotImplementedError('Lower and upper bound expected.')
def test_del_operator(): # Tests for curl assert (delop ^ Vector.zero == (Derivative(0, C.y) - Derivative(0, C.z)) * C.i + (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j + (Derivative(0, C.x) - Derivative(0, C.y)) * C.k) assert ((delop ^ Vector.zero).doit() == Vector.zero == curl( Vector.zero, C)) assert delop.cross(Vector.zero) == delop ^ Vector.zero assert (delop ^ i).doit() == Vector.zero assert delop.cross(2 * y**2 * j, doit=True) == Vector.zero assert delop.cross(2 * y**2 * j) == delop ^ 2 * y**2 * j v = x * y * z * (i + j + k) assert ((delop ^ v).doit() == (-x * y + x * z) * i + (x * y - y * z) * j + (-x * z + y * z) * k == curl(v, C)) assert delop ^ v == delop.cross(v) assert (delop.cross( 2 * x**2 * j) == (Derivative(0, C.y) - Derivative(2 * C.x**2, C.z)) * C.i + (-Derivative(0, C.x) + Derivative(0, C.z)) * C.j + (-Derivative(0, C.y) + Derivative(2 * C.x**2, C.x)) * C.k) assert (delop.cross(2 * x**2 * j, doit=True) == 4 * x * k == curl( 2 * x**2 * j, C)) # Tests for divergence assert delop & Vector.zero == Integer(0) == divergence(Vector.zero, C) assert (delop & Vector.zero).doit() == Integer(0) assert delop.dot(Vector.zero) == delop & Vector.zero assert (delop & i).doit() == Integer(0) assert (delop & x**2 * i).doit() == 2 * x == divergence(x**2 * i, C) assert (delop.dot(v, doit=True) == x * y + y * z + z * x == divergence( v, C)) assert delop & v == delop.dot(v) assert delop.dot(1/(x*y*z) * (i + j + k), doit=True) == \ - 1 / (x*y*z**2) - 1 / (x*y**2*z) - 1 / (x**2*y*z) v = x * i + y * j + z * k assert (delop & v == Derivative(C.x, C.x) + Derivative(C.y, C.y) + Derivative(C.z, C.z)) assert delop.dot(v, doit=True) == 3 == divergence(v, C) assert delop & v == delop.dot(v) assert simplify((delop & v).doit()) == 3 # Tests for gradient assert (delop.gradient(0, doit=True) == Vector.zero == gradient(0, C)) assert delop.gradient(0) == delop(0) assert (delop(Integer(0))).doit() == Vector.zero assert (delop(x) == (Derivative(C.x, C.x)) * C.i + (Derivative(C.x, C.y)) * C.j + (Derivative(C.x, C.z)) * C.k) assert (delop(x)).doit() == i == gradient(x, C) assert (delop(x * y * z) == (Derivative(C.x * C.y * C.z, C.x)) * C.i + (Derivative(C.x * C.y * C.z, C.y)) * C.j + (Derivative(C.x * C.y * C.z, C.z)) * C.k) assert (delop.gradient(x * y * z, doit=True) == y * z * i + z * x * j + x * y * k == gradient(x * y * z, C)) assert delop(x * y * z) == delop.gradient(x * y * z) assert (delop(2 * x**2)).doit() == 4 * x * i assert ((delop(a * sin(y) / x)).doit() == -a * sin(y) / x**2 * i + a * cos(y) / x * j) # Tests for directional derivative assert (Vector.zero & delop)(a) == Integer(0) assert ((Vector.zero & delop)(a)).doit() == Integer(0) assert ((v & delop)(Vector.zero)).doit() == Vector.zero assert ((v & delop)(Integer(0))).doit() == Integer(0) assert ((i & delop)(x)).doit() == 1 assert ((j & delop)(y)).doit() == 1 assert ((k & delop)(z)).doit() == 1 assert ((i & delop)(x * y * z)).doit() == y * z assert ((v & delop)(x)).doit() == x assert ((v & delop)(x * y * z)).doit() == 3 * x * y * z assert (v & delop)(x + y + z) == C.x + C.y + C.z assert ((v & delop)(x + y + z)).doit() == x + y + z assert ((v & delop)(v)).doit() == v assert ((i & delop)(v)).doit() == i assert ((j & delop)(v)).doit() == j assert ((k & delop)(v)).doit() == k assert ((v & delop)(Vector.zero)).doit() == Vector.zero
def test_Function(): assert precedence(sin(x)) == PRECEDENCE["Atom"] assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"]
def test_core_function(): for f in (Derivative, Derivative(x), Function, FunctionClass, Lambda, WildFunction): check(f)
def test_Derivative(): assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"]
def diff(self, *symbols, **assumptions): new_symbols = list(map(sympify, symbols)) # e.g. x, 2, y, z assumptions.setdefault("evaluate", True) return Derivative(self, *new_symbols, **assumptions)