1
$\begingroup$

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!

$\endgroup$
  • 1
    $\begingroup$ What about Dimensions and some ArrayPad? $\endgroup$ – Yves Klett May 13 '14 at 17:14
  • 1
    $\begingroup$ Compare Equal @@ Dimensions[{{0, 0}, {0, 0}}] and Equal @@ Dimensions[{{0, 0}, {0, 0}, {0, 0}}] :) $\endgroup$ – Öskå May 13 '14 at 17:16
  • 1
    $\begingroup$ 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. $\endgroup$ – Ymareth May 13 '14 at 17:27
  • 1
    $\begingroup$ @SaxoMikoMola and where would you like the fill the rectangle matrix? $\endgroup$ – Öskå May 13 '14 at 17:40
  • 2
    $\begingroup$ In V10, there is/will be SquareMatrixQ $\endgroup$ – Michael E2 May 13 '14 at 18:08
4
$\begingroup$

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

padding

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

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@# &;

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



pad @ RandomReal[1, {4, 2}] // MatrixForm

enter image description here

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

enter image description here

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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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