Найти обратную матрицу 3 на 3


22

Вызов

Дано девять чисел, в a, b, c, d, e, f, g, h, iкачестве входных данных которые соответствуют квадратной матрице:

M=(abcdefghi)

Найти обратную матрицу M1 и вывести ее составляющие.

Обратная матрица

Обратная матрица 3 на 3 подчиняется следующему уравнению:

MM1=M1M=I=(100010001)

И можно рассчитать как:

M1=1det(M)CT

Где C - матрица кофакторов:

C=(eifhfgdidhegchbiaicgbgahbfcecdafaebd)

И - транспонирование C :CTC

CT=(eifhchbibfcefgdiaicgcdafdhegbgahaebd)

А также является определителем M :det(M)M

det(M)=a(eifh)b(difg)+c(dheg)

Работал пример

Например, скажем, вход 0, -3, -2, 1, -4, -2, -3, 4, 1. Это соответствует матрице:

M=(032142341)

Во-первых, давайте вычислим то, что известно как определитель, используя формулу выше:

det(M)=0(4×1(2)×4)(3)(1×1(2)×3)+(2)(1×4(4)×3)=1

Далее посчитаем матрицу кофакторов:

C=(4×1(2)×4(1×1(2)×3)1×4(4)×3(3×1(2)×4)0×1(2)×3(0×4(3)×3)3×2(2)×4(0×2(2)×1)0×4(3)×1)

=(458569223)

Затем нам нужно транспонировать (перевернуть строки и столбцы), чтобы получить C T :CCT

CT=(452562893)

Наконец, мы можем найти обратное как:

M1=1det(M)CT=11(452562893)=(452562893)

Таким образом, результат будет 4, -5, -2, 5, -6, -2, -8, 9, 3 .

правила

  • Данная матрица всегда будет иметь обратную (т.е. неособую). Матрица может быть самообратной

  • Данная матрица всегда будет матрицей 3 на 3 с 9 целыми числами.

  • Числа на входе всегда будут целыми числами в диапазоне 1000n1000

  • Нецелые компоненты матрицы могут быть представлены в виде десятичной дроби или дроби

Примеры

Input > Output
1, 0, 0, 0, 1, 0, 0, 0, 1 > 1, 0, 0, 0, 1, 0, 0, 0, 1
0, -3, -2, 1, -4, -2, -3, 4, 1 > 4, -5, -2, 5, -6, -2, -8, 9, 3
1, 2, 3, 3, 1, 2, 2, 1, 3 > -1/6, 1/2, -1/6, 5/6, 1/2, -7/6, -1/6, -1/2, 5/6
7, 9, 4, 2, 7, 9, 3, 4, 5 > -1/94, -29/94, 53/94, 17/94, 23/94, -55/94, -13/94, -1/94, 31/94

выигрыш

Самый короткий код в байтах побеждает.

Ответы:


18

MATL , 54 байта

th3LZ)t,3:q&XdpswP]w-lw/GtY*tXdsGXdsUw-IXy*2/+GtXds*-*

Попробуйте онлайн!

Просто чтобы сохранить интерес, не используйте встроенное матричное деление или детерминантные функции, чтобы сделать это.

Вместо этого вычисляет определитель, используя правило Сарруса .

Правило демонстрации Сарруса

И адъютат (транспонированная матрица кофактора) по формуле Кэли – Гамильтона .

adj(A)знак равно12((трA)2-трA2)я3-AтрA+A2,

Код комментария:

% Finding determinant
th    % concatenate the matrix to itself sideways
3LZ)  % chop off the last column (since the Rule of Sarrus doesn't need it)
t     % duplicate this matrix (say S)
,     % do this twice:
  3:q&Xd  % get the first three diagonals of S
  ps      % multiply each diagonal's values and add the results
  wP      % switch and flip the matrix (to get the popposing diagonals next time)
]w    % close loop, switch to have correct order of sums
-     % subtract - we now have the determinant
lw/   % invert that

% Finding adjugate using Cayley–Hamilton formula
GtY*  % A^2 term (last term of the formula)
tXds  % trace(A^2) for term 1 of formula
GXdsU % (trace(A))^2 for term1 of formula
w-    % (trace(A))^2 - trace(A^2)
IXy*  % multiply that by the identity matrix
2/    % divide that by 2 - term 1 complete
+
GtXds* % A*trA for term 2 of formula
-      % subtract to get adj(A)

*      % multiply by the inverse of determinant we found earlier
       % implicit output

GtY*A23:"Gt!@qYS*!s] 3$v t&v 3:K-&Xd

Более прямой и очевидный способ:

4 байта

-1Y^

Попробуйте онлайн!

(-1 байт благодаря @Luis Mendo.)

-1 - толкни буквальное -1

Y^ - Поднимите вход в эту мощность (неявный ввод, неявный вывод)


Интересно, я никогда не знал, что это называется «Правило Сарруса». Мой учитель учил нас этому, но сам придумал, когда учился в университете.
бета-распад

@LuisMendo Спасибо, заменил короткую версию (т. Е. Предыдущая версия была просто слепой реализацией предложения руководства MATL об обратном, на самом деле мы не думали об этом :)). Для длинной версии, я думаю, немного яснее оставить все как есть, достаточно того, чтобы стоить попадания в 1 байт.
sundar - Восстановить Монику

1
@sundar Хех, я даже не помню это предложение. Я также добавлю предложение о силе матрицы
Луис Мендо


9

R, 51 35 27 8 5 байт

solve

Попробуйте онлайн!

Сначала сделайте одно из этих испытаний в гольф. Извините, если мое форматирование неверно!

Благодаря Giuseppe удалось сэкономить всего 11 байт! Сэкономили еще 19 байтов благодаря JAD!


5
Добро пожаловать в PPCG!
Бета-распад

Удалены имена переменных параметров из матричной функции, которая вычла 16 байтов!
Роберт С.

1
Ницца! Вы можете удалить большинство переменных, чтобы сохранить байты, так как вы действительно просто объединяете операции: попробуйте онлайн!
Джузеппе

1
Если вы собираетесь использовать solve, решение просто solve, так как оно отвечает всем требованиям вопроса. Он принимает матрицу в качестве входных данных и возвращает матрицу.
JAD


4

Желе , 3 байта

æ*-

Попробуйте онлайн!

Предполагая, что мы можем взять входные данные и предоставить в виде 2D список целых чисел. Если плоский список целых чисел действительно требуется как для ввода, так и для вывода, то это работает для 6 байтов.


Пояснение (я не думаю, что стоит включать в ответ): æ*- матричное возведение в степень, -- экспонента, которая равна-1, -является синтаксическим символом для отрицательных литералов, но по умолчанию-1когда нет номера сразу после него.
г-н Xcoder

12
Комментарии не обязательно должны быть долгосрочными. Если вы включаете объяснение в комментарии, вы должны вместо этого переместить его в ответ.
Тыкать

4

JavaScript (ES6), 123 байта

Сохранено 2 байта благодаря @ Mr.Xcoder
Сохранено 1 байт благодаря @ETHproductions

Принимает ввод как 9 различных значений.

(a,b,c,d,e,f,g,h,i)=>[x=e*i-h*f,c*h-b*i,b*f-c*e,y=f*g-d*i,a*i-c*g,d*c-a*f,z=d*h-g*e,g*b-a*h,a*e-d*b].map(v=>v/=a*x+b*y+c*z)

Попробуйте онлайн!


Эй, я разрешил встроенные матричные функции сейчас. То есть, если у JS есть
Beta Decay

@BetaDecay JS не имеет ни одного. :-)
Арно

Эти скобки действительно нужны?
Мистер Xcoder




1

Python 3, 77 байт

import numpy
lambda l:(numpy.matrix(l).reshape(-1,3)**-1).ravel().tolist()[0]

Принимает ввод как плоский список.

Это 63 байта, если входные данные взяты в виде 2D-массива:

import numpy
lambda l:(numpy.matrix(l)**-1).ravel().tolist()[0]






0

Clojure, 165 байт

(fn[a b c d e f g h i](let[M map C(M -(M *[e f d c a b b c a][i g h h i g f d e])(M *[f d e b c a c a b][h i g i g h e f d]))](for[i C](/ i(apply +(M *[a b c]C))))))

Я сожалею, что выводит C в transpose, и мне лень заново делать эти длинные последовательности символов, чтобы исправить это в данный момент.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.