If you can afford to symmetrize the matrix just before doing calculations, the following should be reasonably fast:
def symmetrize(a):
return a + a.T - numpy.diag(a.diagonal())
This works under reasonable assumptions (such as not doing both a[0, 1] = 42
and the contradictory a[1, 0] = 123
before running symmetrize
).
If you really need a transparent symmetrization, you might consider subclassing numpy.ndarray and simply redefining __setitem__
:
class SymNDArray(numpy.ndarray):
def __setitem__(self, (i, j), value):
numpy.ndarray.__setitem__(self, (i, j), value)
numpy.ndarray.__setitem__(self, (j, i), value)
def symarray(input_array):
"Returns a symmetrized version of input_array; further assignments to the array are automatically symmetrized."
return symmetrize(numpy.array(input_array)).view(SymNDArray)
# Example:
a = symarray(numpy.zeros((3, 3)))
a[0, 1] = 42
print a # a[1, 0] == 42 too!
(or the equivalent with matrices instead of arrays, depending on your needs). This approach even handles more complicated assignments, like a[:, 1] = -1
, which correctly sets a[1, :]
elements.