Elegant method of generating this matrix?
Update: here Table
is faster and more user-friendly then Array
.
mat[n_] := LowerTriangularize@Table[2 (1 + Boole[j > 1]) (i - 1) Mod[i + j, 2],
{i, n}, {j, n}];
mat[10] // MatrixForm
It is fast and the result is packed array
mat[1000] // Developer`PackedArrayQ // AbsoluteTiming
(* {0.142522, True} *)
None of the above are particularly "efficient", if that's your goal. By way of example,
mat = Module[{p1 = Range[0, 2 # - 2, 2], p2},
p2 = p1*2;
p1[[1 ;; ;; 2]] = 0;
p2[[2 ;; ;; 2]] = 0;
LowerTriangularize@Transpose[PadRight[{p1}, #, {2 p1, p2}]]] &;
mat[200];//Timing
(*
{0., Null}
*)
And that's on an old netbook. Compared to fastest of the answers so far (the rest ranged from slower to unusably slow):
Update: A faster method, dispenses with the most expensive operation of above, ~2x speed, averaged ~30X faster than fastest answer so far, 72X faster peak, under the range of tests in updated graph (Again, on an old netbook, I'd expect bigger difference w/ more cores...):
The new method:
newmat = Module[{p1 = Range[0, 2 # - 2, 2], p2},
p2 = p1;
p1[[1 ;; ;; 2]] = 0;
p2[[2 ;; ;; 2]] = 0;
LowerTriangularize@Join[Transpose@{p1},
ArrayPad[Transpose[{2 p2, 2 p1}], {{0, 0}, {0, # - 3}}, "Periodic"], 2]] &;
Here is my version using SparseArray
:
mat2[n_]:=SparseArray[{{i_,j_}/;And[i>j,Mod[i+j,2]==1]:> If[j==1,2,4](i-1)},{n,n},0.];
MatrixForm@mat2[10]