# How to create an Identity matrix and replace the ''1''s with n which n is the elements' row or column number?

I want to create a n by n Identity matrix and replace the ones with n π^2. NOS is three here (it is a number). The code I have written for this doesn't work.

Kin = IdentityMatrix[NOS]

n = 1; m = 1; While[n == m && n < NOS &&  m < NOS,
Kin[[n, m]] -> n π^2; n++; m++]


I want

Kin[[1, 1]]== π^2
Kin[[2, 2]]==2 π^2


and so on. Could anyone help me with this please?

• try Pi^2 DiagonalMatrix[Range[NOS]]
– kglr
Jun 14 '17 at 0:32
• @klgr Thanks a lot, It works Jun 14 '17 at 0:34

It is far faster to make the multiplication by a vector and then convert to a diagonal matrix, rather than building a full matrix and multiplying after:

DiagonalMatrix[π^2 Range[3]]


$\left( \begin{array}{ccc} \pi ^2 & 0 & 0 \\ 0 & 2 \pi ^2 & 0 \\ 0 & 0 & 3 \pi ^2 \\ \end{array} \right)$

Even faster is to build a sparse array, which is done by applying SparseArray before (inside) DiagonalMatrix. With this formulation multiplicaiton after is fast because only specified elements (the diagonal) are actually multiplied.

π^2 DiagonalMatrix[Range[1000]];                // RepeatedTiming // First
DiagonalMatrix[π^2 Range[1000]];                // RepeatedTiming // First
π^2 DiagonalMatrix[SparseArray @ Range[1000]];  // RepeatedTiming // First

0.434

0.01

0.000647


The examples above preserve the diagonals in Symbolic form. If machine reals(1) are OK:

π^2 DiagonalMatrix[Range[1000]];                // RepeatedTiming // First
DiagonalMatrix[π^2 Range[1000]];                // RepeatedTiming // First
π^2 DiagonalMatrix[SparseArray @ Range[1000]];  // RepeatedTiming // First

0.0040

0.00174

0.0000231


Reference:

• Can you explain why the SparseArray[] solution is faster? Jun 14 '17 at 4:03
• @AnjanKumar It is a much smaller expression being created, here about 1/144 the size of the dense array. Because of the use of exact π^2 the array cannot be packed (in the plain case), so fast library operations cannot be used. π^2 DiagonalMatrix[Range[1000]]; (note the backtick) takes only 0.00371 on my machine because everything remains packed and fast library functions are used. Jun 14 '17 at 9:58
• I should add the note that there is an undocumented syntax for directly producing a sparse diagonal matrix: DiagonalMatrix[π^2 Range[3], 0, 3, SparseArray] Mar 29 '19 at 10:33
NOS = 3;

π^2 DiagonalMatrix[Range[NOS]]
π^2 Range[NOS] IdentityMatrix[NOS]
MapIndexed[π^2 #2[[1]] # &, IdentityMatrix[NOS], {2}]
ReplacePart[IdentityMatrix[NOS], {i_, i_} :> (i π^2)]
Block[{i = 1}, IdentityMatrix[NOS] /. 1 :> (π^2 i++)]


all give

{{π^2, 0, 0}, {0, 2 π^2, 0}, {0, 0, 3 π^2}}

here is another way using Unitize

π^2 Table[i (1 - Unitize[Range[1000] - i]), {i, 1000}]; // AbsoluteTiming
(* {0.552622, Null} *)


and with SparseArray alone:

π^2 SparseArray[{i_, i_} :> i , {1000, 1000}];//AbsoluteTiming
(* {0.00134081, Null} *)


Borrowing the backtick from @Mr.Wizard significantly improves the answer

π^2 Table[i (1 - Unitize[Range[1000] - i]), {i, 1000}]; // AbsoluteTiming
(* {0.0230811, Null} *)

π^2 SparseArray[{i_, i_} :> i, {1000, 1000}]; // AbsoluteTiming
(* {0.000165618, Null} *)

• Which version are you using? For the first line I get 0.43793 and for the second 0.000658. What timings do you get for the six lines in my answer, please? Jun 14 '17 at 10:06
• @Mr.Wizard thanks for picking it out. I think for the first one i used the timing from Range[100] rather than 1000. I just updated it Jun 14 '17 at 10:18
• Table just seems unnecessarily baroque and honestly I'd leave it out if I were you, but +1 for the concise SparseArray form. It's not quite as fast as DiagonalMatrix with a sparse argument but I doubt it matters. FWIW SparseArray[{i_, i_} :> i Pi^2, {1000, 1000}] also works. Jun 14 '17 at 12:04