Подтвердить что ты не робот

Опасность смешивания матрицы и матрицы

В научном/инженерном приложении, над которым я работаю, есть множество матричных умножений линейной алгебры, поэтому я использую матрицы Numpy. Однако в python существует много функций, которые взаимозаменяемо принимают типы матриц или массивов. Ницца, нет? Ну не совсем. Позвольте мне продемонстрировать проблему с примером:

from scipy.linalg import expm
from numpy import matrix

# Setup input variable as matrix
A = matrix([[ 0, -1.0,  0,  0],
            [ 0,  0,  0,  1.0],
            [ 0,  0,  0,  0],
            [ 0,  0,  1.0,  0]])

# Do some computation with that input
B = expm(A)

b1 = B[0:2, 2:4]
b2 = B[2:4, 2:4].T

# Compute and Print the desired output
print "The innocent but wrong answer:"
print b2 * b1

print "The answer I should get:"
print matrix(b2) * matrix(b1)

При запуске вы получаете:

The innocent but wrong answer:
[[-0.16666667 -0.5       ]
 [ 0.          1.        ]]
The answer I should get, since I expected everything to still be matrices:
[[ 0.33333333  0.5       ]
 [ 0.5         1.        ]]

Любые советы или советы о том, как избежать такого рода переполнения? Это действительно беспорядочно, чтобы поддерживать перенос переменных в вызовах matrix(), чтобы гарантировать, что они все еще являются матрицами. Похоже, в этом нет никакого стандарта, и поэтому это может привести к ошибкам, которые трудно обнаружить.

4b9b3361

Ответ 1

Я склонен использовать array вместо matrix в numpy по нескольким причинам:

  • matrix является строго 2D, тогда как вы можете иметь numpy array любого измерения.
  • Помимо нескольких отличий, операции array и matrix в значительной степени взаимозаменяемы для пользователя Matlab.
  • Если вы последовательно используете array, вы должны использовать numpy.dot() (или в Python 3.5 новый двоичный оператор @) для матричного умножения. Это предотвратит проблему неясно, что * действительно делает в вашем коде. И когда вы сталкиваетесь с ошибкой умножения, вы можете найти проблему проще, поскольку вы уверены в том, какое умножение вы пытаетесь выполнить.

Поэтому я предлагаю вам попробовать придерживаться numpy.array, но также иметь в виду различия между array и matrix.

Наконец, мне было приятно работать с numpy/scipy на bpython. Автоматическое приглашение поможет вам узнать свойства функции, которую вы пытаетесь использовать, намного быстрее, чем постоянно обращаться к документу numpy/scipy.

Edit: Разница между array vs matrix, возможно, лучше всего здесь: 'array' или 'matrix'? Что я должен использовать?

Ответ 2

Смешивающие матрицы и обычные ndarrays действительно могут быть сложными и часто не стоят хлопот. Я бы добавил другие плакаты и советовал вам придерживаться массивов.

Тем не менее, в вашем конкретном примере проблема возникает из expm. Согласно документу, он принимает обычный ndarray как аргумент и выводит ndarray. Если вы хотите преобразовать свой результат обратно в matrix, вы можете использовать:

B = matrix(expm(A))

или

B = expm(A).view(matrix)

Теперь B - это матрица, срезы B будут самими матрицами, и ваше умножение будет работать, как ожидалось.

Итак, совет должен всегда проверять тип вывода функции.