What is the most efficient to store variable sized groups of matrices?

Viewed 56

If this has been asked and answered before, I will remove it.

I'd like to initialize a collection of m x m matrices in different, distinct groups. Given the parameter n, the first group consists of n-1 matrices, the second one of n-2 and so on. Preferrably, I'd like the matrices to be initialized with each column being an array of type np.linspace(0,1,m). I've considered initializing a 4D numpy array, however, only half of the matrices will be needed then. Is storing the matrices in a list a better option?

import numpy as np
n=2
m=2
M = np.zeros([n,n,m,m])
for i in range(0,n):
   for j in range(i,n): 
      for k in range(0, m):
         M[i,j,:,k] = np.linspace(0,1,m)

EDIT1: It is not so important how the elements of the matrices are initialized.

EDIT2: It is not true that only half of the matrices will be needed in the 4D array, since each row of matrices would start on the diagonal to get the correct number of matrices.

1 Answers

You forgot to show your code produces. Most of us can't simply read the code and imagine what what exactly is happening.

     ...: n=2
     ...: m=2
     ...: M = np.zeros([n,n,m,m])
     ...: for i in range(0,n):
     ...:    for j in range(i,n):
     ...:       for k in range(0, m):
     ...:          M[i,j,:,k] = np.linspace(0,1,m)
     ...: 
In [388]: M
Out[388]: 
array([[[[0., 0.],
         [1., 1.]],

        [[0., 0.],
         [1., 1.]]],


       [[[0., 0.],
         [0., 0.]],

        [[0., 0.],
         [1., 1.]]]])

I get the same thing by replacing the k loop with:

      M[i,j,:,:] = np.linspace(0,1,m)[:,None]

edit - valid for j in range(0,n), not range(i,n):

or all loops with

M[...] = np.linspace(0,1,m)[:,None]

or even

M = np.tile(np.linspace(0,1,m).reshape(1,1,m,1), (n,n,1,m))

or

M = np.broadcast_to(np.linspace(0,1,m)[:,None], (n,n,m,m))

correction

We could use np.triu_indices to assign the linspace array to the upper triangle of the (n,n) dimensions:

In [421]: M = np.zeros([n,n,m,m])
In [422]: M[np.triu_indices(n)] = np.linspace(0,1,m)[:,None]
In [423]: M
Out[423]: 
array([[[[0., 0.],
         [1., 1.]],

        [[0., 0.],
         [1., 1.]]],


       [[[0., 0.],
         [0., 0.]],

        [[0., 0.],
         [1., 1.]]]])

where:

In [425]: np.triu_indices(n)
Out[425]: (array([0, 0, 1]), array([0, 1, 1]))
Related