Additionally to Stefan's answer about sympy core , I introduce the example how it may be implemented concretely.
There is the tested code in the atachment of it. (I can create PR, but I don't know where will it be better to put in the sympy modules) And there is the '__call__' magic-method used instead of the implicit multiplication as aplly-like method. >>> Dx = DiffOperator(x) >>> myD = (a*Dx + Dx**3) # construct diff operator >>> myD(x**4) # apply this operator. 4*a*x**3 + 24*x For matrices it is some more complicated >>> I = Matrix([[0, -1], [1, 0]]) >>> myD = I*Dx # construct diff >>> myD(x**2) # apply Derivative([x**2, 0] [ 0, x**2], x) Here I don't know how Derivative can be automatically applied for the Matrix expression. -- Alexey Gudchenko On 26.01.2013 02:49, ruoyu zhang wrote: >>>> p = DifferentialOperator(t) >>>> a * p * f(t) > Derivative(f(t), t)*a > > p is a DifferentialOperator, when it multiply with some expression at > right side, it calculates the derivative of the expression. > -- You received this message because you are subscribed to the Google Groups "sympy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sympy+unsubscr...@googlegroups.com. To post to this group, send email to sympy@googlegroups.com. Visit this group at http://groups.google.com/group/sympy?hl=en. For more options, visit https://groups.google.com/groups/opt_out.
""" The module implemented diff operator. """ from sympy import Expr, Symbol, Eq, Mul, Add, Pow, expand, sympify, Tuple from sympy.core.basic import Basic from sympy.core.operations import AssocOp from sympy.core.singleton import (Singleton, S) from sympy.core.decorators import _sympifyit, call_highest_priority from sympy.core.cache import cacheit from sympy.core.function import diff from sympy.series.order import Order class DiffOperatorExpr(Expr): _op_priority = 12.0 is_DiffOperator = True is_Identity = False # The following is adapted from the core Expr object def __neg__(self): return DOMul(S.NegativeOne, self) def __abs__(self): raise NotImplementedError @_sympifyit('other', NotImplemented) @call_highest_priority('__radd__') def __add__(self, other): return DOAdd(self, other) @_sympifyit('other', NotImplemented) @call_highest_priority('__add__') def __radd__(self, other): return DOAdd(other, self) @_sympifyit('other', NotImplemented) @call_highest_priority('__rsub__') def __sub__(self, other): return DOAdd(self, -other) @_sympifyit('other', NotImplemented) @call_highest_priority('__sub__') def __rsub__(self, other): return DOAdd(other, -self) @_sympifyit('other', NotImplemented) @call_highest_priority('__rmul__') def __mul__(self, other): return DOMul(self, other) @_sympifyit('other', NotImplemented) @call_highest_priority('__mul__') def __rmul__(self, other): return DOMul(other, self) @_sympifyit('other', NotImplemented) @call_highest_priority('__rpow__') def __pow__(self, other): return DOPow(self, other) @_sympifyit('other', NotImplemented) @call_highest_priority('__pow__') def __rpow__(self, other): raise NotImplementedError("DiffOperator Power is not defined") @_sympifyit('other', NotImplemented) @call_highest_priority('__rdiv__') def __div__(self, other): return DOMul(self, other**S.NegativeOne) @_sympifyit('other', NotImplemented) @call_highest_priority('__div__') def __rdiv__(self, other): return DOMul(other, self**S.NegativeOne) class DiffOperatorOne(DiffOperatorExpr): """ Represents the identic operator ( DiffOperator**0). """ __metaclass__ = Singleton is_Identity = True class DiffOperator(DiffOperatorExpr): """ >>> from sympy.abc import x, a >>> from sympy.core.function import Function >>> from sympy.tensor.diff_operator import DiffOperator >>> f = Function("f") >>> Dx = DiffOperator(x) >>> Dx + Dx DiffOperator(x) + DiffOperator(x) >>> Dx(f(x)) Derivative(f(x), x) >>> Dx + Dx**2 DiffOperator(x) + DiffOperator(x)**2 >>> (Dx + Dx**2)(f(x)) Derivative(f(x), x) + Derivative(f(x), x, x) >>> (a*Dx + Dx**3)(x**4) 4*a*x**3 + 24*x """ def __new__(cls, variable): obj = DiffOperatorExpr.__new__(cls, variable) return obj @property def variable(self): return self._args[0] def _hashable_content(self): return tuple(sorted(self._args, key=hash)) def __call__(self, e): return diff(e, self.variable) def _eval_nseries(self, x, n, logx): return self + Order(n) def _latex(self, p): return "\partial_{%s}" % (p._print(self.variable)) def _needs_brackets(self): return False class DOAdd(DiffOperatorExpr, Add): """ A Sum of the DiffOperator expressions. """ def __new__(cls, *args): expr = Add.__new__(cls, *args) if expr.is_Mul: return DOMul(*expr.args) return expr def __call__(self, e): return Add(*tuple(d(e) for d in self.args)) @classmethod def flatten(cls, args): new_seq = [] i = 0 while args: o = args.pop() if o.__class__ is cls: args.extend(o.args) else: new_seq.append(o) new_seq.reverse() return new_seq, [], None class DOMul(DiffOperatorExpr, Mul): def __new__(cls, *args): if any(arg.is_zero for arg in args): return S.Zero expr = Mul.__new__(cls, *args) return expr # is it needed? @classmethod def flatten(cls, args_seq): return args_seq, [], None def as_ordered_terms(self, order=None): return self.args @property def variable(self): for d in self.args: if isinstance(d, DiffOperatorExpr): return d.variable def __call__(self, e): for d in self.args: if isinstance(d, DiffOperatorExpr): e = d(e) else: e = e*d return e class DOPow(DiffOperatorExpr, Pow): def __new__(cls, *args): expr = Pow.__new__(cls, *args, evaluate=False) return expr def __call__(self, e): base = self.base if isinstance(base, DOMul): parts = (arg for arg in base.args) res = S.One for part in parts: if isinstance(part, DiffOperatorExpr): res *= (part**self.exp)(e) else: res *= (part**self.exp) return res else: return diff(e, self.base.variable, self.exp) def _latex(self, p): return "%s^{%s}" % (self.base._latex(p), self.exp)