#python #matrix #normalization #diagonal #symmetric
#python #матрица #нормализация #диагональная #симметричный
Вопрос:
У меня есть симметричная матрица a
, для которой диагональные элементы могут быть разными.
>>> import numpy as np
>>> a = np.array([[3, 7, 6], [7, 2, 5], [6, 5, 1]])
>>> a
array([[3, 7, 6],
[7, 2, 5],
[6, 5, 1]])
Я хотел бы нормализовать эту матрицу, чтобы сделать все диагональные элементы 0 такими:
array([[0, x1, x2],
[x1, 0, x3],
[x2, x3, 0]])
Как я могу это сделать (на Python, если это возможно)?
Любая помощь будет очень признательна, спасибо.
Комментарии:
1. Спасибо за ваши ответы, но я должен был указать больше. Моя цель — не заполнять диагональ. Я хочу нормализовать все элементы матрицы в соответствии с диагональю, например:
A = np.multiply(a, X)
с a = входной матрицей, A = выходной матрицей с диагональным значением = 0 (Примечание. размер матрицы, который я использую, равен 20 * 20)2. Итак, заданы a и A, и вы хотите найти матрицу X такую, что A = np.умножьте (a, X)? (Кстати, вы имеете в виду np.multiply или np.dot)?
3. Извините, это
np.dot(a, X)
иX
неизвестно. Все, что мы знаем, это входная матрицаa
и диагональ выходной матрицыA
, которая равна нулю.4. Я обновил свой первоначальный ответ; это то, что вам было нужно? Существуют ли другие гипотезы / детали, которые следует учитывать в вашей проблеме?
Ответ №1:
Вы можете использовать следующую команду: np.fill_diagonal(a, 0)
(https://numpy.org/doc/stable/reference/generated/numpy.fill_diagonal.html )
Следуя вашим разъяснениям: если я хорошо понимаю, что вы хотите сделать, тогда вы можете различать два случая.
- обратимый ==> использовать
X = np.linalg.solve(a, A)
- необратимое ==> в этом случае может быть либо никакого решения, либо бесконечно много решений.
Например, если a не является обратимым, но A является обратимым, то решения нет (в противном случае X * A ^-1 обеспечит обратное значение для a). В общем случае необходимым условием существования решения является то, что rk (A) <= rk (a) (по теореме о ранге).
В этом другом случае существует бесконечно много решений
a = array([[0, 0, 0],
[0, 2, 0],
[0, 0, 1]])
A = array([[0., 0., 0.],
[0., 0., 1.],
[0., 1., 0.]])
поскольку
array([[0. , 0. , 0. ], array([[1., 1., 1.],
X = [0. , 0. , 0.5], lbda * [0., 0., 0.],
[0. , 1. , 0. ]]) [0., 0., 0.]])
решает np.dot(a,X) = A
для каждого реального значения lbda.
Если вы находитесь во втором случае (бесконечно много решений), вы можете использовать
X = np.linalg.lstsq(a,A)[0]
который обеспечивает решение даже в случае, когда a не является обратимым (и возвращает тот же результат, что и np.linalg.solve, если a является обратимым). Если решения не существует, эта команда возвращает матрицу, такую, что np.dot(a, X) «как можно ближе» к A. Вы можете понять, что это так, добавив последнюю проверку, например assert np.max(np.abs(np.dot(a,X) - A)) < 1E-5
.
Комментарии:
1. Спасибо за ваш ответ. Проблема в том, что мы не знаем
A
ни того, ни другого: мы хотим, чтобы его диагональ была равна нулю, но мы не знаем значений других элементов. В этой системе слишком много неизвестных. Я попытаюсь найти решение для применения исходной матрицыa
без нормализации. В любом случае, большое вам спасибо за ваше драгоценное объяснение, я многому научился!
Ответ №2:
Если вы хотите сделать все диагональные элементы равными 0, просто используйте простой цикл for .
for i in range(len(matrix)):
matrix[i][i] = 0
Комментарии:
1. Удивительная особенность numpy в том, что вам не нужно использовать циклы для изменения массива. Это неправильный способ изменения массива numpy