3

I saw this question,and pop up this idea.

Is there an efficient way to do this in PHP?

EDIT

Best with a demo?

Community
  • 1
  • 1
Mask
  • 33,129
  • 48
  • 101
  • 125

6 Answers6

2

You could use the pear package Math_Matrix for this.

monksy
  • 14,156
  • 17
  • 75
  • 124
Emil H
  • 39,840
  • 10
  • 78
  • 97
  • That link does not yield a page. – monksy Nov 28 '09 at 01:32
  • wow. the pear page really doesn't like that link. went there myself and tried to correct the link. same problem. can't seem to link directly to it. Just have to click Search Packages on the top menu and search for matrix – Jonathan Fingland Nov 28 '09 at 01:35
  • the correct link is pear.php.net/package/Math-Matrix (Sorry, but I cant edit your post to correct the link in place) – Eineki Nov 28 '09 at 01:50
1

This package claims to be able to do what you are looking for.

monksy
  • 14,156
  • 17
  • 75
  • 124
0

There is this open source PHP Library that is able to invert a Matrix.

All you need to do is

<?php
include_once ("Matrix.class.php");
$matrixA = new Matrix(array(array(0, 1), array(2, 6)));
echo $matrixA->getInverse()->getMathMl();
?>
Digerati
  • 93
  • 4
0

Here tested code https://gist.github.com/unix1/7510208 Only identity_matrix() and invert() functions are enough

Abylay
  • 220
  • 2
  • 11
0

Yes there are several ways to accomplish this in php. There are a handful of available libraries. Alternatively, you could maintain your own class and customize as needed. Here is an excerpt from our inhouse library that is based on the mathematical method described in the link. There is a demonstration at the end of the class for further reference.

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
        )

    )
    */
  • 1
    While this code snippet may be the solution, [including an explanation](https://meta.stackexchange.com/questions/114762/explaining-entirely-%E2%80%8C%E2%80%8Bcode-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – Narendra Jadhav Aug 13 '18 at 05:05
-1
/**
* matrix_inverse
*
* Matrix Inverse
* Guass-Jordan Elimination Method
* Reduced Row Eshelon Form (RREF)
*
* In linear algebra an n-by-n (square) matrix A is called invertible (some
* authors use nonsingular or nondegenerate) if there exists an n-by-n matrix    B
* such that AB = BA = In where In denotes the n-by-n identity matrix and the
* multiplication used is ordinary matrix multiplication. If this is the case,
* then the matrix B is uniquely determined by A and is called the inverse of A,
* denoted by A-1. It follows from the theory of matrices that if for finite
* square matrices A and B, then also non-square matrices (m-by-n matrices for
* which m ? n) do not have an inverse. However, in some cases such a matrix may
* have a left inverse or right inverse. If A is m-by-n and the rank of A is
* equal to n, then A has a left inverse: an n-by-m matrix B such that BA = I.
* If A has rank m, then it has a right inverse: an n-by-m matrix B such that
* AB = I.
*
* A square matrix that is not invertible is called singular or degenerate. A
* square matrix is singular if and only if its determinant is 0. Singular
* matrices are rare in the sense that if you pick a random square matrix over
* a continuous uniform distribution on its entries, it will almost surely not
* be singular.
*
* While the most common case is that of matrices over the real or complex
* numbers, all these definitions can be given for matrices over any commutative
* ring. However, in this case the condition for a square matrix to be
* invertible is that its determinant is invertible in the ring, which in
* general is a much stricter requirement than being nonzero. The conditions for
* existence of left-inverse resp. right-inverse are more complicated since a
* notion of rank does not exist over rings.
*/
public function matrix_inverse($m1)
{
    $rows = $this->rows($m1);
    $cols = $this->columns($m1);
    if ($rows != $cols)
    {
        die("Matrim1 is not square. Can not be inverted.");
    }

    $m2 = $this->eye($rows);

    for ($j = 0; $j < $cols; $j++)
    {
        $factor = $m1[$j][$j];
        if ($this->debug)
        {
            fms_writeln('Divide Row [' . $j . '] by ' . $m1[$j][$j] . ' (to
                                                  give us a "1" in the desired position):');
        }
        $m1 = $this->rref_div($m1, $j, $factor);
        $m2 = $this->rref_div($m2, $j, $factor);
        if ($this->debug)
        {
            $this->disp2($m1, $m2);
        }
        for ($i = 0; $i < $rows; $i++)
        {
            if ($i != $j)
            {
                $factor = $m1[$i][$j];
                if ($this->debug)
                {
                    $this->writeln('Row[' . $i . '] - ' . number_format($factor, 4) . ' ×
                                                Row[' . $j . '] (to give us 0 in the desired position):');
                }
                $m1 = $this->rref_sub($m1, $i, $factor, $j);
                $m2 = $this->rref_sub($m2, $i, $factor, $j);
                if ($this->debug)
                {
                    $this->disp2($m1, $m2);
                }
            }
        }
    }
    return $m2;
}
Petrovitch
  • 139
  • 3
  • 11