# Find matrix´s diagonal as fast as the Diagonal[]?

Posted 2 years ago
3458 Views
|
4 Replies
|
3 Total Likes
|
 Hello community.I am studying different ways to find the diagonal of a matrix without using the Diagonal command, just for an operations study, of course I can use Diagonal[], but I wonder if there is a way to simulate this command using other commands, just so that I can learn more about the WL language.For example the matrix a (10000 x 10000) defined by: SeedRandom[1234] n = 10000; a = Table[RandomInteger[9, n], n]; To have a basis of comparison for the study, I get the performance of the Diagonal command: Diagonal[a]; // AbsoluteTiming Some attempts (all were slower than Diagonal[]): Map[a[[#, #]] &, Range@n]; // AbsoluteTiming  Table[a[[i, i]], {i, Length@a}]; // AbsoluteTiming  Edited1: I think I've found a better way than the ones I've tried so far: Extract[Table[{i, i}, {i, Length@a}]][a]; // AbsoluteTiming But it still takes about more than twice the time of Diagonal[].What other ways to find the diagonal of a matrix that are faster than these attempts above without using the Diagonal command? I would love to learn other ways, I could only think of those two ways. Could it also be that, even using Part, there is a faster and simpler way that I haven't thought of? Can anyone teach me others ways (even if they are slower than Diagonal[])? I will be very grateful if anyone can help! Thanks.
4 Replies
Sort By:
Posted 2 years ago
 I'll leave the extensive testing up to you, as I am currently not able to, but back when Diagonal[] was not yet implemented, one used either Tr[mat, List] or Transpose[mat, {1, 1}] for the purpose of extracting diagonal elements. A reason to use the latter construct even now, if not for speed, is that it is compilable, as opposed to Diagonal[].
Posted 2 years ago
 Thank you so much for the reply J.M.Tr[] and Transpose[] I had not thought of as a means of finding the diagonal ... they are really very simple and easy to to get the diagonal, very good. Tr[] had the same performance as Map[] at speed: Tr[a, List]; // AbsoluteTiming Now Transpose[], in the speed test, was intermediate between Extract[] and Table[], at least in this large matrix: Transpose[a, {1, 1}]; // AbsoluteTiming The biggest performance I had in speed was when I replaced the Table[] from within Extract[] with Transpose[] as follows: Extract[Transpose@ConstantArray[Range@Length@a, 2]][ a]; // AbsoluteTiming The result has not yet reached the speed of Diagonal[], it took almost 40-50% more time, but for now it was the best result.Thanks J.M. for the ideas! And if you or anyone in the community has any other way, please, I'd love to hear from you.
 A thing you might have to account for in your performance checks is that Table[RandomInteger[9, n], {n}] will not generate a packed array (see this as well), in contrast to the more orthodox RandomInteger[9, {n, n}]. Additionally, you might also wish to look at SparseArray[] objects with either sparse or dense diagonals.