4

I want to generate symmetric zero diagonal matrices. My symmetric part work, but when I use fill_diagonal from numpy as the result I got "None". My code is below. Thank you for reading

import numpy as np
matrix_size = int(input("Size of the matrix \n"))
random_matrix = np.random.random_integers(-4,4,size=(matrix_size,matrix_size))
symmetric_matrix = (random_matrix + random_matrix.T)/2
print(symmetric_matrix)
zero_diogonal_matrix = np.fill_diagonal(symmetric_matrix,0)
print(zero_diogonal_matrix)
roganjosh
  • 12,594
  • 4
  • 29
  • 46
Dancer PhD
  • 197
  • 1
  • 4
  • 11
  • @roganjosh thank you so much for the response. Then, in this case, how can I assign zero value to the dioganal? – Dancer PhD Sep 27 '17 at 11:30
  • @roganjosh thank you for the response. I have done by this way too. The result is same None again symmetric_matrix = (random_matrix + random_matrix.T)/2 print(np.fill_diagonal(symmetric_matrix,0)) – Dancer PhD Sep 27 '17 at 11:34

2 Answers2

9

np.fill_diagonal(), like many other methods across python/numpy, works in-place. For example: Why does “return list.sort()” return None, not the list?. That is that it directly alters the object in memory and does not create a new object. The return value from such functions is None. Therefore, change:

zero_diogonal_matrix = np.fill_diagonal(symmetric_matrix,0)

To just:

np.fill_diagonal(symmetric_matrix,0)

You will then see the change reflected in symmetric_matrix.

roganjosh
  • 12,594
  • 4
  • 29
  • 46
2

It's probably overkill, but in case you want to preserve the tenet of minimising surprise, you could wrap this (and other functions like it) in a function that takes care of preserving the original array:

def fill_diagonal(source_array, diagonal):
    copy = source_array.copy()
    np.fill_diagonal(copy, diagonal)
    return copy

But the question then becomes "who exactly is going to be least surprised by doing it this way?"

Thomas Kimber
  • 10,601
  • 3
  • 25
  • 42