7
$\begingroup$

Is there a way to display matrices in a shorter form similar to Short or Shallow?

I find that I very often want to inspect the initial and final rows and columns of matrices just to make sure I didn't do something completely silly when generating it. For matrices larger than the truncation size (say Partition[Range[10^6], 1000], Mathematica outputs (...1...) in a box with the options "show less", "show more", "show all", and "set size limit...".

I don't know if "show more" is supposed to do something similar to what I want, but clicking it doesn't do anything. I also don't really want to see the entire matrix. I'd like functionality similar to what Short does for 1D lists (i.e. Range[10^6]//Short produces something like:

{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,<<999966>>,999984,999985,999986,999987,999988,999989,999990,999991,999992,999993,999994,999995,999996,999997,999998,999999,1000000}

Ideally, I'd like something nearly as easy to read as the TableForm or MatrixForm of the full matrix, just with fewer lines. I realize I could do something like:

matrix[[Flatten[{Range[10], Range[-10, -1]}], Flatten[{Range[10], Range[-10, -1]}]]]

each time, but that seems tedious.

I haven't seen anything come up in my Google and MMA.SE searches, so perhaps this isn't a problem other people worry about. I've created my own code to deal with this in a way that's pleasing to my eye, so I'll post the code as an answer in case it helps anyone else. However, if anyone else has a better or more robust way please post an answer and I'll be glad to accept it!

$\endgroup$

2 Answers 2

7
$\begingroup$

Here is my answer:

myshallow[mat_List, dims_: {20, 20}] :=
 Module[{matrix, rows, cols, matrows, matcols, splitrow, splitcol},
  If[! And @@ IntegerQ /@ dims, 
   Return[HoldForm[myshallow[mat, dims]]]];
  If[Length[Dimensions[mat]] == 1, matrix = {mat}, matrix = mat];
  Switch[
   Length[dims],
   0,
   rows = dims; cols = 20,
   1,
   cols = dims[[1]]; rows = 20,
   2,
   {rows, cols} = dims
   ];
  {matrows, matcols} = Dimensions[matrix][[;; 2]];
  {splitrow, splitcol} = {Ceiling[rows/2], Ceiling[cols/2]};
  Which[
   matrows <= rows \[And] matcols <= cols,
   Grid[
    matrix,
    Alignment -> {Center, Center}],
   matrows <= rows \[And] matcols > cols,
   Grid[
    Table[
     Which[
      row == 1 \[And] col == splitcol + 1,
      Skeleton[matcols - cols],
      row > 1 \[And] col == splitcol + 1,
      SpanFromAbove,
      col <= splitcol,
      matrix[[row, col]],
      col >= splitcol + 2,
      matrix[[row, col - (cols + 2)]]],
     {row, matrows}, {col, cols + 1}],
    Alignment -> {Center, Center}],
   matrows > rows \[And] matcols <= cols,
   Grid[
    Table[
     Which[
      row == splitrow + 1 \[And] col == 1,
      Skeleton[matrows - rows],
      row == splitrow + 1 \[And] col > 1,
      SpanFromLeft,
      row <= splitrow,
      matrix[[row, col]],
      row >= splitrow + 2,
      matrix[[row - (rows + 2), col]]],
     {row, rows + 1}, {col, matcols}],
    Alignment -> {Center, Center}],
   matrows > rows \[And] matcols > cols,
   Grid[
    Table[
     Which[
      row <= splitrow \[And] col <= splitcol,
      matrix[[row, col]],
      row == 1 \[And] col == splitcol + 1,
      Skeleton[matcols - cols],
      row <= splitrow \[And] col == splitcol + 1,
      SpanFromAbove,
      row <= splitrow \[And] col >= splitcol + 2,
      matrix[[row, col - (cols + 2)]],
      row == splitrow + 1 \[And] col == 1,
      Skeleton[matrows - rows],
      row == splitrow + 1 \[And] col <= splitcol,
      SpanFromLeft,
      row == splitrow + 1 \[And] col == splitcol + 1,
      "",
      row == splitrow + 1 \[And] col == splitcol + 2,
      Skeleton[matrows - rows],
      row == splitrow + 1 \[And] col > splitcol + 2,
      SpanFromLeft,
      row >= splitrow + 2 \[And] col <= splitcol,
      matrix[[row - (rows + 2), col]],
      row == splitrow + 2 \[And] col == splitcol + 1,
      Skeleton[matcols - cols],
      row > splitrow + 2 \[And] col == splitcol + 1,
      SpanFromAbove,
      row >= splitrow + 2 \[And] col >= splitcol + 2,
      matrix[[row - (rows + 2), col - (cols + 2)]]],
     {row, rows + 1}, {col, cols + 1}],
    Alignment -> {Center, Center}]
   ]
  ]

Essentially, I take any 1D or higher list followed by an optional number of dimensions. Based on other Mathematica functions, if you input 5 for the dimensions it specifies the number of rows and {5} specifies 5 columns. My plan is to place it in $UserBaseDirectory/Kernel/init.m to make it available for every session.

With the following test cases:

matrixhuge = Partition[Range[5*10^6], 1000];
matrixsmall = Partition[Range[25], 5];
matrixwide = Partition[Range[1000], 100];
matrixlong = Partition[Range[1000], 2];
matrixhuge // myshallow
matrixsmall // myshallow
matrixwide // myshallow
matrixlong // myshallow

I get the following:

Picture of output short matrices.

$\endgroup$
4
$\begingroup$
Short/@Partition[Range[10^6], 1000]

Shallow/@Partition[Range[10^6], 1000]
$\endgroup$
1
  • $\begingroup$ Thanks! This definitely gets close to what I want, but I don't find it to be super readable (though certainly not difficult either). It's probably a lot less likely to break than a custom-built function, but I'm hoping to keep something along the lines of MatrixForm or TableForm but shorter. $\endgroup$
    – MassDefect
    Jan 18, 2019 at 7:41

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.