如何在Mathematica中以编程方式显示一个被分区的矩阵?

3

我知道在插入菜单中可以创建具有垂直和水平线的矩阵,但不能创建更通用的分区,例如将4x4矩阵分成4个2x2分区。而且,MatrixForm无法进行任何分区。那么,如何以编程方式显示这样的分区矩阵?我希望保留MatrixForm仅作为包装器并不影响后续评估的能力,但这并非绝对必要。我怀疑这将涉及使用Grid,但我还没有尝试过。

2个回答

3

所以这就是我想到的。对于一个矩阵M:

M = {{a, b, 0, 0}, {c, d, 0, 0}, {0, 0, x, y}, {0, 0, z, w}};

你需要构建两个列表,其中包含True / False值(在希望插入分隔符的位置处为True),这两个列表需要传递两个参数;第一个参数是矩阵,第二个参数是分隔符所在的位置列表。
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] &;

现在使用Grid[]进行分割视图需要使用Dividers

partMatrix = Grid[#1, Dividers -> {colSep[#1, #2], rowSep[#1, #3]}] &;

这个函数需要三个参数:第一个是矩阵,第二个是列分割线的位置列表,第三个是行分割线的值列表。

为了让它显示得好看,你只需要将它用括号包起来并使用MatrixForm:

MatrixForm@{partMatrix[M, {3}, {3}]}

你提到的2by2分区是什么意思?

我需要花一些时间仔细研究它的工作原理,但它确实很聪明。虽然你失去了MatrixForm的好处,即可以直接使用其结果。请给我几个小时来重新投票。 - rcollyer
2
“Dividers”选项也可以只使用分隔符的位置列表,甚至可以使用样式:“Grid[M, Dividers -> {{3 -> True}, {3 -> Red}}]”。 - Michael Pilat
回到最初的问题(也许这本身就是一个问题),在Mathematica中是否有一种方法可以使对象在显示和评估时具有不同和独立的形式? - Timo
@rcollyer 请继续,我现在没时间,而且这与你的问题有关。不过如果能得到一个好的答案会很有趣,尽管我对这种事情是否可能存在怀疑。 - Timo
$Timo,这里有两个不同的问题。第一个是一个对象,它的显示方式与其评估方式不同。这很容易 - 使用Interpretation或其低级等效项。(例如,请参见http://www.feyncalc.org/FeynCalcBook/)。第二个是创建一个显示包装器,如“*Form”。这可能涉及到CellPrint... - Simon
显示剩余3条评论

3

在尝试让Interpretation在后续行中使用矩阵而不是显示的表单时,我玩了很长时间,但最终放弃了,只是创建了一个包装器,几乎完全像MatrixForm。这非常快速,因为它是对此问题的简单修改。

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;)

那么后缀命令 //pMatrixForm[#, 3, 3]& 将给出所请求的 4x4 矩阵的 2x2 分区。将 pMatrixForm 的默认设置从没有分区改为中央分区可能很有用。这不难实现。


实际上,pMatrixForm可能应该继承Grid的参数结构 - 然后它们都可以简单地通过传递。我以后可能会重写这个。 - Simon
有一个错别字,pMatrixForm的整个函数体必须用括号括起来。(你有闭合的括号,但没有开启的括号。)话虽如此,通过 Out[<line num>] 引用输出结果可以正常工作。但是,设置 p = pMatrixForm[M, 3, 3]p 设置为 Null。这非常接近我想要的。 - rcollyer
感谢您发现了这个笔误。通常使用p = MatrixForm[M]p = pMatrixForm[M,3,3]是不好的,因为这样你不能对p做太多事情。最好使用类似(p=M)//pMatrixForm[#,3,3]&或等效的pMatrixForm[p=M,3,3]。如果您真的想将p = pMatrixForm[M,3,3]设置为p=M,则可以删除最后的分号,然后在使用它的表达式中抑制输出。如果您希望将p设置为排版形式,则只需使用我的pMatrixFormHelper即可。 - Simon
真是太棒了,现在我需要把这个问题添加到我的收藏夹中 : )。非常感谢 Simon 提供如此精彩的教育。 - Timo
我得试着操作一下,看看它是如何组合的。但是,绝对是一个不错的解决方案。 - rcollyer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接