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 None 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 cross(self, vect, doit=False): """ Represents the cross product between this operator and a given vector - equal to the curl of the vector field. Parameters ========== vect : Vector The vector whose curl is to be calculated. doit : bool If True, the result is returned after calling .doit() on each component. Else, the returned expression contains Derivative instances Examples ======== >>> from sympy.vector import CoordSysCartesian >>> C = CoordSysCartesian('C') >>> v = C.x*C.y*C.z * (C.i + C.j + C.k) >>> C.delop.cross(v, doit = True) (-C.x*C.y + C.x*C.z)*C.i + (C.x*C.y - C.y*C.z)*C.j + (-C.x*C.z + C.y*C.z)*C.k >>> (C.delop ^ C.i).doit() 0 """ vectx = express(vect.dot(self._i), self.system, variables=True) vecty = express(vect.dot(self._j), self.system, variables=True) vectz = express(vect.dot(self._k), self.system, variables=True) outvec = Vector.zero outvec += (Derivative(vectz, self._y) - Derivative(vecty, self._z)) * self._i outvec += (Derivative(vectx, self._z) - Derivative(vectz, self._x)) * self._j outvec += (Derivative(vecty, self._x) - Derivative(vectx, self._y)) * self._k if doit: return outvec.doit() return outvec
def test_sympy__physics__quantum__operator__DifferentialOperator(): from sympy.physics.quantum.operator import DifferentialOperator from sympy import Derivative, Function f = Function('f') assert _test_args(DifferentialOperator(1 / x * Derivative(f(x), x), f(x)))
def _eval_derivative(self, x): if x.is_real or self.args[0].is_real: return im(Derivative(self.args[0], x, **{'evaluate': True})) if x.is_imaginary or self.args[0].is_imaginary: return -S.ImaginaryUnit \ * re(Derivative(self.args[0], x, **{'evaluate': True}))
def test_Derivative_kind(): A = MatrixSymbol('A', 2, 2) assert Derivative(comm_x, comm_x).kind is NumberKind assert Derivative(A, comm_x).kind is MatrixKind(NumberKind)
def _eval_derivative(self, x): if x.is_real: return conjugate(Derivative(self.args[0], x, evaluate=True)) elif x.is_imaginary: return -conjugate(Derivative(self.args[0], x, evaluate=True))
def test_Derivative(): assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"]
def unreplace(eq, var): return eq.replace(diffx, lambda e: Derivative(e, var))
def test_core_function(): x = Symbol("x") for f in (Derivative, Derivative(x), Function, FunctionClass, Lambda, WildFunction): check(f)
def test_jacobi(): n = Symbol("n") a = Symbol("a") b = Symbol("b") assert jacobi(0, a, b, x) == 1 assert jacobi(1, a, b, x) == a / 2 - b / 2 + x * (a / 2 + b / 2 + 1) assert jacobi(n, a, a, x) == RisingFactorial(a + 1, n) * gegenbauer( n, a + S.Half, x) / RisingFactorial(2 * a + 1, n) assert jacobi(n, a, -a, x) == ((-1)**a * (-x + 1)**(-a / 2) * (x + 1)**(a / 2) * assoc_legendre(n, a, x) * factorial(-a + n) * gamma(a + n + 1) / (factorial(a + n) * gamma(n + 1))) assert jacobi(n, -b, b, x) == ((-x + 1)**(b / 2) * (x + 1)**(-b / 2) * assoc_legendre(n, b, x) * gamma(-b + n + 1) / gamma(n + 1)) assert jacobi(n, 0, 0, x) == legendre(n, x) assert jacobi(n, S.Half, S.Half, x) == RisingFactorial(Rational( 3, 2), n) * chebyshevu(n, x) / factorial(n + 1) assert jacobi( n, Rational(-1, 2), Rational(-1, 2), x) == RisingFactorial(S.Half, n) * chebyshevt(n, x) / factorial(n) X = jacobi(n, a, b, x) assert isinstance(X, jacobi) assert jacobi(n, a, b, -x) == (-1)**n * jacobi(n, b, a, x) assert jacobi(n, a, b, 0) == 2**(-n) * gamma(a + n + 1) * hyper( (-b - n, -n), (a + 1, ), -1) / (factorial(n) * gamma(a + 1)) assert jacobi(n, a, b, 1) == RisingFactorial(a + 1, n) / factorial(n) m = Symbol("m", positive=True) assert jacobi(m, a, b, oo) == oo * RisingFactorial(a + b + m + 1, m) assert unchanged(jacobi, n, a, b, oo) assert conjugate(jacobi(m, a, b, x)) == \ jacobi(m, conjugate(a), conjugate(b), conjugate(x)) _k = Dummy('k') assert diff(jacobi(n, a, b, x), n) == Derivative(jacobi(n, a, b, x), n) assert diff(jacobi(n, a, b, x), a).dummy_eq( Sum((jacobi(n, a, b, x) + (2 * _k + a + b + 1) * RisingFactorial(_k + b + 1, -_k + n) * jacobi(_k, a, b, x) / ((-_k + n) * RisingFactorial(_k + a + b + 1, -_k + n))) / (_k + a + b + n + 1), (_k, 0, n - 1))) assert diff(jacobi(n, a, b, x), b).dummy_eq( Sum(((-1)**(-_k + n) * (2 * _k + a + b + 1) * RisingFactorial(_k + a + 1, -_k + n) * jacobi(_k, a, b, x) / ((-_k + n) * RisingFactorial(_k + a + b + 1, -_k + n)) + jacobi(n, a, b, x)) / (_k + a + b + n + 1), (_k, 0, n - 1))) assert diff(jacobi(n, a, b, x), x) == \ (a/2 + b/2 + n/2 + S.Half)*jacobi(n - 1, a + 1, b + 1, x) assert jacobi_normalized(n, a, b, x) == \ (jacobi(n, a, b, x)/sqrt(2**(a + b + 1)*gamma(a + n + 1)*gamma(b + n + 1) /((a + b + 2*n + 1)*factorial(n)*gamma(a + b + n + 1)))) raises(ValueError, lambda: jacobi(-2.1, a, b, x)) raises(ValueError, lambda: jacobi(Dummy(positive=True, integer=True), 1, 2, oo)) assert jacobi(n, a, b, x).rewrite("polynomial").dummy_eq( Sum((S.Half - x / 2)**_k * RisingFactorial(-n, _k) * RisingFactorial(_k + a + 1, -_k + n) * RisingFactorial(a + b + n + 1, _k) / factorial(_k), (_k, 0, n)) / factorial(n)) raises(ArgumentIndexError, lambda: jacobi(n, a, b, x).fdiff(5))
def test_issue_16160(): assert Derivative(x**3, (x, x)).subs(x, 2) == Subs( Derivative(x**3, (x, 2)), x, 2) assert Derivative(1 + x**3, (x, x)).subs(x, 0 ) == Derivative(1 + y**3, (y, 0)).subs(y, 0)
def test_derivative2(): f = Function("f") x = Symbol("x") a = Wild("a", exclude=[f, x]) b = Wild("b", exclude=[f]) e = Derivative(f(x), x) assert e.match(Derivative(f(x), x)) == {} assert e.match(Derivative(f(x), x, x)) is None e = Derivative(f(x), x, x) assert e.match(Derivative(f(x), x)) is None assert e.match(Derivative(f(x), x, x)) == {} e = Derivative(f(x), x) + x**2 assert e.match(a*Derivative(f(x), x) + b) == {a: 1, b: x**2} assert e.match(a*Derivative(f(x), x, x) + b) is None e = Derivative(f(x), x, x) + x**2 assert e.match(a*Derivative(f(x), x) + b) is None assert e.match(a*Derivative(f(x), x, x) + b) == {a: 1, b: x**2}
def test_Derivative(): assert str(Derivative(x, y)) == "Derivative(x, y)" assert str(Derivative(x**2, x, evaluate=False)) == "Derivative(x**2, x)" assert str(Derivative( x**2/y, x, y, evaluate=False)) == "Derivative(x**2/y, x, y)"
def test_big_expr(): f = Function('f') x = symbols('x') e1 = Dagger(AntiCommutator(Operator('A') + Operator('B'), Pow(DifferentialOperator(Derivative(f(x), x), f(x)), 3))*TensorProduct(Jz**2, Operator('A') + Operator('B')))*(JzBra(1, 0) + JzBra(1, 1))*(JzKet(0, 0) + JzKet(1, -1)) e2 = Commutator(Jz**2, Operator('A') + Operator('B'))*AntiCommutator(Dagger(Operator('C')*Operator('D')), Operator('E').inv()**2)*Dagger(Commutator(Jz, J2)) e3 = Wigner3j(1, 2, 3, 4, 5, 6)*TensorProduct(Commutator(Operator('A') + Dagger(Operator('B')), Operator('C') + Operator('D')), Jz - J2)*Dagger(OuterProduct(Dagger(JzBra(1, 1)), JzBra(1, 0)))*TensorProduct(JzKetCoupled(1, 1, (1, 1)) + JzKetCoupled(1, 0, (1, 1)), JzKetCoupled(1, -1, (1, 1))) e4 = (ComplexSpace(1)*ComplexSpace(2) + FockSpace()**2)*(L2(Interval( 0, oo)) + HilbertSpace()) assert str(e1) == '(Jz**2)x(Dagger(A) + Dagger(B))*{Dagger(DifferentialOperator(Derivative(f(x), x),f(x)))**3,Dagger(A) + Dagger(B)}*(<1,0| + <1,1|)*(|0,0> + |1,-1>)' ascii_str = \ """\ / 3 \\ \n\ |/ +\\ | \n\ 2 / + +\\ <| /d \\ | + +> \n\ /J \\ x \\A + B /*||DifferentialOperator|--(f(x)),f(x)| | ,A + B |*(<1,0| + <1,1|)*(|0,0> + |1,-1>)\n\ \\ z/ \\\\ \\dx / / / \ """ ucode_str = \ """\ ⎧ 3 ⎫ \n\ ⎪⎛ †⎞ ⎪ \n\ 2 ⎛ † †⎞ ⎨⎜ ⎛d ⎞ ⎟ † †⎬ \n\ ⎛J ⎞ ⨂ ⎝A + B ⎠⋅⎪⎜DifferentialOperator⎜──(f(x)),f(x)⎟ ⎟ ,A + B ⎪⋅(⟨1,0❘ + ⟨1,1❘)⋅(❘0,0⟩ + ❘1,-1⟩)\n\ ⎝ z⎠ ⎩⎝ ⎝dx ⎠ ⎠ ⎭ \ """ assert pretty(e1) == ascii_str assert upretty(e1) == ucode_str assert latex(e1) == \ r'{J_z^{2}}\otimes \left({A^{\dagger} + B^{\dagger}}\right) \left\{\left(DifferentialOperator\left(\frac{d}{d x} f{\left(x \right)},f{\left(x \right)}\right)^{\dagger}\right)^{3},A^{\dagger} + B^{\dagger}\right\} \left({\left\langle 1,0\right|} + {\left\langle 1,1\right|}\right) \left({\left|0,0\right\rangle } + {\left|1,-1\right\rangle }\right)' sT(e1, "Mul(TensorProduct(Pow(JzOp(Symbol('J')), Integer(2)), Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), AntiCommutator(Pow(Dagger(DifferentialOperator(Derivative(Function('f')(Symbol('x')), Tuple(Symbol('x'), Integer(1))),Function('f')(Symbol('x')))), Integer(3)),Add(Dagger(Operator(Symbol('A'))), Dagger(Operator(Symbol('B'))))), Add(JzBra(Integer(1),Integer(0)), JzBra(Integer(1),Integer(1))), Add(JzKet(Integer(0),Integer(0)), JzKet(Integer(1),Integer(-1))))") assert str(e2) == '[Jz**2,A + B]*{E**(-2),Dagger(D)*Dagger(C)}*[J2,Jz]' ascii_str = \ """\ [ 2 ] / -2 + +\\ [ 2 ]\n\ [/J \\ ,A + B]*<E ,D *C >*[J ,J ]\n\ [\\ z/ ] \\ / [ z]\ """ ucode_str = \ """\ ⎡ 2 ⎤ ⎧ -2 † †⎫ ⎡ 2 ⎤\n\ ⎢⎛J ⎞ ,A + B⎥⋅⎨E ,D ⋅C ⎬⋅⎢J ,J ⎥\n\ ⎣⎝ z⎠ ⎦ ⎩ ⎭ ⎣ z⎦\ """ assert pretty(e2) == ascii_str assert upretty(e2) == ucode_str assert latex(e2) == \ r'\left[J_z^{2},A + B\right] \left\{E^{-2},D^{\dagger} C^{\dagger}\right\} \left[J^2,J_z\right]' sT(e2, "Mul(Commutator(Pow(JzOp(Symbol('J')), Integer(2)),Add(Operator(Symbol('A')), Operator(Symbol('B')))), AntiCommutator(Pow(Operator(Symbol('E')), Integer(-2)),Mul(Dagger(Operator(Symbol('D'))), Dagger(Operator(Symbol('C'))))), Commutator(J2Op(Symbol('J')),JzOp(Symbol('J'))))") assert str(e3) == \ "Wigner3j(1, 2, 3, 4, 5, 6)*[Dagger(B) + A,C + D]x(-J2 + Jz)*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x|1,-1,j1=1,j2=1>" ascii_str = \ """\ [ + ] / 2 \\ \n\ /1 3 5\\*[B + A,C + D]x |- J + J |*|1,0><1,1|*(|1,0,j1=1,j2=1> + |1,1,j1=1,j2=1>)x |1,-1,j1=1,j2=1>\n\ | | \\ z/ \n\ \\2 4 6/ \ """ ucode_str = \ """\ ⎡ † ⎤ ⎛ 2 ⎞ \n\ ⎛1 3 5⎞⋅⎣B + A,C + D⎦⨂ ⎜- J + J ⎟⋅❘1,0⟩⟨1,1❘⋅(❘1,0,j₁=1,j₂=1⟩ + ❘1,1,j₁=1,j₂=1⟩)⨂ ❘1,-1,j₁=1,j₂=1⟩\n\ ⎜ ⎟ ⎝ z⎠ \n\ ⎝2 4 6⎠ \ """ assert pretty(e3) == ascii_str assert upretty(e3) == ucode_str assert latex(e3) == \ r'\left(\begin{array}{ccc} 1 & 3 & 5 \\ 2 & 4 & 6 \end{array}\right) {\left[B^{\dagger} + A,C + D\right]}\otimes \left({- J^2 + J_z}\right) {\left|1,0\right\rangle }{\left\langle 1,1\right|} \left({{\left|1,0,j_{1}=1,j_{2}=1\right\rangle } + {\left|1,1,j_{1}=1,j_{2}=1\right\rangle }}\right)\otimes {{\left|1,-1,j_{1}=1,j_{2}=1\right\rangle }}' sT(e3, "Mul(Wigner3j(Integer(1), Integer(2), Integer(3), Integer(4), Integer(5), Integer(6)), TensorProduct(Commutator(Add(Dagger(Operator(Symbol('B'))), Operator(Symbol('A'))),Add(Operator(Symbol('C')), Operator(Symbol('D')))), Add(Mul(Integer(-1), J2Op(Symbol('J'))), JzOp(Symbol('J')))), OuterProduct(JzKet(Integer(1),Integer(0)),JzBra(Integer(1),Integer(1))), TensorProduct(Add(JzKetCoupled(Integer(1),Integer(0),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1)))), JzKetCoupled(Integer(1),Integer(1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))), JzKetCoupled(Integer(1),Integer(-1),Tuple(Integer(1), Integer(1)),Tuple(Tuple(Integer(1), Integer(2), Integer(1))))))") assert str(e4) == '(C(1)*C(2)+F**2)*(L2(Interval(0, oo))+H)' ascii_str = \ """\ // 1 2\\ x2\\ / 2 \\\n\ \\\\C x C / + F / x \\L + H/\ """ ucode_str = \ """\ ⎛⎛ 1 2⎞ ⨂2⎞ ⎛ 2 ⎞\n\ ⎝⎝C ⨂ C ⎠ ⊕ F ⎠ ⨂ ⎝L ⊕ H⎠\ """ assert pretty(e4) == ascii_str assert upretty(e4) == ucode_str assert latex(e4) == \ r'\left(\left(\mathcal{C}^{1}\otimes \mathcal{C}^{2}\right)\oplus {\mathcal{F}}^{\otimes 2}\right)\otimes \left({\mathcal{L}^2}\left( \left[0, \infty\right) \right)\oplus \mathcal{H}\right)' sT(e4, "TensorProductHilbertSpace((DirectSumHilbertSpace(TensorProductHilbertSpace(ComplexSpace(Integer(1)),ComplexSpace(Integer(2))),TensorPowerHilbertSpace(FockSpace(),Integer(2)))),(DirectSumHilbertSpace(L2(Interval(Integer(0), oo, false, true)),HilbertSpace())))")
def test_twave(): A1, phi1, A2, phi2, f = symbols('A1, phi1, A2, phi2, f') n = Symbol('n') # Refractive index t = Symbol('t') # Time x = Symbol('x') # Spatial variable E = Function('E') w1 = TWave(A1, f, phi1) w2 = TWave(A2, f, phi2) assert w1.amplitude == A1 assert w1.frequency == f assert w1.phase == phi1 assert w1.wavelength == c / (f * n) assert w1.time_period == 1 / f assert w1.angular_velocity == 2 * pi * f assert w1.wavenumber == 2 * pi * f * n / c assert w1.speed == c / n w3 = w1 + w2 assert w3.amplitude == sqrt(A1**2 + 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) assert w3.frequency == f assert w3.phase == atan2(A1 * sin(phi1) + A2 * sin(phi2), A1 * cos(phi1) + A2 * cos(phi2)) assert w3.wavelength == c / (f * n) assert w3.time_period == 1 / f assert w3.angular_velocity == 2 * pi * f assert w3.wavenumber == 2 * pi * f * n / c assert w3.speed == c / n assert simplify(w3.rewrite(sin) - w2.rewrite(sin) - w1.rewrite(sin)) == 0 assert w3.rewrite('pde') == epsilon * mu * Derivative(E( x, t), t, t) + Derivative(E(x, t), x, x) assert w3.rewrite( cos) == sqrt(A1**2 + 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) * cos(pi * f * n * x * s / (149896229 * m) - 2 * pi * f * t + atan2(A1 * sin(phi1) + A2 * sin(phi2), A1 * cos(phi1) + A2 * cos(phi2))) assert w3.rewrite( exp) == sqrt(A1**2 + 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) * exp( I * (-2 * pi * f * t + atan2(A1 * sin(phi1) + A2 * sin(phi2), A1 * cos(phi1) + A2 * cos(phi2)) + pi * s * f * n * x / (149896229 * m))) w4 = TWave(A1, None, 0, 1 / f) assert w4.frequency == f w5 = w1 - w2 assert w5.amplitude == sqrt(A1**2 - 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) assert w5.frequency == f assert w5.phase == atan2(A1 * sin(phi1) - A2 * sin(phi2), A1 * cos(phi1) - A2 * cos(phi2)) assert w5.wavelength == c / (f * n) assert w5.time_period == 1 / f assert w5.angular_velocity == 2 * pi * f assert w5.wavenumber == 2 * pi * f * n / c assert w5.speed == c / n assert simplify(w5.rewrite(sin) - w1.rewrite(sin) + w2.rewrite(sin)) == 0 assert w5.rewrite('pde') == epsilon * mu * Derivative(E( x, t), t, t) + Derivative(E(x, t), x, x) assert w5.rewrite(cos) == sqrt( A1**2 - 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) * cos(-2 * pi * f * t + atan2(A1 * sin(phi1) - A2 * sin(phi2), A1 * cos(phi1) - A2 * cos(phi2)) + pi * s * f * n * x / (149896229 * m)) assert w5.rewrite( exp) == sqrt(A1**2 - 2 * A1 * A2 * cos(phi1 - phi2) + A2**2) * exp( I * (-2 * pi * f * t + atan2(A1 * sin(phi1) - A2 * sin(phi2), A1 * cos(phi1) - A2 * cos(phi2)) + pi * s * f * n * x / (149896229 * m))) w6 = 2 * w1 assert w6.amplitude == 2 * A1 assert w6.frequency == f assert w6.phase == phi1 w7 = -w6 assert w7.amplitude == -2 * A1 assert w7.frequency == f assert w7.phase == phi1 raises(ValueError, lambda: TWave(A1)) raises(ValueError, lambda: TWave(A1, f, phi1, t))
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 == S(0) == divergence(Vector.zero, C) assert (delop & Vector.zero).doit() == S(0) assert delop.dot(Vector.zero) == delop & Vector.zero assert (delop & i).doit() == S(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(S(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) == S(0) assert ((Vector.zero & delop)(a)).doit() == S(0) assert ((v & delop)(Vector.zero)).doit() == Vector.zero assert ((v & delop)(S(0))).doit() == S(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_sympy__core__function__Derivative(): from sympy.core.function import Derivative assert _test_args(Derivative(2, x, y, 3))
def _eval_derivative(self, t): x, y = re(self.args[0]), im(self.args[0]) return (x * Derivative(y, t, **{'evaluate': True}) - y * Derivative(x, t, **{'evaluate': True})) / (x**2 + y**2)
def define_controller(self, A, B, C, f, eta, phi): """ Define the Dynamic controller given by the differential equations: .. math:: \\frac{dz(t)}{dt} = A.z(t) - B.f(\\sigma(t)) + \\eta\\left(w(t), \\frac{dw(t)}{dt}\\right) .. math:: \\sigma(t) = C'.z .. math:: u_0 = \\phi\\left(z(t), \\frac{dz(t)}{dt}\\right) with z(t) the state vector, w(t) the input vector and t the time in seconds. the symbol ' refers to the transpose. Conditions: * A is Hurwitz, * (A, B) should be controllable, * (A, C) is observable, * rank(B) = rang (C) = s <= n, with s the dimension of sigma, and n the number of states. **HINT:** use create_variables() for an easy notation of the equations. Parameters ----------- A : array-like Hurwitz matrix. Size: n x n B : array-like In combination with matrix A, the controllability is checked. The linear definition can be used. Size: s x n C : array-like In combination with matrix A, the observability is checked. The linear definition can be used. Size: n x 1 f : callable (lambda-function) A (non)linear lambda function with argument sigma, which equals C'.z. eta : array-like The (non)linear relation between the inputs plus its derivatives to the change in state. Size: n x 1 phi : array-like The (non)linear output equation. The equations should only contain states and its derivatives. Size: n x 1 Examples: --------- See DyncamicController object. """ dim_states = self.states.shape[0] # Allow scalar inputs if np.isscalar(A): A = [[A]] if np.isscalar(B): B = [[B]] if np.isscalar(C): C = [[C]] if type(eta) not in (list, Matrix): eta = [[eta]] if type(phi) not in (list, Matrix): phi = [[phi]] if Matrix(A).shape[1] == dim_states: if self.hurwitz(A): self.A = Matrix(A) else: error_text = '[nlcontrol.systems.DynamicController] The A matrix should be Hurwitz.' raise AssertionError(error_text) else: error_text = '[nlcontrol.systems.DynamicController] The number of columns of A should be equal to the number of states.' raise AssertionError(error_text) if Matrix(B).shape[0] == dim_states: if self.controllability_linear(A, B): self.B = Matrix(B) else: error_text = '[nlcontrol.systems.DynamicController] The system is not controllable.' raise AssertionError(error_text) else: error_text = '[nlcontrol.systems.DynamicController] The number of rows of B should be equal to the number of states.' raise AssertionError(error_text) if Matrix(C).shape[0] == dim_states: if self.observability_linear(A, C): self.C = Matrix(C) else: error_text = '[nlcontrol.systems.DynamicController] The system is not observable.' raise AssertionError(error_text) else: error_text = '[nlcontrol.systems.DynamicController] The number of rows of C should be equal to the number of states.' raise AssertionError(error_text) if type(f) is not Matrix: if callable(f): argument = self.C.T * Matrix(self.states) #TODO: make an array of f self.f = f(argument[0, 0]) elif f == 0: self.f = 0 else: error_text = '[nlcontrol.systems.DynamicController] Argument f should be a callable function or identical 0.' raise AssertionError(error_text) else: self.f = f def return_dynamic_symbols(expr): try: return find_dynamicsymbols(expr) except: return set() if Matrix(eta).shape[0] == dim_states and Matrix(eta).shape[1] == 1: # Check whether the expressions only contain inputs if type(eta) is Matrix: dynamic_symbols_eta = [ return_dynamic_symbols(eta_el[0]) for eta_el in eta.tolist() ] else: dynamic_symbols_eta = [ return_dynamic_symbols(eta_el) for eta_el in list(itertools.chain(*eta)) ] dynamic_symbols_eta = set.union(*dynamic_symbols_eta) if dynamic_symbols_eta <= (set(self.inputs)): self.eta = Matrix(eta) else: error_text = '[nlcontrol.systems.DynamicController] Vector eta cannot contain other dynamic symbols than the inputs.' raise AssertionError(error_text) else: error_text = '[nlcontrol.systems.DynamicController] Vector eta has an equal amount of columns as there are states. Eta has only one row.' raise AssertionError(error_text) # Check whether the expressions only contain inputs and derivatives of the input if type(phi) is Matrix: dynamic_symbols_phi = [ return_dynamic_symbols(phi_el[0]) for phi_el in phi.tolist() ] else: dynamic_symbols_phi = [ return_dynamic_symbols(phi_el) for phi_el in list(itertools.chain(*phi)) ] dynamic_symbols_phi = set.union(*dynamic_symbols_phi) if dynamic_symbols_phi <= (set(self.states) | set(self.dstates)): self.phi = Matrix(phi) else: error_text = '[nlcontrol.systems.DynamicController] Vector phi cannot contain other dynamic symbols than the states and its derivatives.' raise AssertionError(error_text) state_equation = Array(self.A * Matrix(self.states) - self.B * self.f + self.eta) output_equation = Array(self.phi) diff_states = [] for state in self.states: diff_states.append(Derivative(state, Symbol('t'))) substitutions = dict(zip(diff_states, state_equation)) # print('Subs: ', substitutions) output_equation = msubs(output_equation, substitutions) self.system = DynamicalSystem(state_equation=state_equation, output_equation=output_equation, state=self.states, input_=self.inputs)
def _eval_derivative(self, x): return re(Derivative(self.args[0], x, **{'evaluate': True}))
def _eval_derivative(self, t): x, y = self.args[0].as_real_imag() return (x * Derivative(y, t, evaluate=True) - y * Derivative(x, t, evaluate=True)) / (x**2 + y**2)
def _eval_derivative(self, symbol): new_expr = Derivative(self.expr, symbol) return DifferentialOperator(new_expr, self.args[-1])
def _eval_derivative(self, t): x, y = re(self.args[0]), im(self.args[0]) return (x * Derivative(y, t, evaluate=True) - y * Derivative(x, t, evaluate=True)) / (x**2 + y**2)
def _as_finite_diff(derivative, points=1, x0=None, wrt=None): """ Returns an approximation of a derivative of a function in the form of a finite difference formula. The expression is a weighted sum of the function at a number of discrete values of (one of) the independent variable(s). Parameters ========== derivative: a Derivative instance points: sequence or coefficient, optional If sequence: discrete values (length >= order+1) of the independent variable used for generating the finite difference weights. If it is a coefficient, it will be used as the step-size for generating an equidistant sequence of length order+1 centered around ``x0``. default: 1 (step-size 1) x0: number or Symbol, optional the value of the independent variable (``wrt``) at which the derivative is to be approximated. Default: same as ``wrt``. wrt: Symbol, optional "with respect to" the variable for which the (partial) derivative is to be approximated for. If not provided it is required that the Derivative is ordinary. Default: ``None``. Examples ======== >>> from sympy import symbols, Function, exp, sqrt, Symbol >>> from sympy.calculus.finite_diff import _as_finite_diff >>> x, h = symbols('x h') >>> f = Function('f') >>> _as_finite_diff(f(x).diff(x)) -f(x - 1/2) + f(x + 1/2) The default step size and number of points are 1 and ``order + 1`` respectively. We can change the step size by passing a symbol as a parameter: >>> _as_finite_diff(f(x).diff(x), h) -f(-h/2 + x)/h + f(h/2 + x)/h We can also specify the discretized values to be used in a sequence: >>> _as_finite_diff(f(x).diff(x), [x, x+h, x+2*h]) -3*f(x)/(2*h) + 2*f(h + x)/h - f(2*h + x)/(2*h) The algorithm is not restricted to use equidistant spacing, nor do we need to make the approximation around ``x0``, but we can get an expression estimating the derivative at an offset: >>> e, sq2 = exp(1), sqrt(2) >>> xl = [x-h, x+h, x+e*h] >>> _as_finite_diff(f(x).diff(x, 1), xl, x+h*sq2) 2*h*((h + sqrt(2)*h)/(2*h) - (-sqrt(2)*h + h)/(2*h))*f(E*h + x)/((-h + E*h)*(h + E*h)) + (-(-sqrt(2)*h + h)/(2*h) - (-sqrt(2)*h + E*h)/(2*h))*f(-h + x)/(h + E*h) + (-(h + sqrt(2)*h)/(2*h) + (-sqrt(2)*h + E*h)/(2*h))*f(h + x)/(-h + E*h) Partial derivatives are also supported: >>> y = Symbol('y') >>> d2fdxdy=f(x,y).diff(x,y) >>> _as_finite_diff(d2fdxdy, wrt=x) -Derivative(f(x - 1/2, y), y) + Derivative(f(x + 1/2, y), y) See also ======== sympy.calculus.finite_diff.apply_finite_diff sympy.calculus.finite_diff.finite_diff_weights """ if derivative.is_Derivative: pass elif derivative.is_Atom: return derivative else: return derivative.fromiter( [_as_finite_diff(ar, points, x0, wrt) for ar in derivative.args], **derivative.assumptions0) if wrt is None: old = None for v in derivative.variables: if old is v: continue derivative = _as_finite_diff(derivative, points, x0, v) old = v return derivative order = derivative.variables.count(wrt) if x0 is None: x0 = wrt if not iterable(points): if getattr(points, 'is_Function', False) and wrt in points.args: points = points.subs(wrt, x0) # points is simply the step-size, let's make it a # equidistant sequence centered around x0 if order % 2 == 0: # even order => odd number of points, grid point included points = [ x0 + points * i for i in range(-order // 2, order // 2 + 1) ] else: # odd order => even number of points, half-way wrt grid point points = [ x0 + points * S(i) / 2 for i in range(-order, order + 1, 2) ] others = [wrt, 0] for v in set(derivative.variables): if v == wrt: continue others += [v, derivative.variables.count(v)] if len(points) < order + 1: raise ValueError("Too few points for order %d" % order) return apply_finite_diff( order, points, [Derivative(derivative.expr.subs({wrt: x}), *others) for x in points], x0)
def _eval_derivative(self, x): if x.is_real or self.args[0].is_real: return re(Derivative(self.args[0], x, evaluate=True)) if x.is_imaginary or self.args[0].is_imaginary: return -S.ImaginaryUnit \ * im(Derivative(self.args[0], x, evaluate=True))
def _eval_diff(self, *args, **kwargs): if kwargs.pop("evaluate", True): return self.diff(*args) else: return Derivative(self, *args, **kwargs)
def test_Function(): assert precedence(sin(x)) == PRECEDENCE["Atom"] assert precedence(Derivative(x, y)) == PRECEDENCE["Atom"]
"\\frac{d}{d x}( \\frac{f{\\left(x \\right)}}{g{\left(x \\right)}})") expresion = expresion.replace( "\\frac{- f{\\left(x \\right)} \\frac{d}{d x} g{\\left(x \\right)} + g{\\left(x \\right)} \\frac{d}{d x} f{\\left(x \\right)}}{g^{2}{\\left(x \\right)}}", "\\frac{- f{\\left(x \\right)} \\frac{d}{d x}( g{\\left(x \\right)}) + g{\\left(x \\right)} \\frac{d}{d x}( f{\\left(x \\right))}}{g^{2}{\\left(x \\right)}}") expresion = expresion.replace("\\frac{d}{d x} f{\\left(x \\right)}", "\\frac{d}{d x}( f{\\left(x \\right)})") expresion = expresion.replace("\\frac{d}{d x} g{\\left(x \\right)}", "\\frac{d}{d x}( g{\\left(x \\right)})") return expresion ##MAIN## salida = open("/tmp/solucion_28d36c18-7985-42e7-bce1-11babf379715.txt","w") x = symbols('x') expr = parse_latex(r"2x^3+12x^2-30x-1").subs({Symbol('pi'): pi}) salida.write("Obtener: $$%s$$<br><br>" % latex(Derivative(expr, x))) solucion = print_html_steps(expr, x) solucion = acomodaNotacion(solucion) salida.write(solucion) derivada = Derivative(expr) derivada = derivada.doit() anula = solve(derivada, x) puntos = [] xmin,xmax = 0,0 ymin,ymax = 0,0 solucion = "Resolviendo $$%s=0$$ obtenemos las raices<br/>" % (latex(derivada)) n = 1 for x_0 in anula: solucion = solucion + "$$x_%s=%s$$ <br/>" % (n, latex(x_0)) n = n+1 n = 1
def curl(vect, coord_sys=None, doit=True): """ Returns the curl of a vector field computed wrt the base scalars of the given coordinate system. Parameters ========== vect : Vector The vector operand coord_sys : CoordSys3D The coordinate system to calculate the gradient in. Deprecated since version 1.1 doit : bool If True, the result is returned after calling .doit() on each component. Else, the returned expression contains Derivative instances Examples ======== >>> from sympy.vector import CoordSys3D, curl >>> R = CoordSys3D('R') >>> v1 = R.y*R.z*R.i + R.x*R.z*R.j + R.x*R.y*R.k >>> curl(v1) 0 >>> v2 = R.x*R.y*R.z*R.i >>> curl(v2) R.x*R.y*R.j + (-R.x*R.z)*R.k """ coord_sys = _get_coord_sys_from_expr(vect, coord_sys) if len(coord_sys) == 0: return Vector.zero elif len(coord_sys) == 1: coord_sys = next(iter(coord_sys)) i, j, k = coord_sys.base_vectors() x, y, z = coord_sys.base_scalars() h1, h2, h3 = coord_sys.lame_coefficients() vectx = vect.dot(i) vecty = vect.dot(j) vectz = vect.dot(k) outvec = Vector.zero outvec += (Derivative(vectz * h3, y) - Derivative(vecty * h2, z)) * i / (h2 * h3) outvec += (Derivative(vectx * h1, z) - Derivative(vectz * h3, x)) * j / (h1 * h3) outvec += (Derivative(vecty * h2, x) - Derivative(vectx * h1, y)) * k / (h2 * h1) if doit: return outvec.doit() return outvec else: if isinstance(vect, (Add, VectorAdd)): from sympy.vector import express try: cs = next(iter(coord_sys)) args = [express(i, cs, variables=True) for i in vect.args] except ValueError: args = vect.args return VectorAdd.fromiter(curl(i, doit=doit) for i in args) elif isinstance(vect, (Mul, VectorMul)): vector = [ i for i in vect.args if isinstance(i, (Vector, Cross, Gradient)) ][0] scalar = Mul.fromiter( i for i in vect.args if not isinstance(i, (Vector, Cross, Gradient))) res = Cross(gradient(scalar), vector).doit() + scalar * curl(vector, doit=doit) if doit: return res.doit() return res elif isinstance(vect, (Cross, Curl, Gradient)): return Curl(vect) else: raise Curl(vect)
def test_del_operator(): # Tests for curl assert delop ^ Vector.zero == Vector.zero assert (delop ^ Vector.zero).doit() == Vector.zero == curl(Vector.zero) 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) ) 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) # Tests for divergence assert delop & Vector.zero is S.Zero == divergence(Vector.zero) assert (delop & Vector.zero).doit() is S.Zero assert delop.dot(Vector.zero) == delop & Vector.zero assert (delop & i).doit() is S.Zero assert (delop & x ** 2 * i).doit() == 2 * x == divergence(x ** 2 * i) assert delop.dot(v, doit=True) == x * y + y * z + z * x == divergence(v) 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) 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) assert delop.gradient(0) == delop(0) assert (delop(S.Zero)).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) 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) ) 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) is S.Zero assert ((Vector.zero & delop)(a)).doit() is S.Zero assert ((v & delop)(Vector.zero)).doit() == Vector.zero assert ((v & delop)(S.Zero)).doit() is S.Zero 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 # Tests for laplacian on scalar fields assert laplacian(x * y * z) is S.Zero assert laplacian(x ** 2) == S(2) assert ( laplacian(x ** 2 * y ** 2 * z ** 2) == 2 * y ** 2 * z ** 2 + 2 * x ** 2 * z ** 2 + 2 * x ** 2 * y ** 2 ) A = CoordSys3D( "A", transformation="spherical", variable_names=["r", "theta", "phi"] ) B = CoordSys3D( "B", transformation="cylindrical", variable_names=["r", "theta", "z"] ) assert laplacian(A.r + A.theta + A.phi) == 2 / A.r + cos(A.theta) / ( A.r ** 2 * sin(A.theta) ) assert laplacian(B.r + B.theta + B.z) == 1 / B.r # Tests for laplacian on vector fields assert laplacian(x * y * z * (i + j + k)) == Vector.zero assert ( laplacian(x * y ** 2 * z * (i + j + k)) == 2 * x * z * i + 2 * x * z * j + 2 * x * z * k )