Home > database >  Populating a matrix with only a single list input
Populating a matrix with only a single list input

Time:11-03

I have a code snippet that creates a matrix by populating the upper elements one by one and populate the lower elements afterwards (if the upper element is x then the lower is 1/x)

n = 4
m = np.ones([n, n])
for i in range(0,n):
    for j in range(0,n):
         if i < j:
             x = input()
             m[i, j] = float(x) 
             m[j, i] = 1 / float(x) 

In the second code I can populate the matrix at once, but I need to populate the elements row-wise from top left to bottom right

n = int(input())
entries = list(map(int, input().split()))
matrix = np.array(entries).reshape(n, n)

My question is: is there any way can I populate the upper triangle of the matrix first like the first snippet, but only by entering a list once like the second snippet?

Ex.

n = 3

Input = 2 3 4 (list)

Expected output=
[[1.         2.         3.        ]
 [0.5        1.         4.        ]
 [0.33333333 0.25       1.        ]]

CodePudding user response:

np.triu_indices and np.tril_indices are your friends here. These functions supply the indices of the upper or lower triangle of a matrix. You can use the indices to assign your flat list into the portion of the matrix you want:

n = int(input())
entries = np.array(list(map(int, input().split())))
matrix = np.ones((n, n))
matrix[np.triu_indices(n, 1)] = entries
matrix[np.tril_indices(n, -1)] = 1 / entries

Since your matrices are square, supplying both n and the list is redundant because the length of the list must be a triangular number. len(entries) = (n**2 - n) / 2, only has a valid integer solution when 1 8 * len(entries) is an odd perfect square:

entries = np.array(list(map(int, input().split())))
d = np.sqrt(1   8 * entries.size)
if np.round(d) != d or d % 2:
    raise ValueError('invalid number of entries')
n = (d   1) // 2
  • Related