I am using NCAlgebra but I am open to any solution. I would like to simplify some expressions with many terms (a few dozens) using:

  • the fact that each term is a scalar (like $v^\top M v$ with $v$ vector and $M$ matrix), hence symmetric;
  • the symmetry and skew-symmetry of some variables.

For example, if $v$ is a vector, $M$ a symmetric matrix, $K$ a skew-symmetric matrix, we may want to simplify $v^\top MKv - v^\top KM v$ as $2v^\top MKv$, because $$\mathbb{R}\ni v^\top KM v = (v^\top KM v)^\top = v^\top M^\top K^\top v = -v^\top M K v.$$

How can I do that in Mathematica ? (below, tp is the transpose in NCAlgebra)

expr = tp[v] ** m ** k ** v - tp[v] ** k ** m ** v

3 Answers 3


You can use TensorReduce to do this. Your assumptions:

$Assumptions = v \[Element] Vectors[d] && 
    M \[Element] Matrices[{d,d}, Reals, Symmetric[{1,2}]] &&
    K \[Element] Matrices[{d,d}, Reals, Antisymmetric[{1,2}]];

Your expression is:

expr = v.M.K.v - v.K.M.v;

TensorReduce works best with TensorProduct/TensorContract objects instead of Dot objects. Use the "ToTensor" ResourceFunction to convert:

t = ResourceFunction["ToTensor"] @ expr

2 TensorContract[ K \[TensorProduct] M \[TensorProduct] v \[TensorProduct] v, {{1, 3}, {2, 5}, {4, 6}}]

(Internally, "ToTensor" uses TensorReduce). Now, convert back to a Dot representation using "FromTensor":

r = ResourceFunction["FromTensor"] @ t

2 v.Transpose[K].M.v

This is basically what you wanted. A further simplification is possible using TensorReduce:


-2 v.K.M.v

  • $\begingroup$ Thanks a lot, that's a very convenient tool. The only "issue" I have with this approach is that it does not gather similar terms when the expression is long: a.r.r.k.r.r.a/(2 n^4) - (4 Cos[n] a.r.r.k.r.r.a)/n^4 - (2 a.r.r.k.r.r.a Sin[n])/n^3 (with $Assumptions = a \[Element] Vectors[d] && k \[Element] Matrices[{d, d}, Reals, Symmetric[{1, 2}]] && r \[Element] Matrices[{d, d}, Reals, Antisymmetric[{1, 2}]] && n \[Element] Reals). It's basically the same problem I had with **, see mathematica.stackexchange.com/questions/214043/…. $\endgroup$
    – anderstood
    Feb 7, 2020 at 9:04

This is a possibility that should work in cases of the expanded form "sum of noncommutative products". It works by extracting each NC product, transposing it, summing al the terms back and comparing the LeafCount after having applied the rules for symmetry and skew-symmetry with the LeafCount before transposing.

The symmetric variables are symVars, the skew-symmetric ones are skewSymVars.

mySimplify[expr_, symVars_: {}, skewSymVars_: {}] := Block[{level = Level[expr, 1]},
rules = Thread[tp /@ symVars -> symVars]~Join~Thread[tp /@ skewSymVars -> -skewSymVars];
i = 1;
While[i <= Length@level,
 temp = ReplacePart[level, i -> tp[level[[i]]]];
 If[LeafCount@Total@(temp /. rules) < 
   LeafCount@(Total@level /. rules), level = temp];
 i += 1;
Total@level /. rules

For the example in the OP:

 mySimplify[tp[v] ** m ** k ** v - tp[v] ** k ** m ** v, {m}, {k}]
 (* 2 v^T ** m ** k ** v *)

Please do not hesitate to post if you have remarks/better solutions!


If you have a single relationship that you would like to enforce

tp[v] ** m ** k ** v -> tp[v] ** k ** m ** v

then you can apply that as a rule and your expression will simplify. For example:

expr = tp[v] ** m ** k ** v - tp[v] ** k ** m ** v
NCReplaceAll[expr, tp[v] ** k ** m ** v -> tp[v] ** m ** k ** v] 

will evaluate to zero.

However, I suspect that you were hoping for something more generic that would automatically parse all such products and simplify for you. That is a surprisingly difficult task to do with noncommutative algebra. It would require you to normalize the expressions, which could only be done if you have the notion of ordering among your letters. For example, that

tp[v] ** b ** a ** v -> tp[v] ** a ** b ** v

and not vice versa. That would also require ordering among things like tp of a symbol, and so on. You can handle such problems in the context of NC Grobner basis, which are also built in NCAlgebra, but you would first have to define an ordering for your symbols. It might be overkill for what you want to do though. It might be worth it depending on how many such things you would need to simplify.


Your Answer

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

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