Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to do a cross product involving a vector of Pauli matrices $\vec \sigma = \left( {{\sigma _1},{\sigma _2},{\sigma _3}} \right)$; for example, $\vec \sigma \times \left( {1,2,3} \right)$.

s:= Table[PauliMatrix[i], {i, 1, 3}];

The code above will not work.

The only way I can think of is to use the method which I have just learned from Mr. Wizard:

ReleaseHold @ Block[{PauliMatrix}, Hold @@ {Cross[s,{1, 2, 3}]}]

But I feel uncomfortable writing such long code to realize such a simple cross product.

Is there any better way or not?

Update J.M. give the method

Cross[Unevaluated /@ PauliMatrix[Range[3]], {a,b,c}]

But it turns out that when one of the a,b,c is zero, the code will give error. a Remedy is given by J.M in his comment.

But I am asking here why it gives right answer when a b c are all nonzero while failed with a zero component?

share|improve this question

Taking a page from kptnw's fine answer, here's one possibility:

Cross[Unevaluated /@ PauliMatrix[Range[3]], Range[3]]
share|improve this answer
I finally choose your answer. easier and won't have to worry about the order and negtive sign when using LeviCivitaTensor – matheorem May 5 '13 at 8:09
OhOh, Sorry J.M. I found peculier things. Your solution is flawed. Try Cross[Unevaluated/@PauliMatrix[Range[3]],{0,1,0}] – matheorem May 5 '13 at 8:55
Yes, I see what you mean. In that case, Cross[Unevaluated /@ PauliMatrix[Range[3]], {\[FormalP], \[FormalQ], \[FormalR]}] /. Thread[{\[FormalP], \[FormalQ], \[FormalR]} -> {0, 1, 0}] – J. M. May 5 '13 at 11:37
Ok, rule replacement works. But I still don't know where does it gone wrong? I looked into the Trace result, but it is unexpectedly long! I can't figure out why. – matheorem May 5 '13 at 12:23
FWIW the referenced question is a duplicate. – Mr.Wizard Jun 5 '13 at 6:21

Another idea to shorten the notation for the cross product in the special case where you have a Pauli matrix vector as the first argument is this:

OverVector /: Cross[OverVector[σ], x_?VectorQ] := 

Cross[OverVector[σ], {x, y, z}]

==> {{{-y, -I z}, {I z, y}}, {{x, -z}, {-z, -x}}, {{0, 
   I x + y}, {-I x + y, 0}}}

You can also literally enter $\vec{\sigma}$ instead of OverVector[σ].

If you want to make the definition of the cross product more visible in your notation, you could also introduce the LeviCivitaTensor in the form of an abbreviation $\varepsilon$ and use it instead of Cross directly:

ε = LeviCivitaTensor[3];

OverVector[σ] = PauliMatrix[Range[3]];

{x, y, z}.ε.OverVector[σ]

==> {{{-y, -I z}, {I z, y}}, {{x, -z}, {-z, -x}}, {{0, 
   I x + y}, {-I x + y, 0}}}

I've defined an abbreviation for the vector of Pauli matrices here. Because of this, the two approaches (this one and the first alternative) don't mix - so one should settle on or the other.

Edit in response to updated question

The Unevaluated trick in J.M.'s answer works without error in version 8 (that's where I tested it first, and upvoted that method initially). But it produces divide-by-zero errors in version 9. This seems like a bug to me because there are no documented changes in Cross or Unevaluated in recent versions. My LeviCivitaTensor approach works in all versions.

share|improve this answer
For people like me who've forgotten their identities: {p, q, r}.LeviCivitaTensor[3].{u, v, w} === Cross[{u, v, w}, {p, q, r}]. Note the order! – J. M. May 4 '13 at 17:36
@J.M. BTW, a related answer where I used this is: Is it possible to do vector calculus in Mathematica?. Hope you don't get into an identity crisis... – Jens May 4 '13 at 17:41
up vote 3 down vote accepted

Directly define a cross function should be the easiest.

cross3[{x_, y_, z_}, {a_, b_, c_}] := {c y - b z, -c x + a z, b x - a y}

then no matter




will be OK. No ordering problem in Jens' LeviCivitaTensor method.

share|improve this answer

Since I'm being credited with the method (which I do appreciate), let me point out that your use of Block is being needlessly complicated with Hold and ReleaseHold. The same behavior can be had with:

Block[{PauliMatrix}, Cross[s, {1, 2, 3}]]
{{{-2, -3 I}, {3 I, 2}}, {{1, -3}, {-3, -1}}, {{0, 2 + I}, {2 - I, 0}}}

We can make the Unevaluated method, similar to what I showed here and what J. M. posted above, work even with vectors containing zero by applying it to all elements. I would write it thus:

heldCross[vec__] := Cross @@ Map[Unevaluated, {vec}, {2}]


heldCross[PauliMatrix @ Range @ 3, {1, 2, 3}]
{{{-2, -3 I}, {3 I, 2}}, {{1, -3}, {-3, -1}}, {{0, 2 + I}, {2 - I, 0}}}
heldCross[PauliMatrix @ Range @ 3, {0, 1, 2}]
{{{-1, -2 I}, {2 I, 1}}, {{0, -2}, {-2, 0}}, {{0, 1}, {1, 0}}}
share|improve this answer
Happy to see you! Thank you very much! you're right, I realized how stupid I am at that time. But this method only works in the situation when s is setdeleyed as Table[PauliMatrix[i],{3}], it will not gonna work if s is not setdeleyed or `PauliMatix[Range[3]]. So let me just stick with my answer below, it is quite straightforward which makes it seems a little "silly", but to my experience, it is quite robust. – matheorem Jun 5 '13 at 5:59
@matheorem Hardly stupid; a mere mistake. :-) Normally I would have recommended Unevaluated as J. M. did, but I see that method breaks with zeros. I am looking into that now. (The Trace is indeed long.) – Mr.Wizard Jun 5 '13 at 6:11
Awesome. But can you explain why J.M.'s solution is flawed when there is zero. By the way, J.M. changed his name to 0x4A4D??!!! – matheorem Jun 5 '13 at 7:52
@matheorem I didn't see anything obvious and I didn't feel like working on it right now. Yes, he did; I guess he's feeling pallid. – Mr.Wizard Jun 5 '13 at 8:00
So it is a chinese character. Wow, that's interesting. I know a lot of chinese characters, actually I am a chinese. But I can bet, this character is not known by 99.99% chinese people. – matheorem Jun 5 '13 at 8:16

Much has already been said about this problem, but maybe this solution still might be helpful.

First we define an auxiliary vector

In[18]:= va = Array[a, 3]

Out[18]= {a[1], a[2], a[3]}

with which it is trivial to calculate the cross product:

In[19]:= Cross[va, {1, 2, 3}]

Out[19]= {3 a[2] - 2 a[3], -3 a[1] + a[3], 2 a[1] - a[2]}

Now we replace the components of va by the Pauli matrices which gives us the final result

In[20]:= % /. Table[a[i] -> PauliMatrix[i], {i, 1, 3}]

Out[20]= {{{-2, -3 I}, {3 I, 2}}, {{1, -3}, {-3, -1}}, {{0, 2 + I}, {2 - I, 0}}}

In compact form, and for an arbitrary vector {u,v,w} instead of {1,2,3} we have

In[41]:= Cross[
  Array[a, 3], {u, v, w}] /. ((a[#] -> PauliMatrix[#]) & /@ Range[3])

Out[41]= {{{-v, -I w}, {I w, v}}, {{u, -w}, {-w, -u}}, {{0, I u + v}, {-I u + v, 0}}}

Regards, Wolfgang

share|improve this answer

Here's a method that uses LeviCivita and defines the cross product in terms of its index notation expression:

Cr[ms_, a_] := Map[Sum[
    LeviCivitaTensor[3][[#, j, k]] ms[[j]] a[[k]], 
    {j, Range[3]}, 
    {k, Range[3]}
    ] &, Range[3]] /; 3 == Length[ms] == Length[a]

In dimensions other than 3, the analogously defined cross product is not a vector, so this definition is meaningless in that case.

Cr[PauliMatrix /@ Range[3], {1, 2, 3}]
    (* {{{-2, -3 I}, {3 I, 2}}, {{1, -3}, {-3, -1}}, {{0, 2 + I}, {2 - I, 0}}} *)
Cr[a /@ Range[3], b /@ Range[3]]
    (* {-a[3] b[2] + a[2] b[3], a[3] b[1] - a[1] b[3], -a[2] b[1] + a[1] b[2]} *)
share|improve this answer

Your Answer


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.