4
$\begingroup$

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.

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

3 Answers 3

5
$\begingroup$

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].

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

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

f@a

(* {{2, 2, 3}, {4, 10, 6}, {7, 8, 18}} *)
$\endgroup$
1
$\begingroup$

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

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

Mathematica graphics

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

   LowerTriangularize[m] + UpperTriangularize[m]

Mathematica graphics

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]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.