Numpy 'умная' симметрическая матрица

Есть ли умная и эффективная пространством симметрическая матрица в numpy, который автоматически (и прозрачно) заполняет положение в [j][i] когда [i][j] записан в?

import numpy
a = numpy.symmetric((3, 3))
a[0][1] = 1
a[1][0] == a[0][1]
# True
print(a)
# [[0 1 0], [1 0 0], [0 0 0]]

assert numpy.all(a == a.T) # for any symmetric matrix

Автоматическое Эрмитово также было бы хорошо, хотя мне не будет нужно это во время записи.

66
задан Guillaume Jacquenot 12 May 2017 в 08:27
поделиться

1 ответ

Если вы можете себе позволить симметризуйте матрицу непосредственно перед выполнением вычислений, следующее должно быть достаточно быстрым:

def symmetrize(a):
    return a + a.T - numpy.diag(a.diagonal())

Это работает при разумных предположениях (например, не выполняется одновременно a [0, 1] = 42 и противоречивое a [1, 0] = 123 перед запуском симметризовать ).

Если вам действительно нужна прозрачная симметризация, вы можете рассмотреть возможность создания подкласса numpy.ndarray и просто переопределить __ 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!

(или эквивалент с матрицами вместо массивов, в зависимости от ваших потребностей). Этот подход обрабатывает даже более сложные присваивания, такие как a [:, 1] = -1 , который правильно устанавливает элементы a [1,:] .

Обратите внимание, что Python 3 исключил возможность записи def… (…, (i, j),…) , поэтому код необходимо немного адаптировать перед запуском с Python 3: def __setitem __ (self, indexes, value): (i, j) = indexes

70
ответ дан 24 November 2019 в 15:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: