I know that using the Insert menu, you can create a matrix with vertical and horizontal lines, but not a more generic partition, such as dividing a 4x4 matrix into 4 2x2 partitions. Nor, can MatrixForm
do any sort of partitioning. So, how would I go about programmatically displaying such a partitioned matrix? I would like to retain the ability of MatrixForm
to act only as a wrapper and not affect subsequent evaluations, but it is not strictly necessary. I suspect this would involve using a Grid
, but I haven't tried it.
views:
76answers:
2So this is what I came up with. For a matrix M:
M = {{a, b, 0, 0}, {c, d, 0, 0}, {0, 0, x, y}, {0, 0, z, w}};
you construct two list of True/False values (with True for places where you want separators) that take two arguments; first the matrix and second a list of positions for separators.
colSep = Fold[ReplacePart[#1, #2 -> True] &,
Table[False, {First@Dimensions@#1 + 1}], #2] &;
rowSep = Fold[ReplacePart[#1, #2 -> True] &,
Table[False, {Last@Dimensions@#1 + 1}], #2] &;
Now the partitioned view using Grid[]
is made with the use of Dividers
:
partMatrix = Grid[#1, Dividers -> {colSep[#1, #2], rowSep[#1, #3]}] &;
This takes three arguments; first the matrix, second the list of positions for column dividers, and third the list of values for row dividers.
In order for it to display nicely you just wrap it in brakets and use MatrixForm:
MatrixForm@{partMatrix[M, {3}, {3}]}
Which does the 2by2 partitioning you mentioned.
After playing around for far too long trying to make Interpretation
drop the displayed form and use the matrix when used in subsequent lines, I gave up and just made a wrapper that acts almost exactly like MatrixForm
. This was really quick as it was a simple modification of this question.
Clear[pMatrixForm,pMatrixFormHelper]
pMatrixForm[mat_,col_Integer,row_:{}]:=pMatrixForm[mat,{col},row]
pMatrixForm[mat_,col_,row_Integer]:=pMatrixForm[mat,col,{row}]
pMatrixFormHelper[mat_,col_,row_]:=Interpretation[MatrixForm[
{Grid[mat,Dividers->{Thread[col->True],Thread[row->True]}]}],mat]
pMatrixForm[mat_?MatrixQ,col:{___Integer}:{},row:{___Integer}:{}]:=
(CellPrint[ExpressionCell[pMatrixFormHelper[mat,col,row],
"Output",CellLabel->StringJoin["Out[",ToString[$Line],"]:=//pMatrixForm"]]];
Unprotect[Out];Out[$Line]=mat;Protect[Out];mat;)
Then the postfix command //pMatrixForm[#, 3, 3]&
will give the requested 2x2 partitioning of a 4x4 matrix. It maybe useful to change the defaults of pMatrixForm
from no partitions to central partitions. This would not be hard.