2013-12-19 3 views
1

У меня есть код, где я хочу проверить, является ли произведение матрицы и вектора нулевым вектором. Пример моей попытки является:Сравнение двух векторов

n =2 
zerovector = np.asarray([0]*n) 

for column in itertools.product([0,1], repeat = n): 
    for row in itertools.product([0,1], repeat = n-1): 
     M = toeplitz(column, [column[0]]+list(row)) 
     for v in itertools.product([-1,0,1], repeat = n): 
      vector = np.asarray(v) 
      if (np.dot(M,v) == zerovector): 
       print M, "No good!" 
       break 

Но линия if (np.dot(M,v) == zerovector): дает ошибку ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all(). Каков правильный способ сделать это?

+0

Ваш внутренний цикл всегда будет «ломаться», поскольку вы включаете нулевой вектор в тестовые векторы, который, безусловно, будет в ядре 'M'. Чего вы пытаетесь достичь? –

+0

@SvenMarnach Код еще не закончен, но спасибо, что вы правы. – marshall

ответ

2

Проблема заключается в том, что между двумя массивами является сравнение по элементам - вы возвращаете массив значений типа boolean. Массив логических значений не является булевым значением, поэтому вы не можете использовать его в if. Это то, что ошибка пытается вам рассказать.

может решить это с помощью метода all, чтобы проверить, являются ли все элементы в булевом массиве истинными. Но вы делаете это более сложным, чем вам нужно. Ненулевые значения truthy, нулевые значения falsey, так что вы можете просто использовать any без сравнения:

if not np.dot(M, v).any(): 

Если вы хотите, чтобы сделать сравнение нуля явно, просто сравните скаляр, не строит ноль вектор; он будет транслироваться одинаково. И, если вы когда-либо do хотите построить нулевой вектор, просто используйте функцию zeros; не стройте list нулей сложным способом и передайте его asarray.

Вы также можете использовать функцию count_nonzero здесь в качестве другой альтернативы. Если он возвращает что-либо правдоподобное (то есть любое ненулевое число), массив имел по крайней мере один ненулевой.

В общем, вы делаете почти все, что необходимо, и, используя краткое руководство по NumPy, а затем сканирование основных страниц документов для полезных функций действительно поможет вам.


Кроме того, если значения не являются целыми числами, вы, вероятно, на самом деле не хотят, чтобы сравнить == 0 в первую очередь. Числа с плавающей запятой накапливают ошибки округления. Для этого воспользуйтесь функцией allclose.

+0

Спасибо, что сработал. Любые советы по улучшению остальной части кода с благодарностью получены. Все значения являются целыми числами в моем случае. – marshall

1

как ошибка говорит, что вы должны использовать all

if all(np.dot(M,v) == zerovector): 

или np.all. np.dot(M,v) == zerovector дает вам вектор, который является парным сравнением двух векторов.

+1

Использование встроенного 'all' будет работать, но это заставляет вас перебирать вектор в Python, а не позволять NumPy делать это быстрее. В общем, вы хотите сохранить итерацию внутри NumPy, когда это возможно. – abarnert

Смежные вопросы