7
$\begingroup$

Suppose you have the following diagonal matrix:

$\left( \begin{array}{cc} a & 0 \\ 0 & \{b,c\} \end{array} \right)$

How can the above matrix be converted to the following rectangular one?

$\left( \begin{array}{ccc} a & 0 & 0 \\ 0 & b & c \end{array} \right)$

Or a more complex example:

$\left( \begin{array}{ccc} \{\{b,c,d,e,f\}\} & 0 & 0 \\ 0 & \{a\} & 0 \\ 0 & 0 & \{\{b,c\},\{x,y\}\} \end{array} \right)$

to

$\left( \begin{array}{cccccccc} b & c & d & e & f & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & a & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & b & c \\ 0 & 0 & 0 & 0 & 0 & 0 & x & y \end{array} \right)$

$\endgroup$
10
$\begingroup$

Using a combination of SparseArray and Band after some processing of the diagonal of the input matrix:

ClearAll[toRectangularMatrix]
toRectangularMatrix = Module[{blocks = Replace[Diagonal[#], 
    {x_?(ArrayDepth @ # == 0 &) :> {{x}},  x_?(ArrayDepth @ # == 1 &) :> {x}}, 1]}, 
  SparseArray[Band[{1, 1}] -> blocks]] &;

Examples:

toRectangularMatrix @ {{a, 0}, {0, {b, c}}} // MatrixForm // TeXForm

$\left( \begin{array}{ccc} a & 0 & 0 \\ 0 & b & c \\ \end{array} \right)$

 toRectangularMatrix @ {{{b, c}, 0}, {0, a}} // MatrixForm // TeXForm

$\left( \begin{array}{ccc} b & c & 0 \\ 0 & 0 & a \\ \end{array} \right)$

toRectangularMatrix @ {{a, 0}, {0, {{b, c}, {d, e}}}} // MatrixForm  // TeXForm

$\left( \begin{array}{ccc} a & 0 & 0 \\ 0 & b & c \\ 0 & d & e \\ \end{array} \right)$

toRectangularMatrix @ {{{a, d, e}, 0}, {0, {b, c}}} // MatrixForm // TeXForm

$\left( \begin{array}{ccccc} a & d & e & 0 & 0 \\ 0 & 0 & 0 & b & c \\ \end{array} \right)$

toRectangularMatrix @ {{a, 0, 0}, {0, {b, c, d, e, f}, 0}, {0, 0, {{b, c}, {x, y}}}} // 
 MatrixForm // TeXForm

$\left( \begin{array}{cccccccc} a & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & b & c & d & e & f & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & b & c \\ 0 & 0 & 0 & 0 & 0 & 0 & x & y \\ \end{array} \right)$

$\endgroup$
  • $\begingroup$ Yes, in a situation where the diagonal matrix is as per the below example, then this approach should not be applied: {{a,b},0},{0,c}} $\endgroup$ – aleksander_si Jul 7 at 6:11
  • 1
    $\begingroup$ @aleksander_si, please see the updated version. $\endgroup$ – kglr Jul 7 at 6:52
  • $\begingroup$ It seems that your updated solution also correctly handles more complex cases, for example, nested matrix, single row matrix as well as the order/length is now not important anymore. I have tested this as well and it seems this is the best solution now. $\endgroup$ – aleksander_si Jul 7 at 7:29
9
$\begingroup$

Here is a solution using ArrayFlatten:

toRectangularMatrix2[m_] := ArrayFlatten@Replace[m, l_List /; ! MatrixQ@l :> {l}, {2}]

toRectangularMatrix2@{{a, 0, 0}, {0, {b, c, d, e, f}, 0}, {0, 0, {{b, c}, {x, y}}}} // MatrixForm

$\left( \begin{array}{cccccccc} a & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & b & c & d & e & f & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & b & c \\ 0 & 0 & 0 & 0 & 0 & 0 & x & y \\ \end{array} \right)$

The Replace[…] part is only needed to convert the list-type entries to matrices, e.g. {b,c,d,e,f} to {{b,c,d,e,f}}. So if you can change the input format to be more uniform, ArrayFlatten on its own would be enough:

{{a, 0, 0}, {0, {{b, c, d, e, f}}, 0}, {0, 0, {{b, c}, {x, y}}}} // ArrayFlatten // MatrixForm
$\endgroup$
  • $\begingroup$ I have to test your solution first to decide if this should be labeled as the answer. The approach by kglr uses sparse array, not sure if this may be useful by anyone? @kglr, why have you used sparse array approach? But yes, we should use the ArrayFlatten function as much as possible. $\endgroup$ – aleksander_si Jul 8 at 9:45
4
$\begingroup$
diag = Flatten[{#}] & /@ Diagonal[m];
ncols = Length@Flatten[diag];
offsets = Most@Prepend[Accumulate[Length /@ diag], 0];
row[values_, offset_, ncols_] := PadRight[ArrayPad[values, {offset, 0}], ncols]
matrix[diag_, offsets_, ncols_] := MapThread[row[#, #2, ncols] &, {diag, offsets}]

m = {{a, 0, 0}, {0, {b, c, d, e, f}, 0}, {0, 0, {b, c}}}
matrix[diag, offsets, ncols] // MatrixForm

Mathematica graphics

$\endgroup$
  • $\begingroup$ @C.E. replaced PadRight with an alternative method. $\endgroup$ – kglr Jul 7 at 7:02
  • 1
    $\begingroup$ @kglr ok, I withdraw my complaints :) $\endgroup$ – C. E. Jul 7 at 7:05
  • $\begingroup$ Thank you very much for the effort, the solution covers most of the possibilities :) $\endgroup$ – aleksander_si Jul 7 at 7:36

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.