12
$\begingroup$

Today, I want to write a program to show the solving process of a the inverse of a matrix, and I use the Elementary Transformation, so I need to add a vertical dashed line to the matrix.

I hope the result looks like this:

enter image description here

Question

Is it possible to achieve this effect?

Update1:

Firstly, thanks for Öskå's answer

For example, I have the following augmented matrix,

augmentedMatrix[n_Integer] := 
  Join[
    RandomInteger[{1, 10}, {n, n}], IdentityMatrix@n, 2]

augmentedMatrix[6] // MatrixForm

enter image description here

Then I need the result shown as below. Namely, myStyle[augmentedMatrix[6]]$$\Rightarrow$$

enter image description here

Update2:

Öskå's answer, the final effect that apply augmentedMatrixForm to my function:

  augmentedMatrixForm[mat_?MatrixQ] :=
   Module[{middlemat, len},
    len = Length@First@mat;
    middlemat = {Take[#, len/2] & /@ mat, Take[#, -len/2] & /@ mat};
    MatrixForm@
     List@Grid[
      List@(TableForm[#, TableSpacing -> {1, 1}] & /@ middlemat), 
       Dividers -> {# -> 
        Directive[Red, Dashed] & /@ (Range@Length@middlemat)[[2 ;;]]}]
  ]

enter image description here

I found that the matrix cannot align beautifully when the matrix contained fraction.

$\endgroup$
12
$\begingroup$

Grid directly supports such lines, called Dividers:

m = augmentedMatrix[6];

g = Grid[m, Dividers -> {7 -> {Red, Dashed}}]

enter image description here

All that remains is to incorporate the large ( ) brackets used by MatrixForm:

MatrixForm[{{g}}]

enter image description here

Another approach is to realize that both MatrixForm and Grid produce a GridBox expression:

Shallow[ToBoxes @ MatrixForm[m], 5]
Shallow[ToBoxes @ Grid[m], 3]
TagBox[RowBox[{(,,GridBox[<<5>>],,)}],Function[BoxForm`e$,BoxForm`e$]]

TagBox[GridBox[<<3>>],Grid]

We can manipulate that Box data to get the desired result:

ToBoxes @ MatrixForm[m] /. 
  GridBox[x__] :> 
   GridBox[x, GridBoxDividers -> {"ColumnsIndexed" -> {7 -> {Red, Dashed}}}] // 
     DisplayForm

enter image description here

The more verbose syntax required (replacement, and GridBoxDividers etc.) is certainly not ideal, but I think it is useful to understand that at a fundamental level all these functions are working with the same FrontEnd Box "primitives."

Proposal

Finally, here is what I propose for actual use, packaging the first method above into a hopefully convenient form.

Format[matWithDiv[n_, opts : OptionsPattern[Grid]][m_?MatrixQ]] := 
  MatrixForm[{{Grid[m, opts, Dividers -> {n -> {Red, Dashed}}]}}]

Now:

augmentedMatrix[6] // matWithDiv[7]

enter image description here

Additional Grid options can be used:

augmentedMatrix[6] // matWithDiv[7, Background -> LightOrange]

enter image description here

You can of course combine the formatting with the matrix generation, e.g.:

augMat2[n_, opts: OptionsPattern[Grid]] := augmentedMatrix[n] // matWithDiv[n + 1, opts]

augMat2[4]

enter image description here

augMat2[5, Frame -> All]

enter image description here

Be aware that, like MatrixForm, you will need to extract the first part of the output if you wish to manipulate the raw matrix data:

augMat2[5, Frame -> All] // First
{{8, 9, 9, 5, 5, 1, 0, 0, 0, 0},
 {7, 7, 4, 6, 6, 0, 1, 0, 0, 0},
 {4, 5, 4, 10, 6, 0, 0, 1, 0, 0},
 {7, 4, 2, 7, 9, 0, 0, 0, 1, 0},
 {7, 2, 9, 9, 1, 0, 0, 0, 0, 1}}
$\endgroup$
  • $\begingroup$ Dear Mr.Wizard, +1,Firstly, thanks sincerely, In addition, your solution always detaied and rigorous, as well as surprised me. :-) $\endgroup$ – xyz Sep 25 '14 at 14:06
  • $\begingroup$ @Tangshutao You're welcome, and thanks for the Accept. $\endgroup$ – Mr.Wizard Sep 26 '14 at 11:54
7
$\begingroup$
SeedRandom@0;
mat = RandomInteger[{0, 10}, {2, 3, 3}];
MatrixForm@List@Grid[List@(TableForm /@ mat), Dividers -> {2 -> Directive[Red, Dashed]}]

Mathematica graphics

Of course you can play with spacings: TableForm[#, TableSpacing -> {1, 1}] & /@ mat

Mathematica graphics


To go a bit further with Dividers:

SeedRandom@0;
mat = RandomInteger[{0, 10}, {10, 3, 3}];
MatrixForm@
 List@Grid[List@(TableForm[#, TableSpacing -> {1, 1}] & /@ mat), 
   Dividers -> {# -> Directive[Red, Dashed] & /@ (Range@Length@mat)[[2 ;;]]}]

Mathematica graphics


With the new matrix (I removed the Join) it works the same:

augmentedMatrix[n_Integer] := {RandomInteger[{1, 10}, {n, n}], IdentityMatrix@n}
mat = augmentedMatrix[6];
MatrixForm@
 List@Grid[List@(TableForm[#, TableSpacing -> {1, 1}] & /@ mat), 
   Dividers -> {# -> Directive[Red, Dashed] & /@ (Range@Length@mat)[[2 ;;]]}]

Mathematica graphics

$\endgroup$
  • $\begingroup$ @Tangshutao You should not Accept an answer so quickly. I was working on an answer and it is disheartening to see that you feel that no additional answers are useful. $\endgroup$ – Mr.Wizard Sep 25 '14 at 13:22
  • $\begingroup$ @Mr.Wizard Knowing that you will pwnd me :) $\endgroup$ – Öskå Sep 25 '14 at 13:26
  • $\begingroup$ @Öskå I wouldn't say that; I just have a different approach. $\endgroup$ – Mr.Wizard Sep 25 '14 at 13:50
  • $\begingroup$ @Tangshutao That took longer than expected, but I rethought what I was writing half way through and started over. I hope that my answer will now both give a useful method and some understanding of the low-level Front End functions in play here. $\endgroup$ – Mr.Wizard Sep 25 '14 at 13:51

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.