Calculate the row echelon form (REF) of the matrix using Gaussian
elimination. Return the matrix and the number of swaps in a tuple.

@throws \RuntimeException
@return array
421721
public function gaussianElimination() : array
    {
        $minDim = min($this->shape());

        $b = $this->a;

        $swaps = 0;

        for ($k = 0; $k < $minDim; $k++) {
            $index = $k;

            for ($i = $k; $i < $this->m; $i++) {
                if (abs($b[$i][$k]) > abs($b[$index][$k])) {
                    $index = $i;
                }
            }

            if ($b[$index][$k] == 0) {
                throw new RuntimeException('Cannot compute row echelon form'
                    . ' of a singular matrix.');
            }

            if ($k !== $index) {
                $temp = $b[$k];

                $b[$k] = $b[$index];
                $b[$index] = $temp;

                $swaps++;
            }

            $diag = $b[$k][$k];

            for ($i = $k + 1; $i < $this->m; $i++) {
                $scale = $diag != 0 ? $b[$i][$k] / $diag : 1;
                
                for ($j = $k + 1; $j < $this->n; $j++) {
                    $b[$i][$j] -= $scale * $b[$k][$j];
                }
                
                $b[$i][$k] = 0;
            }
        }

        $b = self::quick($b);

        return [$b, $swaps];
    }
474025
public function getRowsCountRecursive()
    {
        $totalCount = 0;
        foreach ($this->rows as $row) {
            $subTable = $row->getSubtable();
            if ($subTable) {
                $count = $subTable->getRowsCountRecursive();
                $totalCount += $count;
            }
        }

        $totalCount += $this->getRowsCount();
        return $totalCount;
    }
991735
public function argmax() : ColumnVector
    {
        $b = [];

        foreach ($this->a as $row) {
            $b[] = (int) array_search(max($row), $row);
        }

        return ColumnVector::quick($b);
    }
466055
public function eig(bool $normalize = true) : array
    {
        if (!$this->isSquare()) {
            throw new RuntimeException('Cannot decompose a non'
                . ' square matrix.');
        }

        $jama = new JAMA($this->a);

        $decomp = $jama->eig();

        $eigenvalues = $decomp->getRealEigenvalues();
        $eigenvectors = $decomp->getV()->getArray();

        $eigenvectors = self::quick($eigenvectors)
            ->transpose();

        if ($normalize === true) {
            $norm = $eigenvectors->transpose()
                ->square()
                ->sum()
                ->sqrt()
                ->transpose();
        
            $eigenvectors = $eigenvectors->divide($norm);
        }

        return [$eigenvalues, $eigenvectors];
    }
1017934
public function inverse() {
        $determinant = $this->determinant();
        if ($determinant == 0) { // If 0, there is no inverse.
            return;
        }

        $adj = $this->getAdjoinMatrix();
        for ($i=0; $i<static::ROWS; $i++) {
            $sign = ($i%2 === 1) ? -1 : 1;
            for ($j=0; $j<static::COLUMNS; $j++) {
                $adj[$i][$j] = $sign * $adj[$i][$j];
                $sign        = -$sign;
            }
        }

        $this->copy($adj);
        $this->transpose();
        $div = 1 / $determinant;
        $this->mul($div);
    }
876109
public static function MINVERSE($matrixValues)
    {
        $matrixData = array();
        if (!is_array($matrixValues)) {
            $matrixValues = array(array($matrixValues));
        }

        $row = $maxColumn = 0;
        foreach ($matrixValues as $matrixRow) {
            if (!is_array($matrixRow)) {
                $matrixRow = array($matrixRow);
            }
            $column = 0;
            foreach ($matrixRow as $matrixCell) {
                if ((is_string($matrixCell)) || ($matrixCell === null)) {
                    return PHPExcel_Calculation_Functions::VALUE();
                }
                $matrixData[$column][$row] = $matrixCell;
                ++$column;
            }
            if ($column > $maxColumn) {
                $maxColumn = $column;
            }
            ++$row;
        }
        if ($row != $maxColumn) {
            return PHPExcel_Calculation_Functions::VALUE();
        }

        try {
            $matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData);
            return $matrix->inverse()->getArray();
        } catch (PHPExcel_Exception $ex) {
            return PHPExcel_Calculation_Functions::VALUE();
        }
    }
933421
private function decodeList()
    {
        $list = array();
        $terminated = false;
        $listOffset = $this->offset;

        while (false !== $this->getChar()) {
            if ("e" == $this->getChar()) {
                $terminated = true;
                break;
            }

            $list[] = $this->doDecode();
        }

        if (!$terminated && false === $this->getChar()) {
            throw new RuntimeException("Unterminated list definition at offset $listOffset");
        }

        $this->offset++;

        return $list;
    }
942393
public function getMatrixByRow($i0 = null, $iF = null)
    {
        if (is_int($i0)) {
            if (is_int($iF)) {
                return $this->getMatrix($i0, 0, $iF + 1, $this->n);
            } else {
                return $this->getMatrix($i0, 0, $i0 + 1, $this->n);
            }
        } else {
            trigger_error(ArgumentTypeException, ERROR);
        }
    }
223353
public function getAdjoinMatrix() : Matrix {
        $matrix = new static();
        for ($i=0; $i<static::ROWS; $i++) {
            for ($j=0; $j<static::COLUMNS; $j++) {
                $subMatrix      = MatrixMath::getSubMatrix($this->toArray(), $i, $j);
                $matrix[$i][$j] = MatrixMath::calculateDeterminant($subMatrix);
            }
        }
        return $matrix;
    }
1330754
public function det()
    {
        if ($this->m !== $this->n) {
            throw MatrixException::notSquareMatrix();
        }

        $d = $this->pivsign;
        for ($j = 0; $j < $this->n; ++$j) {
            $d *= $this->LU[$j][$j];
        }

        return $d;
    }
1024784
public function getEnumerators(): array
    {
        $enumeration = $this->enumeration;
        $enumerators = [];
        foreach ($this->getOrdinals() as $ord) {
            $enumerators[] = $enumeration::byOrdinal($ord);
        }
        return $enumerators;
    }
512842
public function getRows()
    {
        $out = new ArrayList();
        foreach ($this->rows as $row) {
            $columns = new ArrayList();
            foreach ($row as $column => $value) {
                $columns->push(
                    new ArrayData(array(
                        "Heading"=> $column,
                        "Value" => $value
                    ))
                );
            }
            $out->push(
                new ArrayData(array(
                    "Columns" => $columns
                ))
            );
        }
        return $out;
    }
982075
public function toArray()
    {
        $arr = [];
        foreach ($this as $k => $v) {
            if ($v instanceof Enumerable) {
                $arr[] = $v->toArray();
            } else {
                $arr[] = $v;
            }
        }

        return $arr;
    }
100871
public function getU()
    {
        $U = [];
        for ($i = 0; $i < $this->n; ++$i) {
            for ($j = 0; $j < $this->n; ++$j) {
                if ($i <= $j) {
                    $U[$i][$j] = $this->LU[$i][$j];
                } else {
                    $U[$i][$j] = 0.0;
                }
            }
        }
        return new Matrix($U);
    }
1071817
public Matrix[] svd() {
		GMatrix m = (GMatrix) matrix.clone();
		int nrows = (int) getRowCount();
		int ncols = (int) getColumnCount();
		GMatrix u = new GMatrix(nrows, nrows);
		GMatrix s = new GMatrix(nrows, ncols);
		GMatrix v = new GMatrix(ncols, ncols);
		m.SVD(u, s, v);
		Matrix U = new VecMathDenseDoubleMatrix2D(u);
		Matrix S = new VecMathDenseDoubleMatrix2D(s);
		Matrix V = new VecMathDenseDoubleMatrix2D(v);
		return new Matrix[] { U, S, V };
	}
1274238
public T transpose() {
        T ret = createMatrix(mat.getNumCols(),mat.getNumRows(), mat.getType());

        ops.transpose(mat,ret.mat);

        return ret;
    }
1059573
public function asColumnMatrix() : Matrix
    {
        $b = [];

        foreach ($this->a as $value) {
            $b[] = [$value];
        }

        return Matrix::quick($b);
    }