2013-06-13 6 views
1

Я попытался создать случайную симметричную матрицу для проверки моей программы. Я вообще не забочусь о данных, пока он симметричен (достаточная случайность не вызывает никакого беспокойства).семантика генерации симметричных матриц в numpy

Моя первая попытка была такова:

x=np.random.random((100,100)) 
x+=x.T 

Однако np.all(x==x.T) возвращает значение False. print x==x.T дает

array([[ True, True, True, ..., False, False, False], 
    [ True, True, True, ..., False, False, False], 
    [ True, True, True, ..., False, False, False], 
    ..., 
    [False, False, False, ..., True, True, True], 
    [False, False, False, ..., True, True, True], 
    [False, False, False, ..., True, True, True]], dtype=bool) 

Я попытался запустить небольшой тестовый пример с п = 10, чтобы увидеть, что происходит, но этот пример работает точно так же, как вы ожидаете.

Если я это сделать, как это вместо:

x=np.random.random((100,100)) 
x=x+x.T 

, то она работает просто отлично.

Что здесь происходит? Не являются ли эти утверждения семантически эквивалентными? Какая разница?

ответ

2

Эти утверждения не являются семантически эквивалентными. x.T возвращает вид оригинального массива. в случае += вы фактически меняете значения x, когда вы перебираете его (что изменяет значения x.T).

Подумайте об этом так ... Когда ваш алгоритм получает индекс (3,4), это выглядит, как это в псевдокоде:

x[3,4] = x[3,4] + x[4,3] 

теперь, когда ваша итерация получает (4,3), вы

x[4,3] = x[4,3] + x[3,4] 

но, x[3,4] это не то, что было, когда вы начали итерацию.


Во втором случае, вы на самом деле создать новый (пустой) массив и изменить элементы в пустом массиве (никогда не писал для x). Так псевдокод выглядит примерно так:..

y[3,4] = x[3,4] + x[4,3] 

и

y[4,3] = x[4,3] + x[3,4] 

, который, очевидно, даст вам симметричную матрицу (y

+0

Это имеет смысл, но это похоже на плохой выбор семантики 'x + = ' никогда не будет отличаться от 'x = x + '. – aestrivex

+0

@aestrivex, 'x + = ' будет работать до тех пор, пока 'exp' не читает ячейку памяти, на которую записывалось' x + = 'part. Это sam Причина, по которой 'memmove()' существует в C (и 'memcpy()' имеет неопределенное поведение, когда области памяти перекрываются). Если вы все еще хотите использовать '+ =', вы можете сделать 'x + = x.T.copy()'. –

+1

@aestrivex - На самом деле, мой [самый высокий вопрос о всех вопросах] (http://stackoverflow.com/questions/15376509/when-is-ix-different-from-iix-in-python/15376520#15376520) является объясняя разницу между «x + = something» и «x = x + something». – mgilson