# Cyclic Noncommutative Multiplication

I work with traces of long matrix products and I want mathematica to employ the cyclicity when simplifying.

I use this redefinition of the non-commutative multiplication:

Unprotect[NonCommutativeMultiply];
Clear[NonCommutativeMultiply]

(*Factor out numerics-- could generalize to some ScalarQ*)
nc : NonCommutativeMultiply[a__] /; MemberQ[{a}, _?NumericQ] :=
NCMFactorNumericQ[NCM[a]] /. NCM -> NonCommutativeMultiply

(*Simplify Powers*)
b___ ** a_^n_. ** a_^m_. ** c___ :=
NCM[b, a^(n + m), c] /. NCM -> NonCommutativeMultiply

(*Minus*)
NonCommutativeMultiply[a___, b_Times, c___] :=
NCMFactorNumericQ[NCM[a, Sequence @@ b, c]] /.
NCM -> NonCommutativeMultiply
Protect[NonCommutativeMultiply];

Unprotect[NCM];
Clear[NCM]
NCMFactorNumericQ[nc_NCM] :=
With[{pos = Position[nc, _?NumericQ, 1]},
Times @@ Extract[nc, pos] Delete[nc, pos]]
NCM[a_] := a
NCM[] := 1
Protect[NCM];


which was given as an answer to this question and is very helpful, but I want it to be able to cancel A**B**C with -B**C**A (but only if these matrices stand alone, i.e. I don't want it to cancel A**B**C**D with -B**C**A**D). Any help would be greatly appreciated.

• Beware! By default, ** is associative, but one implication of the last statement is that your multiplication is not. Thus, even an expression like A**B**C is not well-defined, because it could mean either (A**B)**C or A**(B**C). You probably should not be thinking of your manipulations with traces as resulting from a binary operation at all. Dec 13, 2012 at 15:25
• Good point, @whuber . I was thinking something along the lines of letting it check if what is left and right is a one (then it can cycle) or something else (then it can't). On the other hand, I don't really need it to be encoded in the multiplication itself. I'd be perfectly happy with a newly defined trace that I can apply on my expressions and that knows that cyclic permutations are identical. Dec 13, 2012 at 16:41

NCAlgebra supports a trace type operator. It will automatically reduce

tr[a ** b ** c - b ** c ** a]


to

0

and

tr[a ** b ** c ** d - b ** c ** a ** d]


tr[a ** b ** c ** d] - tr[a ** d ** b ** c]

It achieves that by automatically canonizing the sorting of the arguments or tr.

P.S.: We are in the process of updating NCAlgebra so you might want to try our latest beta version from here, which you can install as a paclet.