Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

How do I create an operator which acts like a derivative to everything to the right of it:

for example:

$ \left( \partial_x + \partial_y + z \right ) x \psi $

How do I make that evaluate to:

$x \partial_x \psi + \psi + x \partial_y \psi + z x \psi $

(I want the derivatives to distribute...)

share|improve this question
add comment

5 Answers

up vote 13 down vote accepted

A general idea as to how this can be done in a consistent way is explained in the help documents under NonCommutativeMultiply. The thing is that you want to use your operators in an algebraic notation, and that's what that page discusses.

If, on the other hand, you're happy with a more formal Mathematica notation, then you would have the easier task of defining operators simply as

dx := D[#, x] &
dy := D[#, y] &

and using them as follows:

dx@f[x, y, z]

$f^{(1,0,0)}(x,y,z)$

Combining operators would then be done using Composition:

dxy = Composition[dx, dy];
dxy[f[x, y, z]]

$f^{(1,1,0)}(x,y,z)$

Edit

Here is another approach that's sort of intermediate between the very simple D[#,x]& scheme and the more complicated realization of an operator algebra in the linked reference from the documentation.

To make the operators satisfy the axioms of a vector space, we'd have to define their addition among each other and the multiplication with scalars. This can be done most conveniently if we don't use patterns to represent the operators, but Functions. So here I repeat the operator definitions - they act the same way as the dx, dy defined above, but their definition is stored differently:

dx = Function[{f}, D[f, x]];
dy = Function[{f}, D[f, y]];

Now I define the multiplication of an operator with a scalar:

multiplyOp[scalar_, op_] := Function[{f1}, scalar op[f1]];

For simplicity, I always assume that the scalar is given as the first argument, and the second argument is an operator, e.g., dx etc. Note that the arguments here are not x or y (the assumed independent variables on which functions depend), because multiplyOp maps operators onto operators.

Finally, we need the addition of two (or more) operators, which is again a mapping from operators (a sequence of them) onto operators:

addOps[ops__] := Function[{f1}, Total@Map[#[f1] &, {ops}]];

Both addition and multiplication are mapped back to their usual meaning in these functions, by defining how the combined new operators act on a test function f1 (which is in turn a function of x, y, and z - depending on the dimension).

To illustrate the way these operations are used, take the example in the question,

$\left(\partial_x+\partial_y+z\right)x\psi$

and write it with our syntax:

addOps[dx, dy, multiplyOp[z, Identity]]@(x ψ[x, y])

$x \psi ^{(0,1)}(x,y)+x \psi ^{(1,0)}(x,y)+\psi (x,y)+x z \psi (x,y)$

This is the correct result (the result quoted originally in the post was actually missing an x).

Note how I added the scalar z above: in this syntax, it first has to be made into an operator using multiplyOp[z, Identity]. The Identity operator is very useful for this.

Of course these expressions with addOps and multiplyOp aren't as easy to read as the ones with simple + signs, but on the bright side it can also be beneficial pedagogically to separate the "operator operations" clearly from the operations between the functions they act on.

Edit 2

In response to the comment, I'll add a nicer notation, but without modifying the last approach. So I'll simply introduce new symbols for the operations defined above, using some of the operator symbols that Mathematica knows in terms of their operator precedence, but has no pre-defined meanings for:

  • CirclePlus ⊕ typed as escc+esc
  • CircleDot ⊙ typed as escc.esc
  • CircleTimes ⊗ typed as escc*esc

I'll use them as follows:

CirclePlus[ops__] := addOps[ops];
CircleDot[scalar_, op_] := multiplyOp[scalar, op];
CircleTimes[ops__] := Composition[ops];

With this, we can now use Infix notation to write in a more "natural" fashion:

(dx ⊕ dy ⊕ z⊙Identity)@(x ψ[x,y])

$x \psi ^{(0,1)}(x,y)+x \psi ^{(1,0)}(x,y)+\psi (x,y)+x z \psi (x,y)$

As the third operator, CircleTimes ⊗, I've also defined the composition of operators. That allows us to do things like commutators:

commutator = dx ⊗ x⊙Identity ⊕ (-x)⊙Identity ⊗ dx;

I'm relying on the fact that ⊙ has higher precedence than ⊗ which in turn has higher precedence than ⊕ (according to the documentation).

As expected, the commutator is unity, as we can check by applying to a test function:

commutator@f[x]

f[x]

share|improve this answer
    
very nicely done. I imagine it would be possible to unprotect and modify the addition and multiplication signs to make this simpler to read? –  Andrew Spott May 3 '12 at 22:00
    
@AndrewSpott I've added a more readable notation in a way that doesn't require unprotecting Times and Plus, so the symbols used for operators are still distinct from the usual ones, but more intuitive (I hope) than before. –  Jens May 4 '12 at 7:06
    
thanks! that is really slick. The commutator is actually what I'm interested in, thanks. –  Andrew Spott May 4 '12 at 7:09
add comment

This simple solution will work only on conmutative operators:

applyOp[anything_] := 
     Expand[anything] //. Times[d : Except[_Function] .., a__Function] 
                          :> (Composition[a][Times[d]])

And defining operators like Jens:

dx := D[#, x] &
dy := D[#, y] &

But no need to define z as operator. You can do:

applyOp[(dx + dy + z) (x psi[x, y, z])]
(* --->
psi[x,y,z]+x z psi[x,y,z]+x (psi^(0,1,0))[x,y,z]+x (psi^(1,0,0))[x,y,z]
*)

EDITED: Composition of operators is only on conmutative operators, derivatives are not.

share|improve this answer
    
Your last example uses non-commuting operators (dx and x don't commute, nor do dy and y) and therefore violates the restriction you identified yourself (try da := D[#,a]&; applyOp[da a] to see a result which you surely didn't expect). However your suggestion has a more important flaw: You do not distinguish between the operator and the function it is applied to. Most importantly, the operator $\partial_x f(\hat x)$ is not the same as the operator $f'(\hat x)$, but equals the operator $(f'(\hat x) + f(\hat x)\partial_x)$. –  celtschk May 3 '12 at 8:28
    
@celtschk you are totally right. I should not answer at nights... I will change it to a non-conmutative way. –  FJRA May 3 '12 at 13:05
add comment

Since no one mentioned it yet, Through can do something similar:

(Derivative[1, 0] + Derivative[0, 1])[f] // Through

will evaluate to

Mathematica graphics

share|improve this answer
add comment

Something like this

f = D[#, x] + D[#, y] + z # &

seems to work. Use as follows:

f[x ψ[x, y, z]]

to give

$x \psi ^{(0,1,0)}(x,y,z)+x \psi ^{(1,0,0)}(x,y,z)+x z \psi (x,y,z)+\psi (x,y,z)$

share|improve this answer
add comment

Not sure if this is what you want. Anyway:

d[psi_[a_, b_, c_]] := D[psi, a] + D[psi, b] + c psi

p[x_, y_, z_] := x + y;

d[p[x, y, z]]
(*
-> 2 + (x + y) z
*)
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.