Change matrix elements at specific locations?

Let's say I have an array

a={{1,2,3},
{4,5,6},
{7,8,9}}


I want to have all elements along the diagonal multiplied by 2.

{{2,2,3},
{4,10,6},
{7,8,18}}


What is the best way to do this? I tried

ReplacePart[a,{i_,i_} -> 2 a[[i,i]]]


and

a[[i_, i_]] = 2 a[[i, i]]


Which both gives the error

Part::pkspec1: The expression i cannot be used as a part specification


I suppose I can do

a*SparseArray[{i_,i_} -> 2,{3,3},1]


but I feel like there should be a simpler way to do this.

• use RuleDelayed instead of Rule: ReplacePart[a, {i_, i_} :> 2 a[[i, i]]]
– kglr
Mar 10, 2015 at 19:31
• and use Part as (a[[#, #]] = 2 a[[#, #]]) & /@ Range[3]; a or Table[a[[i, i]] == 2 a[[i, i]], {i, 1, 3}]; a
– kglr
Mar 10, 2015 at 19:34

Using RuleDelayed instead of Rule in ReplacePart:

ReplacePart[a, {i_, i_} :> 2 a[[i, i]]]


or, using Part assignment as in:

(a[[#, #]] = 2 a[[#, #]]) & /@ Range[3]
Table[a[[i, i]] == 2 a[[i, i]], {i, 1, 3}]


or, using MapAt:

MapAt[2 # &, a, Table[{j, j}, {j, 3}]]


or, using MapIndexed:

MapIndexed[If[SameQ @@ #2, 2 #, #] &, a, {2}]
(* or MapIndexed[If[Equal @@ #2, 2 #, #] &, a, {2}] *)


all give

(* {{2, 2, 3}, {4, 10, 6}, {7, 8, 18}} *)


By the way, my favorite is your a*SparseArray[{i_,i_} -> 2, {3,3}, 1].

• Thanks a lot! I didn't know anything about RuleDelayed. Now I see why my code didn't work. Mar 11, 2015 at 4:38
a = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}}

f = # + #*IdentityMatrix[Dimensions@#] &;

f@a

(* {{2, 2, 3}, {4, 10, 6}, {7, 8, 18}} *)


Since all the good answers are taken, here is one for fun

m =  {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};


In this case, since the multiplier happened to be 2, you can just do

   LowerTriangularize[m] + UpperTriangularize[m]


and the diagonal will be doubled automatically. But this is only for this example only. In the general case

n=2; (*or any other value*)
DiagonalMatrix[n*Diagonal[m]] + LowerTriangularize[m, -1] + UpperTriangularize[m, 1]