Python 4D array with elements only on one side of the diagonal

Click For Summary
The discussion focuses on initializing a 4D array where each entry is an m x m matrix, specifically containing elements only on one side of the diagonal of an n x n structure. Participants clarify that the structure is more accurately described as a 2D array of matrices, with emphasis on whether to include zero or empty matrices below or above the diagonal. A suggested approach involves using a nested list or a 4D numpy array, depending on efficiency needs. Code examples are provided for both methods, illustrating how to create an upper triangular matrix of matrices. The conversation concludes with the acknowledgment that a 4D array may be more efficient than a nested list structure.
schniefen
Messages
177
Reaction score
4
TL;DR
Is it possible to initialize a 4D array with only elements on one side of the diagonal?
Given the parameters ##n## and ##m##, I'd like to initialize a ##n \times n ## 4D array where each entry is an ##m \times m ## matrix, and where each column of the matrix is an array of type numpy.linspace(0,1,m). Furthermore, I'd only like to have entries on the diagonal and above it, or only on the diagonal and below it. Is there a possible one-liner for this? The reason for this peculiarly shaped array is that I only need half of the matrices in the full array, but at the same time I’d like to keep the structure the array gives, i.e. the matrices on the second row belong to a “group” and this “group” consists of exactly as many matrices there are in the row of the array made up of only matrices on the diagonal and above or below it. The same goes for the columns.
 
Technology news on Phys.org
Which diagonal are you referring to?

It sounds like your structure is not so much a 4D array as a 2D array of matrices - ie a n x n array of elements, each of which is a m x m matrix.

Although not clear, it sounds like you mean the diagonal of the n x n array, rather than a diagonal of a m x m matrix, or a diagonal hyperplane of a 4D hyper-rectangle (which is a complicated beast).

If that's correct, it gives rise to another necessary clarification: what do you mean by "only ... have entries on the diagonal and above it". Do you mean to not have any matrices below the diagonal or perhaps to have all zeroes or NAs in those matrices? If you mean not to have any, I suspect the best structure for you is a nested list, as follows:
- item 1 is a n-element list of m x m matrices
- item 2 is a (n-1)-element list of m x m matrices
.
.
.
- item n is a 2-element list of m x m matrices (ie containing two such matrices)
- item n is a 1-element list of m x m matrices (ie containing one m x m matrix)

Item k of that top-level list is the k-th row of the top-level n x n array.

Is that the sort of thing you want?
 
  • Like
Likes schniefen
You are right, a matrix with matrices as elements. I said 4D because in numpy arrays one can specify up to 4 indices if I’m not wrong, and this will give one a matrix of matrices. And yes, the diagonal referred to is the diagonal of the matrix of matrices. If not having any entries below or above this diagonal is more efficient than having simply empty matrices, than a nested list is probably the way to go. Would this list then be a list of numpy arrays, and if so, how would one initialize that?
 
I guess numpy 4D arrays only gives a column vector of matrices, and not a matrix of matrices.
 
You can have an array of dimension (\frac12n(n+1),m,m), in which the (i,j)th matrix is at position j + \frac12i(i+1) of the first index, where 0 \leq j \leq i < n. You can initialize this as follows:
Python:
>>> import numpy as np
>>> n = 3
>>> m = 2
>>> arr = np.zeros([int(n*(n+1)/2),m,m])
for i in range(0,int(n*(n+1)/2)):
   for j in range(0,m):
	   arr[i,:,j] = np.linspace(0,1,2)

	   
>>> arr
array([[[0., 0.],
        [1., 1.]],

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

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

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

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

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

With a four-dimensional array you can still do
Python:
arr = np.zeros([n,n,m,m])
for i in range(0,n):
   for j in range(i,n):  # or range(0, i+1) for a lower triangular array
      for k in range(0, m):
         arr[i,j,:,k] = np.linspace(0,1,m)
 
  • Like
Likes schniefen
pasmith said:
With a four-dimensional array you can still do
Python:
arr = np.zeros([n,n,m,m])
for i in range(0,n):
   for j in range(i,n):  # or range(0, i+1) for a lower triangular array
      for k in range(0, m):
         arr[i,j,:,k] = np.linspace(0,1,m)
As you comment in the code, this is an upper triangular matrix of matrices. The matrices that only have 0 elements will not be used, but maybe having it this way is more efficient compared to constructing some kind of list of list of matrices with n-1 entries in the first list, n-2 matrices in the second, ...
 
Learn If you want to write code for Python Machine learning, AI Statistics/data analysis Scientific research Web application servers Some microcontrollers JavaScript/Node JS/TypeScript Web sites Web application servers C# Games (Unity) Consumer applications (Windows) Business applications C++ Games (Unreal Engine) Operating systems, device drivers Microcontrollers/embedded systems Consumer applications (Linux) Some more tips: Do not learn C++ (or any other dialect of C) as a...

Similar threads

  • · Replies 3 ·
Replies
3
Views
2K
  • · Replies 4 ·
Replies
4
Views
6K
  • · Replies 25 ·
Replies
25
Views
2K
Replies
2
Views
2K
  • · Replies 2 ·
Replies
2
Views
2K
  • · Replies 17 ·
Replies
17
Views
3K
  • · Replies 14 ·
Replies
14
Views
4K
  • · Replies 15 ·
Replies
15
Views
5K
  • · Replies 3 ·
Replies
3
Views
4K
  • · Replies 14 ·
Replies
14
Views
5K