Как определить, являются ли все строки неквадратичной матрицы ортогональными в python

Я могу проверить ранг матрицы, используя np.linalg.matrix_rank (A). Но как я могу проверить, все ли строки a ортогональны эффективно?

Я мог бы взять все пары строк и вычислить скалярное произведение между ними, но есть лучший способ?

моя матрица имеет меньше строк, чем столбцов, и строки не являются единичными векторами.

3 ответов


этот ответ в основном обобщает подходы, упомянутые в вопросе и комментариях, и добавляет некоторые сравнения/идеи о них


подход #1 -- проверка всех пар строк

Как вы предложили, вы можете перебирать все пары строк и вычислять внутренний продукт. Если A.shape==(N,M), т. е. у вас есть N строк размера M каждый, вы получаете сложность O(M*N^2).

подход #2 -- Матрица умножение

как предложено в комментариях @JoeKington, вы можете вычислить умножение A.dot(A.T), и проверьте все недиагональные элементы. В зависимости от алгоритма, используемого для умножения матрицы, это может быть быстрее чем наивный алгоритм O(M*N^2), но только асимптотически лучше. Если ваши матрицы не большие, они будут медленнее.


преимущества подхода №1:

  • вы можете "короткое замыкание" -- выйдите из проверки, как только найдете первую неортогональную пару
  • требует меньше памяти. В #2 вы создаете временную матрицу NxN.

преимущества подхода №2:

  • умножение происходит быстро, так как оно реализовано в сильно оптимизированной библиотеке линейной алгебры (BLAS of ATLAS). Я считаю, что эти библиотеки выбирают правильный алгоритм для использования в соответствии с размером ввода (т. е. они не будут использовать причудливые алгоритмы на небольших матрицах, потому что они медленнее для малых матриц. За этой o-нотацией скрывается большая константа).
  • меньше кода писать

моя ставка заключается в том, что для небольших матриц подход № 2 окажется быстрее из-за того, что библиотеки LA сильно оптимизированы и, несмотря на то, что они вычисляют все умножение, даже после обработки первой пары неортогональных строк.


Кажется, что это будет делать

product = np.dot(A,A.T)
np.fill_diagonal(product,0)
if (product.any() == 0):

подход #3: вычислить QR-декомпозицию aT

В общем случае, чтобы найти ортогональный базис пространства диапазона некоторой матрицы X, можно вычислить QR-разложение этой матрицы (используя вращения Гивенса или рефлекторы домовладельца). Q-ортогональная матрица и R верхняя треугольная. Столбцы Q, соответствующие ненулевым диагональным записям R, образуют ортонормированный базис пространства диапазонов.

если столбцы X=AT, т. е., строки A уже ортогональны, тогда QR-разложение обязательно будет иметь диагональ R-фактора, где диагональные записи плюс или минус длины столбцов X соответственно. ряды А.

в народном фольклоре говорится, что этот подход численно лучше ведет себя, чем вычисление продукта A * aT=RT * R. Это может иметь значение только для больших матриц. Однако вычисление не так просто, как матричное произведение, объем операций одинаков.