6
$\begingroup$

Assume that I have a function that generates an $m \times n$ array of numbers and I want to put this array in a specified place in an $(m+n) \times (m+n)$ matrix. How can I do that?

$\endgroup$
  • $\begingroup$ Do you mean that you want to overwrite an $m\times n$ block in a matrix with a different (smaller) matrix? $\endgroup$ – Szabolcs Sep 28 '17 at 12:58
  • $\begingroup$ First, I have a zero $(m+n) \times (m+n)$ matrix and I want to put the array in the up-right $m \times n$ block in the matrix. $\endgroup$ – A. Mpi Sep 28 '17 at 13:02
6
$\begingroup$

You can index into matrices directly using Part or its shortcut [[ ]]. For example, to place the random 2-by-3 matrix n in the upper right of the larger 4-by-5 matrix m:

m = ConstantArray[0, {4, 5}];
n = RandomInteger[{1, 9}, {2, 3}];
m[[1 ;; 2, 3 ;; 5]] = n
m // MatrixForm

enter image description here

The indexing into m is (in this example) rows 1 to 2, and columns 3 to 5. The assignment will work as long as this matches the number of rows and columns in n.

$\endgroup$
2
$\begingroup$

Use PadLeft or PadRight

mat := {{1, 2, 3, 4}, {5, 6, 7, 8}}
PadLeft[#, {-#, #} &[Total[Dimensions[#]]]] &[mat] // MatrixForm

$\left( \begin{array}{cccccc} 0 & 0 & 1 & 2 & 3 & 4 \\ 0 & 0 & 5 & 6 & 7 & 8 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

To specify the place you need ArrayPad

With[{x = 1, y = 3, dim = Dimensions[#]},
  ArrayPad[#, {{y, # - y}, {x, #2 - x}} & @@
    (Total[dim] - dim)]] &[mat] // MatrixForm

$\left( \begin{array}{cccccc} 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 2 & 3 & 4 & 0 \\ 0 & 5 & 6 & 7 & 8 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

$\endgroup$
2
$\begingroup$

Update:

I want to put the array in the up-right m×n block in the matrix.

padF[m_] := Normal[SparseArray[{Band[{1, 1 + Dimensions[m][[1]]] -> m},
  Total[Dimensions[m]] {1, 1}]]

mat = Partition[Range@8, 4];
padF[mat] // TeXForm

$\left( \begin{array}{cccccc} 0 & 0 & 1 & 2 & 3 & 4 \\ 0 & 0 & 5 & 6 & 7 & 8 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

Original answer:

You can use SparseArray and Band:

padF[pos_, m_] := Normal[Quiet@SparseArray[{Band[pos] -> m}, Total[Dimensions[m]] {1, 1}]]

Examples:

mat = Partition[Range@8, 4];
padF[{1, 3}, mat] // TeXForm

$\left( \begin{array}{cccccc} 0 & 0 & 1 & 2 & 3 & 4 \\ 0 & 0 & 5 & 6 & 7 & 8 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

padF[{2, 3}, mat] // TeXForm

$\left( \begin{array}{cccccc} 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 2 & 3 & 4 \\ 0 & 0 & 5 & 6 & 7 & 8 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

padF[{3, 4}, mat] // TeXForm

$\left( \begin{array}{cccccc} 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1 & 2 & 3 \\ 0 & 0 & 0 & 5 & 6 & 7 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{array} \right)$

$\endgroup$

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.