Finding if a matrix is square

I have a matrix which is constructed element by element through some iterations, and thus can be non-square. If it's not square, then I want to make it square filling with 0. Is there a function to determine if a matrix is square?

I was thinking of something like this:

(* If determinant of matrix is possible, then fill with 0s, else do nothing. *)
If[Det[matrix]=Indeterminate,Fillwithzeros[matrix]]

I'm pretty sure Det[matrix] = Indeterminate is not a correct way to express my thoughts, so maybe you could help me out with my syntax or even suggest a better way to do it :D

Thanks!

• What about Dimensions and some ArrayPad? – Yves Klett May 13 '14 at 17:14
• Compare Equal @@ Dimensions[{{0, 0}, {0, 0}}] and Equal @@ Dimensions[{{0, 0}, {0, 0}, {0, 0}}] :) – Öskå May 13 '14 at 17:16
• BTW: Det[matrix]=Indeterminate is trying to set the value of Det[matrix] equal to Indeterminate not test if it is. Testing if A equals B is written ==. However Indeterminate is a symbol so you need === in that case. – Ymareth May 13 '14 at 17:27
• @SaxoMikoMola and where would you like the fill the rectangle matrix? – Öskå May 13 '14 at 17:40
• In V10, there is/will be SquareMatrixQ – Michael E2 May 13 '14 at 18:08

If you are concerned about the case where you list of lists has unequal length sublists then you should first do MatrixQ:

MatrixQ[#] && MatchQ[  Dimensions[#] , {_ ..}] &@ RandomInteger[10,{3,3}]
True

or

MatrixQ[#] && Equal @@ Dimensions@# &@{{1, 2, 1}, {1, 4, 4}, {4, 5, 4}}
True

Normal@SparseArray[#, ConstantArray[Max@Dimensions@#,2]] &@ RandomReal[1, {4, 2}]

Here is what I would propose, but it can probably be faster:

filling[mat_] := If[Equal @@ Dimensions@mat, mat,
If[Less @@ Dimensions@mat,
Join[mat, SparseArray[{}, {1, Max@Dimensions@mat}]],
PadRight[mat[[#]], Max@Dimensions@mat] & /@ Range@Max@Dimensions@mat]]

where the test on the matrix squareness¹ is not needed.

mat[m_, n_] := RandomInteger[{0, 10}, {m, n}]

Examples:

SeedRandom@10;
mat[3, 2] // MatrixForm

$\left( \begin{array}{cc} 10 & 10 \\ 9 & 7 \\ 8 & 6 \\ \end{array} \right)$

SeedRandom@10;
filling[mat[3, 2]] // MatrixForm

$\left( \begin{array}{ccc} 10 & 10 & 0 \\ 9 & 7 & 0 \\ 8 & 6 & 0 \\ \end{array} \right)$

SeedRandom@2;
mat[2, 3] // MatrixForm

$\left( \begin{array}{ccc} 8 & 4 & 5 \\ 4 & 7 & 4 \\ \end{array} \right)$

SeedRandom@2;
filling[mat[2, 3]] // MatrixForm

$\left( \begin{array}{ccc} 8 & 4 & 5 \\ 4 & 7 & 4 \\ 0 & 0 & 0 \\ \end{array} \right)$

Timings:

filling[mat[10000, 9999]]; // AbsoluteTiming
{1.897158, Null}
filling[mat[9999, 10000]]; // AbsoluteTiming
{1.651018, Null}
filling[mat[10000, 10000]]; // AbsoluteTiming
{1.253314, Null}

The last being approximately equivalent to mat[10000, 10000]; // AbsoluteTiming

¹ squareQ = Equal @@ Dimensions@# &;

pad = With[{dim = Dimensions@#},
If[Equal @@ dim, #, ArrayPad[#, {{0, 0}, Abs[dim - Max@dim]}\[Transpose]]]] &;

pad @ RandomReal[1, {4, 2}] // MatrixForm Edit this version is going to work with multidimensional matrices too :)

pad = With[{dim = Dimensions@#},
If[Equal @@ dim, #, ArrayPad[#, {0 dim, Abs[dim - Max@dim]}\[Transpose]]]] &;

pad @ RandomReal[1, {3, 2, 3, 2}] // MatrixForm • Damn, I was really wondering how to use ArrayPad, I guess I was missing the Abs[dim - Max@dim] part.. :) – Öskå May 13 '14 at 19:21
• @Öskå Thanks :P I was looking for more compact way but I've failed :( – Kuba May 13 '14 at 19:23
• It's already quite compact compared to mine :P I feel stupid now for not handling ArrayPad :) – Öskå May 13 '14 at 19:25
• @Öskå now George made me stupid ;P – Kuba May 13 '14 at 19:41