I am looking for a way to define anti-commuting numbers (variables) in Mathematica. Let say we have a set of four variables like ${x_1,x_2,x_3,x_4}$ from which I need to get all possible permutations, then multiply them so they appear as a sum as

$\qquad x_1*x_2*x_3*x_4+x_1*x_2*x_4*x_3+(22\,{\rm terms})$

But these variables are Grassmann anti-commutative, so whenever we interchange any two of them we should get a negative sign, i.e., $x_1*x_2 = -x_2*x_1$, for example the above expression should appear as

$\qquad x_1*x_2*x_3*x_4-x_1*x_2*x_4*x_3+(22\,{\rm terms})$

I know how to permute the variables, but I do not know how get their signs correctly. Any ideas?

  • $\begingroup$ Your 2nd expression, it should be $x_1*x_2*x_3*x_4-x_1*x_2*x_3*x_4+(22\,{\rm terms})$, and reduce to just $(22\,{\rm terms})$, right? $\endgroup$
    – m_goldberg
    Dec 1, 2017 at 5:04

3 Answers 3


I've been adding to the implementation above for the purposes of understanding Grassmann variables (and Grassmann integration) a bit better. Here are my additional contributions.

(*Linearity of addition:*)
(*Scalars come out. Define C[i] symbols to be scalars. *)
NonCommutativeMultiply[H___,Times[c_,A__],T___]:=c NonCommutativeMultiply[H,Times[A],T]/;ScalarQ[c]
NonCommutativeMultiply[H___,c_,T___]:=c NonCommutativeMultiply[H,T]/;ScalarQ[c];
(* Allow NonCommutativeMultiply[\[Psi]] to simplify to \[Psi] *)
(*One-way flatness:*)
(*Canonical ordering:*)
(*Squares vanish:*)
(* 1**2**3 should simplify to 6, not Times[6,NonCommutativeMultiply[]] *) 

Grassmann Integration definitions. I work with the convention integral(dx x) = 1, where the differential comes first.

(* Linearity of addition: *)
(* Scalars come out: *)
GrassmannIntegrate[var_,c_ y_]:=c GrassmannIntegrate[var,y]/;(FreeQ[c,var]&&FreeQ[c,NonCommutativeMultiply]);
(* Integral of a scalar is zero: *)
(* Integral of var is one: *)
(* Integral of (a___**var_**b___) is (-1)^k a___**b___: *)
GrassmannIntegrate[var_,x_NonCommutativeMultiply]:=Block[{NonCommutativeMultiply}, Replace[x,NonCommutativeMultiply[a___,var,b___]:> If[Length[{a,b}]==0,1,(-1)^(Length[{a}])NonCommutativeMultiply[a,b]]]];
(* Allow multivariable integrals. Integration is done starting with the last variable passed in, to make sure we don't swap any variables in the integration measure. So eg GrassmannMultivariableIntegrate[{a,b},a**b]\[Equal]-GrassmannMultivariableIntegrate[{b,a},a**b] *)
GrassmannMultivariableIntegrate[Most[vars], GrassmannIntegrate[Last[vars],x]]];

Testing it:

In[] := {a**a===0, 
(a**b+c**d)**(a**b+c**d)===2 a**b**c**d,
GrassmannIntegrate[a,(a-b)**(C[1]+C[2] a)]==C[1]+C[2]b
Out[] := {True,True,True,True,True,True}

Find the determinant of a matrix using differential forms:

In[]:= matrix=RandomInteger[{-10,10},{3,3}]
Out[]= {{-1,-6,3},{-3,10,-6},{-6,10,1}}
Out[]= {-dx-3 dy-6 dz,-6 dx+10 dy+10 dz,3 dx-6 dy+dz}
Out[]= -214 dx**dy**dz
Out[]= -214

I don't recommend this for production code! It's already painfully slow for a seven by seven matrix, so clearly this isn't fit for any sort of numerics. I haven't given any thought to optimization either.

In[]:= matrix=RandomInteger[{-10,10},{7,7}];
Out[]= {102.951,12754089 da**db**dc**dd**de**df**dg}

To define anti-commutative multiplication you first have to choose some canonical ordering. For this you can use for example the OrderedQ function: OrderedQ[{x[1],x[2]}] evaluates to True whereas OrderedQ[{x[2],x[1]}] evaluates to False.

Then you can define some arbitrary symbol having the appropriate properties. I normally use CenterDot because it displays nicely, but you could also use NonCommutativeMultiply (which I find has some annoying preset attributes) or anything else for that matter.

If you define

CenterDot[a___, b_, c_, d___] /; ! OrderedQ[{b, c}] := -CenterDot[a, c, b, d]

Then CenterDot[x[2], x[1], x[3], x[4]] evaluates to -CenterDot[x[1], x[2], x[3], x[4]] and so on. For your particular problem of course

Sum[CenterDot @@ x /@ p, {p, Permutations@Range@4}]

evaluates to 0, but you get the idea.

Finally, you should remember that Mathematica knows nothing a priori about this new anti-commutative multiplication, so you will probably have to define other usual properties, such as linearity, squares evaluating to zero, etc.


You probably want to use NonCommutativeMultiply, as Fidel suggests.

ClearAttributes[NonCommutativeMultiply, Flat]
(* Canonical ordering: *)
NonCommutativeMultiply[H___, B_, A_,T___] := -NonCommutativeMultiply[H, A, B, T] /; Not[OrderedQ[{B, A}]]
(* Linearity of addition: *)
NonCommutativeMultiply[H___, Plus[A_, B__], T___] := NonCommutativeMultiply[H, A, T] + NonCommutativeMultiply[H, Plus[B], T]
(* Scalars come out: *)
ScalarQ[f_] := Or[NumericQ[f]](* you can put other conditions in the Or *)
NonCommutativeMultiply[H___, Times[c_, A__], T___] := c NonCommutativeMultiply[H, Times[A], T] /; ScalarQ[c]
NonCommutativeMultiply[H___, c_, T___] := c NonCommutativeMultiply[H, T] /; ScalarQ[c]
(* Squares vanish: *)
NonCommutativeMultiply[H___, A_, M___, A_, T___] := 0
(* One-way flatness: *)
NonCommutativeMultiply[H___, NonCommutativeMultiply[M___], T___] :=  NonCommutativeMultiply[H, M, T]

Now x1**x2**x3**x4 remains as-is but x2**(x3+x1)**x4**x1 evaluates to - (x1**x2**x3**x4) (the term with x1 twice evaluated to 0).

  • $\begingroup$ Great suggestions, it solved my problem, thx $\endgroup$
    – Hawi
    Dec 2, 2017 at 14:46
  • $\begingroup$ Beware future visitors: (a**b+c**d)**(a**b+c**d)=2 a**b**c**d isn't handled properly by this implementation. $\endgroup$
    – user273
    Mar 14, 2018 at 22:33
  • $\begingroup$ If the "CanonicalOrdering" and "squares vanish" definitions are moved after "One-way flatness", the procedure simplifies correctly (assuming a,b,... are grassmann monomials). This ensures we distribute, etc. as far as possible before figuring out signs and zeros. $\endgroup$
    – user273
    Mar 14, 2018 at 22:50
  • $\begingroup$ You can also change "canonical ordering" to NonCommutativeMultiply[H__, B_, A_, T___] := -NonCommutativeMultiply[H, A, B, T] /; OrderedQ[{A, B}] NonCommutativeMultiply[H___, B_, A_, T__] := -NonCommutativeMultiply[A, B, T] /; OrderedQ[{A, B}]. But moving one-way flatness to the top is the best way to do it. $\endgroup$
    – evanb
    Mar 14, 2018 at 22:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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