-1

I am given a quadratic matrix and have to do as follows:

For each entry (i,j) in the matrix
    If i = j:
        set y[i,j] = x[i,j].
    Else:
        set y[i,j] = x[i,j] + x[j,i]

I have made the following script:

def symmetrize(x):

    ## The symmetrized matrix that is returned
    y = np.zeros(np.shape(x))

    ## For loop for each element (i,j) in the matrix
    for i in range (np.size(x)):
        for j in range (np.size(x)):
            if i == j:
                y[i,j] = x[i,j]
            else:
                y[i,j] = x[i,j] + x[j,i]
    return y

I get this error message whenever I want to run the code with the following matrix:

np.array([[1.2, 2.3, 3.4],[4.5, 5.6, 6.7], [7.8, 8.9, 10.0]])

Error message:

y[i,j] = x[i,j] + x[j,i]

IndexError: index 3 is out of bounds for axis 1 with size 3

Do someone know what the problem is?

martineau
  • 119,623
  • 25
  • 170
  • 301
Charles Hay
  • 3
  • 1
  • 2

2 Answers2

2

np.size(), without an axis, gives you the total number of elements in the matrix. So your range()s are going to go from 0 - 8, not from 0 - 2.

You don't need to use np.size() or np.shape() for that matter; these functions aren't even listed in the documentation any more. Just use the .shape attribute of a matrix:

y = np.zeros(x.shape)

for i in range(x.shape[0]):
    for j in range(x.shape[1]):

There are better ways of producing your output. You could use:

def symmetrize(x):
    return x + x.T - np.diag(x.diagonal())

instead. x.T is the transposed matrix, so rows and columns swapped. x + x.T is the sum of the original matrix and the transposition matrix, so the numbers on the diagonal are doubled. x.diagonal() is an array of just those numbers on the diagonal, which can be subtracted once you created a matrix of those numbers on the diagonal, which is what np.diag() does for you.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
0

You are using np.size() wrong way, it doesn't tell you how many rows or columns your list has, but number of elements in the array, in your case - 9. You could use shape of your list like so:

def symmetrize(x):

    ## The symmetrized matrix that is returned
    y = np.zeros(np.shape(x))

    ## For loop for each element (i,j) in the matrix
    for i in range(x.shape[0]):
        for j in range(x.shape[1]):
            if i == j:
                y[i,j] = x[i,j]
            else:
                y[i,j] = x[i,j] + x[j,i]
    return y
Filip Młynarski
  • 3,534
  • 1
  • 10
  • 22