Да, есть несколько способов сделать это в php. Есть несколько доступных библиотек. Кроме того, вы можете сохранить свой собственный класс и настроить по мере необходимости. Вот выдержка из нашей внутренней библиотеки, основанная на математическом методе, описанном в ссылке. В конце урока проводится демонстрация для дальнейшего ознакомления.
https://www.intmath.com/matrices-determinants/inverse-matrix-gauss-jordan-elimination.php
class MatrixLibrary
{
//Gauss-Jordan elimination method for matrix inverse
public function inverseMatrix(array $matrix)
{
//TODO $matrix validation
$matrixCount = count($matrix);
$identityMatrix = $this->identityMatrix($matrixCount);
$augmentedMatrix = $this->appendIdentityMatrixToMatrix($matrix, $identityMatrix);
$inverseMatrixWithIdentity = $this->createInverseMatrix($augmentedMatrix);
$inverseMatrix = $this->removeIdentityMatrix($inverseMatrixWithIdentity);
return $inverseMatrix;
}
private function createInverseMatrix(array $matrix)
{
$numberOfRows = count($matrix);
for($i=0; $i<$numberOfRows; $i++)
{
$matrix = $this->oneOperation($matrix, $i, $i);
for($j=0; $j<$numberOfRows; $j++)
{
if($i !== $j)
{
$matrix = $this->zeroOperation($matrix, $j, $i, $i);
}
}
}
$inverseMatrixWithIdentity = $matrix;
return $inverseMatrixWithIdentity;
}
private function oneOperation(array $matrix, $rowPosition, $zeroPosition)
{
if($matrix[$rowPosition][$zeroPosition] !== 1)
{
$numberOfCols = count($matrix[$rowPosition]);
if($matrix[$rowPosition][$zeroPosition] === 0)
{
$divisor = 0.0000000001;
$matrix[$rowPosition][$zeroPosition] = 0.0000000001;
}
else
{
$divisor = $matrix[$rowPosition][$zeroPosition];
}
for($i=0; $i<$numberOfCols; $i++)
{
$matrix[$rowPosition][$i] = $matrix[$rowPosition][$i] / $divisor;
}
}
return $matrix;
}
private function zeroOperation(array $matrix, $rowPosition, $zeroPosition, $subjectRow)
{
$numberOfCols = count($matrix[$rowPosition]);
if($matrix[$rowPosition][$zeroPosition] !== 0)
{
$numberToSubtract = $matrix[$rowPosition][$zeroPosition];
for($i=0; $i<$numberOfCols; $i++)
{
$matrix[$rowPosition][$i] = $matrix[$rowPosition][$i] - $numberToSubtract * $matrix[$subjectRow][$i];
}
}
return $matrix;
}
private function removeIdentityMatrix(array $matrix)
{
$inverseMatrix = array();
$matrixCount = count($matrix);
for($i=0; $i<$matrixCount; $i++)
{
$inverseMatrix[$i] = array_slice($matrix[$i], $matrixCount);
}
return $inverseMatrix;
}
private function appendIdentityMatrixToMatrix(array $matrix, array $identityMatrix)
{
//TODO $matrix & $identityMatrix compliance validation (same number of rows/columns, etc)
$augmentedMatrix = array();
for($i=0; $i<count($matrix); $i++)
{
$augmentedMatrix[$i] = array_merge($matrix[$i], $identityMatrix[$i]);
}
return $augmentedMatrix;
}
public function identityMatrix(int $size)
{
//TODO validate $size
$identityMatrix = array();
for($i=0; $i<$size; $i++)
{
for($j=0; $j<$size; $j++)
{
if($i == $j)
{
$identityMatrix[$i][$j] = 1;
}
else
{
$identityMatrix[$i][$j] = 0;
}
}
}
return $identityMatrix;
}
}
$matrix = array(
array(11, 3, 12),
array(8, 7, 10),
array(13, 14, 15),
);
$matrixLibrary = new MatrixLibrary();
$inverseMatrix = $matrixLibrary->inverseMatrix($matrix);
print_r($inverseMatrix);
/*
Array
(
[0] => Array
(
[0] => 0.33980582524272
[1] => -1.1941747572816
[2] => 0.52427184466019
)
[1] => Array
(
[0] => -0.097087378640777
[1] => -0.087378640776699
[2] => 0.13592233009709
)
[2] => Array
(
[0] => -0.20388349514563
[1] => 1.1165048543689
[2] => -0.51456310679612
)
)
*/