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$
0

3 Answers 3

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$
3
  • $\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$ Jul 7, 2019 at 6:11
  • 1
    $\begingroup$ @aleksander_si, please see the updated version. $\endgroup$
    – kglr
    Jul 7, 2019 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$ Jul 7, 2019 at 7:29
10
$\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$
1
  • $\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$ Jul 8, 2019 at 9:45
5
$\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$
3
  • $\begingroup$ @C.E. replaced PadRight with an alternative method. $\endgroup$
    – kglr
    Jul 7, 2019 at 7:02
  • 1
    $\begingroup$ @kglr ok, I withdraw my complaints :) $\endgroup$
    – C. E.
    Jul 7, 2019 at 7:05
  • $\begingroup$ Thank you very much for the effort, the solution covers most of the possibilities :) $\endgroup$ Jul 7, 2019 at 7:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.