Нахождение обратной матрицы по правилу Крамера

Я создал определитель функции, который выводит определитель матрицы 3x3. Мне также нужно создать функцию для инвертирования этой матрицы, однако код, похоже, не работает, и я не могу понять, почему.

M = np.array([
 [4.,3.,9.],
 [2.,1.,8.],
 [10.,7.,5.]
 ])

def inverse(M):
'''
This function finds the inverse of a matrix using the Cramers rule.

Input: Matrix - M
Output: The inverse of the Matrix - M.
'''

    d = determinant(M) # Simply returns the determinant of the matrix M.

    counter = 1
    array = []

    for line in M: # This for loop simply creates a co-factor of Matrix M and puts it in a list.
        y = []
        for item in line:
             if counter %2 == 0:
                x = -item
             else:
                x = item
         counter += 1
        y.append(x)
    array.append(y)

    cf = np.matrix(array) # Translating the list into a matrix.
    adj = np.matrix.transpose(cf) # Transposing the matrix.
    inv = (1/d) * adj
    return inv

ВЫВОД:

через обратный (M):

 [[ 0.0952381  -0.04761905  0.23809524],
 [-0.07142857  0.02380952 -0.16666667],
 [ 0.21428571 -0.19047619  0.11904762]]

через встроенную обратную функцию numpy:

 [[-1.21428571  1.14285714  0.35714286]
 [ 1.66666667 -1.66666667 -0.33333333]
 [ 0.0952381   0.04761905 -0.04761905]]

Как вы можете видеть, некоторые числа совпадают, и я просто не уверен, почему ответ не является точным, поскольку я правильно использую формулу.

Вы уверены, что функция determinant работает правильно? Вы не показываете его, поэтому мы не можем запустить ваш код.

Rory Daulton 23.01.2019 15:07

Если я не ошибаюсь, то для вычисления матрицы кофакторов нужно много раз вызывать determinant (по 1 разу на каждую ячейку, поэтому на практике этот метод используется редко), а в вашем коде я его вообще не вижу. AFAIU, вы не можете построить кофактор, просто инвертируя некоторые знаки в исходной матрице. Я что-то пропустил?

SergGr 23.01.2019 15:16

Я не включал функцию определителя, так как она успешно работает. Его можно заменить встроенной функцией определителя (np.linalg.det(M))

definaly 23.01.2019 16:13
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
3
447
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Ваш расчет матрицы кофакторов неверен.

def inverse(M):
  d = np.linalg.det(M)

  cf_mat = []
  for i in range(M.shape[0]):
      for j in range(M.shape[1]):
          # for each position we need to calculate det
          # of submatrix without current row and column
          # and multiply it on position coefficient
          coef = (-1) ** (i + j)
          new_mat = []
          for i1 in range(M.shape[0]):
              for j1 in range(M.shape[1]):
                  if i1 != i and j1 != j:
                      new_mat.append(M[i1, j1])
          new_mat = np.array(new_mat).reshape(
              (M.shape[0] - 1, M.shape[1] - 1))
          new_mat_det = np.linalg.det(new_mat)
          cf_mat.append(new_mat_det * coef)

  cf_mat = np.array(cf_mat).reshape(M.shape)
  adj = np.matrix.transpose(cf_mat)
  inv = (1 / d) * adj
  return inv

Этот код не очень эффективен, но здесь вы можете видеть, как он должен рассчитываться. Более подробную информацию и четкую формулу вы можете найти на Wiki.

Выходная матрица:

[[-1.21428571  1.14285714  0.35714286]
 [ 1.66666667 -1.66666667 -0.33333333]
 [ 0.0952381   0.04761905 -0.04761905]]

Другие вопросы по теме