Si usted puede permitirse el lujo de simetrizar la matriz justo antes de hacer cálculos, lo siguiente debe ser razonablemente rápido:
def symmetrize(a):
return a + a.T - numpy.diag(a.diagonal())
Esto funciona bajo supuestos razonables (como no hacer tanto a[0, 1] = 42
y lo contradictorio a[1, 0] = 123
antes de ejecutar symmetrize
)
Si realmente necesita una simetrización transparente, es posible considerar la subclasificación numpy.ndarray y simplemente redefiniendo __setitem__
:
class SymNDArray(numpy.ndarray):
def __setitem__(self, (i, j), value):
super(SymNDArray, self).__setitem__((i, j), value)
super(SymNDArray, self).__setitem__((j, i), value)
def symarray(input_array):
"""
Returns a symmetrized version of the array-like input_array.
Further assignments to the array are automatically symmetrized.
"""
return symmetrize(numpy.asarray(input_array)).view(SymNDArray)
# Example:
a = symarray(numpy.zeros((3, 3)))
a[0, 1] = 42
print a # a[1, 0] == 42 too!
(o el equivalente con matrices en lugar de matrices, dependiendo de sus necesidades). Este enfoque incluso maneja asignaciones más complicadas, como a[:, 1] = -1
, que establece correctamente a[1, :]
elementos.
Tenga en cuenta que Python 3 eliminado la posibilidad de escribir def …(…, (i, j),…)
, por lo que el código tiene que ser adaptado ligeramente antes de ejecutar con Python 3: def __setitem__(self, indexes, value): (i, j) = indexes
...
usted podría considerar marcando la respuesta como aceptada, si resuelve su problema. :) – EOL
Quería esperar una respuesta mejor (es decir, incorporada y eficiente en la memoria) por venir. No hay nada de malo con su respuesta, por supuesto, así que lo aceptaré de todos modos. – Debilski