5
$\begingroup$

I have the diagonal and both upper and lower triangulars of a grid.

diag = {1, 2, 3, 4};
upper = {{u12, u13, u14}, {u23, u24}, {u34}};
lower = {{l21}, {l31, l32}, {l41, l42, l43}};

I want to combine this and display them in a grid with shading. My code for this is very bulky and I can't help feeling I've missed some function that would make more compact and easier to read. I also would rather not convert everything into Item to get the shading I want.

diag = Item[#, Background -> LightGray] & /@ diag;
upper = Map[Item[#, Background -> LightBlue] &, upper, {2}];
lower = Map[Item[#, Background -> LightGreen] &, lower, {2}];
first = Append[{diag[[1]]}, upper[[1]]] // Flatten;
mid = Table[Append[{diag[[row]]}] /* Append[upper[[row]]] /* Flatten@
   lower[[row - 1]], {row, 2, 3}];
last = Append[lower[[3]], {diag[[4]]}] // Flatten;
Grid[Partition[{first, mid, last} // Flatten, 4]]

Mathematica graphics

Is there a more compact way to do this?

$\endgroup$
6
$\begingroup$
(*Some pre-format, starting with your element definitions *)
diag = List /@ diag;
upper = Join[upper, {{}}];
lower = Join[{{}}, lower];

(*code *)
f[els_, col_] := Map[Item[#, Background -> col] &, els, {2}]; 
Grid@MapThread[Join, {f[lower, LightBlue], f[diag, LightGray], f[upper, LightRed]}]

Mathematica graphics

$\endgroup$
  • 1
    $\begingroup$ I like the combination method you have used. Sneaky to add an empty row and and nest the diagonal. $\endgroup$ – Edmund Nov 24 '14 at 1:43
5
$\begingroup$

Generally speaking I favour using Grid options for styling rather than using Item. For example make your matrix:

MatrixForm[m = Array[Subscript[a, ##] &, {4, 4}]];

then:

Grid[m,
 ItemStyle -> {None, None, Flatten@MapIndexed[Which[
       #2[[2]] > #2[[1]], #2 -> Blue,
       #2[[2]] == #2[[1]], #2 -> Gray,
       #2[[2]] < #2[[1]], #2 -> Red
       ] &, m, {2}]}
 ]

enter image description here

Did you start with a matrix and then split it into upper, lower and diagonals? And if you did was that solely for the purpose of styling? If you did then just revert to your starting matrix. If somehow you actually only have the 3 components of the matrix then combine them simply like this:

m = RotateLeft@PadLeft[upper, {4, 4}] + 
  RotateRight@PadRight[lower, {4, 4}] + DiagonalMatrix[diag];

Or, as per @wreach answer, use negative indexes rather than wrapping to do the rotating:

m = PadLeft[upper, {-4, 4}] + PadRight[lower, {-4, 4}] + DiagonalMatrix[diag];

Then use the grid styling as before:

Grid[m, Background -> {None, None, 
   Flatten@MapIndexed[
     Which[#2[[2]] > #2[[1]], #2 -> Blue, #2[[2]] == #2[[1]], #2 -> 
        Gray, #2[[2]] < #2[[1]], #2 -> Red] &, m, {2}]}]

enter image description here

$\endgroup$
  • $\begingroup$ You aren't starting from the stated input. Was that on purpose? $\endgroup$ – Dr. belisarius Nov 24 '14 at 1:28
  • $\begingroup$ wanted to simply address using MapIndexed rather than Item for styling of Grid but will update $\endgroup$ – Mike Honeychurch Nov 24 '14 at 1:41
  • $\begingroup$ Ah, using rules. Nice. I didn't realise the was possible but of course with MapIndexed. $\endgroup$ – Edmund Nov 24 '14 at 1:42
  • $\begingroup$ @Edmund I find it more intuitive doing it that way but it is up to individual preference $\endgroup$ – Mike Honeychurch Nov 24 '14 at 2:01
4
$\begingroup$

A helper function can reduce the boilerplate somewhat:

a_ // itemize[c_] := Map[Item[#, Background -> c]&, a, {-1}]

DiagonalMatrix[diag // itemize[LightGray]] +
PadLeft[upper // itemize[LightBlue], {-4,4}] +
PadRight[lower // itemize[LightGreen], {-4,4}] //
Grid

grid screenshot

$\endgroup$
  • $\begingroup$ +1 nice use of negative indexes to avoid rotating functions $\endgroup$ – Mike Honeychurch Nov 24 '14 at 2:03
  • $\begingroup$ @MikeHoneychurch I abandoned my first solution because your post got there first. Now I see that my second solution is much like your edit. Oh well, them's the MSE breaks. :) $\endgroup$ – WReach Nov 24 '14 at 2:06
  • $\begingroup$ I like your answer ...although I've never liked using Item :) $\endgroup$ – Mike Honeychurch Nov 24 '14 at 2:07
  • $\begingroup$ This combination is sweet. I looked at the padding functions but was trying to figure out how to do what you have done with the -4. $\endgroup$ – Edmund Nov 24 '14 at 2:14

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.