# Display Short Form of Large Matrix

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!

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:

Short/@Partition[Range[10^6], 1000]

Shallow/@Partition[Range[10^6], 1000]

• 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. Commented Jan 18, 2019 at 7:41