2
$\begingroup$

I have a loop structure which performs certain calculations and writes the results in some matrix $M$. When certain condition is satisfied the loop stops. Let's assume that this happens after $T$ iterations. Then, for the purposes of the problem I am considering, the necessary dimensions of $M$ are $d \times d$, where $d= \sum_{i=1}^{T+1} n^i$ and $n$ is a constant from the given problem considered (typically n=2,3,4). For example if $n=2$ and we know that the loop will finish after two iterations, we would have that $d=14$ and I would need a matrix $M$ that is $14\times 14$.

My issue is that since I do not know in advance when the loop is going to finish, I can not allocate in advance a size to the matrix $M$, so I have to assign something large to $d$ by guessing and hope the loop will finish before it runs out of space. I pre-allocate $M$ by:

M = ConstantArray[0, {d, d}]

So the question is, can I do this dynamically? In other words, can I increase the size of the matrix $M$ at each iteration without losing the previously written elements and how?

I can imagine that one could create a new matrix at each iteration of the appropriate size and copy the elements from previous iterations into it. Would that be efficient? How can it be done efficiently?

Thanks!

$\endgroup$
3
  • 1
    $\begingroup$ Just create a new matrix every time instead of put the new data into a fixed size table. $\endgroup$
    – cvgmt
    Commented Nov 25, 2020 at 8:13
  • $\begingroup$ How do I copy efficiently all the elements of the previous matrix to the new one? $\endgroup$
    – AG1123
    Commented Nov 25, 2020 at 9:10
  • 1
    $\begingroup$ This sounds very much like an XY problem. If you write down your actual problem, someone can help you find a solution that fits Mathematica's style better. $\endgroup$
    – Roman
    Commented Nov 25, 2020 at 19:36

1 Answer 1

3
$\begingroup$

There are various ways to expand a matrix array by adding rows and columns, but for this application, making a new matrix and copying the old matrix to the new one will work. First, make a sample matrix.

SeedRandom[12]
d = 4;
m = RandomInteger[9, {d, d}];
m // MatrixForm

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

To make a new matrix that’s twice as large, for example, make a new matrix with ConstantArray, and copy matrix m. This fast and flexible as long as the new matrix is larger than the dimensions of m. It also works with matrices that aren’t square.

n = ConstantArray[0, {2 d, 2 d}];
(n[[ ;; #1, ;; #2]] = m) &@@ Dimensions@m;
n // MatrixForm

${\small\left( \begin{array}{cccccccc} 2 & 4 & 0 & 1 & 0 & 0 & 0 & 0 \\ 9 & 7 & 3 & 1 & 0 & 0 & 0 & 0 \\ 7 & 0 & 9 & 5 & 0 & 0 & 0 & 0 \\ 4 & 6 & 7 & 2 & 0 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 & 0 & 0 \\ 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)}$

Avoid using ConstantArray with SparseArray, although this method is slower.

n = SparseArray[{Band[{1, 1}] -> m}, {2 d, 2 d}];

The results are the same.

$\endgroup$

Your Answer

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

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