I have a list of 2 by 2 matrices and I want the list of their traces. I have been using
Map[Tr,mylistofmatrices] But I wonder if there is a way to make Tr Listable so I can just call
Tr[mylistofmatrices] I have a list of 2 by 2 matrices and I want the list of their traces. I have been using
Map[Tr,mylistofmatrices] But I wonder if there is a way to make Tr Listable so I can just call
Tr[mylistofmatrices] No, there isn't. There are several reasons for that:
Tr operates on tensors of arbitrary rank, not just matrices
Listable functions will automatically thread to the deepest level of lists, so if you set Tr to be Listable, it'll individually wrap each deepest element of a nested list, e.g. Tr[{{1,2},{3,4}}] would transform to {{Tr[1], Tr[2]}, {Tr[3], Tr[4]}}.
Just use Map, which is unambiguous and takes just one extra character to type ... Tr /@ list vs Tr @ list.
If you have version 10 or later you can use operators forms, i.e. Map[Tr] acts as a function:
mylistofmatrices = {{{a, b}, {c, d}}, {{q, r, s}, {t, u, v}}}; Map[Tr][mylistofmatrices] {a + d, q + u}
This is a subtle difference but it may be useful nevertheless.
If you always want the trace of a tensor with a specific array depth you can check for that. If you want only a two-dimensional tensor (which is what you state in your question) you can use MatrixQ; otherwise look at ArrayDepth and TensorRank. One implementation:
myTr[m_?MatrixQ] := Tr[m] myTr[{m__?MatrixQ}] := Tr /@ {m} Now:
myTr @ foo myTr @ {1, 2, 3} myTr @ {{a, b}, {c, d}} myTr @ mylistofmatrices myTr[foo] myTr[{1, 2, 3}] a + d {a + d, q + u}
TensorRank[], how very odd. "Introduced in 2012 (9.0)", and yet it's been around since the first version, and at one point "replaced by ArrayDepth". $\endgroup$ TensorRank[], so reading that "new" bit gave mixed emotions. :) Oh well, glad that it's "back". $\endgroup$