# Let NCAlgebra know that Tr[] commutes

I have an expression where there are terms like

a ** (b*Tr[a ** b])


and I want to simplify it to something like

Tr[a ** b]a ** b


How can it be done? I have tried with NCExpand and haven't worked.

• Strictly speaking, it is "cyclic". Nov 27, 2020 at 0:35
• I mean, it is cyclic in the argument but the result is an scalar and it then commutes, isn't it? Nov 27, 2020 at 9:49

See my edits for my earlier submission.

• Can you edit your posted answer with this? That is the better way to do this. If not, I suggest you do this or post this as a comment. It might be helpful if you included a successful test input/output, also. Nov 28, 2020 at 5:00
• Ok, it worked even though I had to unprotect the symbol Tr with Unprotect[Tr], which could be risky isn't it? Thanks! Nov 28, 2020 at 12:27

Edited: The command SetCommutative[Tr] forces all of the expressions whose head is Tr to be considered commutative.

If necessary, you can use UnProtect[Tr];SetCommutative[Tr];Protect[Tr];.

Another solution is Tr/:CommutativeQ[Tr[x_]] := True;

• Shouldm't it be the other way around? SetCommutative[Tr] . Either way it doesn't work for me. With SetNonCommutative[Tr] I get WARNING: Symbol Tr is protected. You should seriously consider not setting it as noncommutative and with SetCommutative[Tr] I get UpSet::write: Tag Tr in CommutativeQ[Tr] is Protected. Nov 27, 2020 at 9:46
• Got the answer backward. See the other solution which I posted. Dec 2, 2020 at 16:02

In NCAlgebra, expressions are considered commutative only if the Head and all arguments are commutative. That is why using SetCommutative[Tr] will fail in this case. If Tr is commutative, Tr[x] will still be noncomutative if x is noncommutative. However, I would not recommend that you add rules to CommutativeQ. That can become messy. Instead use the brand new command SetCommutativeFunction which is available with the version 5.0.6 of NCAlgebra. I would also discourage you from using the built in protected symbol Tr. For example,

SetCommutativeFunction[trace];
a ** (b*trace[a ** b])


would evaluate to

trace[a ** b] * a ** b

as you want. By the way, I also implemented an operator tr that has the properties of the standard matrix trace. You might want to give it a try.