# Canonical way to map a function to diagonal elements of a square matrix?

What is the Canonical way to map a function to only the diagonal elements of a matrix?

For example, given

 A = {{E, 0}, {0, E}}


I wanted to take the log of the diagonal elements only to obtain {{1, 0}, {0, 1}}

I came up with these

 MapAt[Log[#] &, A, Table[{i, i}, {i, Length[A]}]] result = Log[Diagonal[A]];
ReplacePart[A, {i_, i_} :> result[[i]]] Since in Mathematica the rule of thumb is that there should be at least 10 different ways to do the same thing, I think there is room to find a better approach.

• Maybe using MapIndexed rather than MapAt ? – b.gates.you.know.what Apr 20 '20 at 10:23
• Also possible : ReplacePart[A, {i_, i_} :> Log[A[[i, i]]]] – andre314 Apr 20 '20 at 10:34

Using b.gates.you.know.what's idea:

With[{f = Log},
MapIndexed[Function[{x, id}, If[Equal @@ id, f[x], x]], A, {2}]]


Using an undocumented function:

res = A;
With[{f = Log}, LinearAlgebraPrivateSetMatrixDiagonal[res, f[Diagonal[res]]]];
res


Note that this function modifies matrices given to it, so you'll need to make a copy if you still need the starting matrix.

A modification of a method given by Leonid Shifrin in Mathematica programming: an advanced introduction

A// MapThread[ReplacePart, {#, Log@Diagonal[#], Range[Length@#]}]&


{{1, 0}, {0, 1}}

There is a discussion in this old SO question: Changing the Diagonals of a Matrix with Mathematica

I don't know if there are 10 different ways, but here's a third.

A - DiagonalMatrix[Diagonal[A]] + DiagonalMatrix[Log[Diagonal[A]]]