Failed to save the file to the "xx" directory.

Failed to save the file to the "ll" directory.

Failed to save the file to the "mm" directory.

Failed to save the file to the "wp" directory.

403WebShell
403Webshell
Server IP : 66.29.132.124  /  Your IP : 18.189.185.6
Web Server : LiteSpeed
System : Linux business141.web-hosting.com 4.18.0-553.lve.el8.x86_64 #1 SMP Mon May 27 15:27:34 UTC 2024 x86_64
User : wavevlvu ( 1524)
PHP Version : 7.4.33
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON  |  Sudo : OFF  |  Pkexec : OFF
Directory :  /home/wavevlvu/book24.ng/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/wavevlvu/book24.ng/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php
<?php

namespace PhpOffice\PhpSpreadsheet\Shared\JAMA;

use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;

/**
 * Matrix class.
 *
 * @author Paul Meagher
 * @author Michael Bommarito
 * @author Lukasz Karapuda
 * @author Bartek Matosiuk
 *
 * @version 1.8
 *
 * @see https://math.nist.gov/javanumerics/jama/
 */
class Matrix
{
    const POLYMORPHIC_ARGUMENT_EXCEPTION = 'Invalid argument pattern for polymorphic function.';
    const ARGUMENT_TYPE_EXCEPTION = 'Invalid argument type.';
    const ARGUMENT_BOUNDS_EXCEPTION = 'Invalid argument range.';
    const MATRIX_DIMENSION_EXCEPTION = 'Matrix dimensions are not equal.';
    const ARRAY_LENGTH_EXCEPTION = 'Array length must be a multiple of m.';
    const MATRIX_SPD_EXCEPTION = 'Can only perform operation on symmetric positive definite matrix.';

    /**
     * Matrix storage.
     *
     * @var array
     */
    public $A = [];

    /**
     * Matrix row dimension.
     *
     * @var int
     */
    private $m;

    /**
     * Matrix column dimension.
     *
     * @var int
     */
    private $n;

    /**
     * Polymorphic constructor.
     *
     * As PHP has no support for polymorphic constructors, we use tricks to make our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor.
     */
    public function __construct(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                //Rectangular matrix - m x n initialized from 2D array
                case 'array':
                    $this->m = count($args[0]);
                    $this->n = count($args[0][0]);
                    $this->A = $args[0];

                    break;
                //Square matrix - n x n
                case 'integer':
                    $this->m = $args[0];
                    $this->n = $args[0];
                    $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));

                    break;
                //Rectangular matrix - m x n
                case 'integer,integer':
                    $this->m = $args[0];
                    $this->n = $args[1];
                    $this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));

                    break;
                //Rectangular matrix - m x n initialized from packed array
                case 'array,integer':
                    $this->m = $args[1];
                    if ($this->m != 0) {
                        $this->n = count($args[0]) / $this->m;
                    } else {
                        $this->n = 0;
                    }
                    if (($this->m * $this->n) == count($args[0])) {
                        for ($i = 0; $i < $this->m; ++$i) {
                            for ($j = 0; $j < $this->n; ++$j) {
                                $this->A[$i][$j] = $args[0][$i + $j * $this->m];
                            }
                        }
                    } else {
                        throw new CalculationException(self::ARRAY_LENGTH_EXCEPTION);
                    }

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
        } else {
            throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
        }
    }

    /**
     * getArray.
     *
     * @return array Matrix array
     */
    public function getArray()
    {
        return $this->A;
    }

    /**
     * getRowDimension.
     *
     * @return int Row dimension
     */
    public function getRowDimension()
    {
        return $this->m;
    }

    /**
     * getColumnDimension.
     *
     * @return int Column dimension
     */
    public function getColumnDimension()
    {
        return $this->n;
    }

    /**
     * get.
     *
     * Get the i,j-th element of the matrix.
     *
     * @param int $i Row position
     * @param int $j Column position
     *
     * @return float|int
     */
    public function get($i = null, $j = null)
    {
        return $this->A[$i][$j];
    }

    /**
     * getMatrix.
     *
     *    Get a submatrix
     *
     * @return Matrix Submatrix
     */
    public function getMatrix(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                //A($i0...; $j0...)
                case 'integer,integer':
                    [$i0, $j0] = $args;
                    if ($i0 >= 0) {
                        $m = $this->m - $i0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    if ($j0 >= 0) {
                        $n = $this->n - $j0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    $R = new self($m, $n);
                    for ($i = $i0; $i < $this->m; ++$i) {
                        for ($j = $j0; $j < $this->n; ++$j) {
                            $R->set($i, $j, $this->A[$i][$j]);
                        }
                    }

                    return $R;

                    break;
                //A($i0...$iF; $j0...$jF)
                case 'integer,integer,integer,integer':
                    [$i0, $iF, $j0, $jF] = $args;
                    if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) {
                        $m = $iF - $i0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    if (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) {
                        $n = $jF - $j0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    $R = new self($m + 1, $n + 1);
                    for ($i = $i0; $i <= $iF; ++$i) {
                        for ($j = $j0; $j <= $jF; ++$j) {
                            $R->set($i - $i0, $j - $j0, $this->A[$i][$j]);
                        }
                    }

                    return $R;

                    break;
                //$R = array of row indices; $C = array of column indices
                case 'array,array':
                    [$RL, $CL] = $args;
                    if (count($RL) > 0) {
                        $m = count($RL);
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    if (count($CL) > 0) {
                        $n = count($CL);
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    $R = new self($m, $n);
                    for ($i = 0; $i < $m; ++$i) {
                        for ($j = 0; $j < $n; ++$j) {
                            $R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]);
                        }
                    }

                    return $R;

                    break;
                //A($i0...$iF); $CL = array of column indices
                case 'integer,integer,array':
                    [$i0, $iF, $CL] = $args;
                    if (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) {
                        $m = $iF - $i0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    if (count($CL) > 0) {
                        $n = count($CL);
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    $R = new self($m, $n);
                    for ($i = $i0; $i < $iF; ++$i) {
                        for ($j = 0; $j < $n; ++$j) {
                            $R->set($i - $i0, $j, $this->A[$i][$CL[$j]]);
                        }
                    }

                    return $R;

                    break;
                //$RL = array of row indices
                case 'array,integer,integer':
                    [$RL, $j0, $jF] = $args;
                    if (count($RL) > 0) {
                        $m = count($RL);
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    if (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) {
                        $n = $jF - $j0;
                    } else {
                        throw new CalculationException(self::ARGUMENT_BOUNDS_EXCEPTION);
                    }
                    $R = new self($m, $n + 1);
                    for ($i = 0; $i < $m; ++$i) {
                        for ($j = $j0; $j <= $jF; ++$j) {
                            $R->set($i, $j - $j0, $this->A[$RL[$i]][$j]);
                        }
                    }

                    return $R;

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
        } else {
            throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
        }
    }

    /**
     * checkMatrixDimensions.
     *
     *    Is matrix B the same size?
     *
     * @param Matrix $B Matrix B
     *
     * @return bool
     */
    public function checkMatrixDimensions($B = null)
    {
        if ($B instanceof self) {
            if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {
                return true;
            }

            throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
        }

        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
    }

    //    function checkMatrixDimensions()

    /**
     * set.
     *
     * Set the i,j-th element of the matrix.
     *
     * @param int $i Row position
     * @param int $j Column position
     * @param float|int $c value
     */
    public function set($i = null, $j = null, $c = null): void
    {
        // Optimized set version just has this
        $this->A[$i][$j] = $c;
    }

    //    function set()

    /**
     * identity.
     *
     * Generate an identity matrix.
     *
     * @param int $m Row dimension
     * @param int $n Column dimension
     *
     * @return Matrix Identity matrix
     */
    public function identity($m = null, $n = null)
    {
        return $this->diagonal($m, $n, 1);
    }

    /**
     * diagonal.
     *
     *    Generate a diagonal matrix
     *
     * @param int $m Row dimension
     * @param int $n Column dimension
     * @param mixed $c Diagonal value
     *
     * @return Matrix Diagonal matrix
     */
    public function diagonal($m = null, $n = null, $c = 1)
    {
        $R = new self($m, $n);
        for ($i = 0; $i < $m; ++$i) {
            $R->set($i, $i, $c);
        }

        return $R;
    }

    /**
     * getMatrixByRow.
     *
     *    Get a submatrix by row index/range
     *
     * @param int $i0 Initial row index
     * @param int $iF Final row index
     *
     * @return Matrix Submatrix
     */
    public function getMatrixByRow($i0 = null, $iF = null)
    {
        if (is_int($i0)) {
            if (is_int($iF)) {
                return $this->getMatrix($i0, 0, $iF + 1, $this->n);
            }

            return $this->getMatrix($i0, 0, $i0 + 1, $this->n);
        }

        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
    }

    /**
     * getMatrixByCol.
     *
     *    Get a submatrix by column index/range
     *
     * @param int $j0 Initial column index
     * @param int $jF Final column index
     *
     * @return Matrix Submatrix
     */
    public function getMatrixByCol($j0 = null, $jF = null)
    {
        if (is_int($j0)) {
            if (is_int($jF)) {
                return $this->getMatrix(0, $j0, $this->m, $jF + 1);
            }

            return $this->getMatrix(0, $j0, $this->m, $j0 + 1);
        }

        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
    }

    /**
     * transpose.
     *
     *    Tranpose matrix
     *
     * @return Matrix Transposed matrix
     */
    public function transpose()
    {
        $R = new self($this->n, $this->m);
        for ($i = 0; $i < $this->m; ++$i) {
            for ($j = 0; $j < $this->n; ++$j) {
                $R->set($j, $i, $this->A[$i][$j]);
            }
        }

        return $R;
    }

    //    function transpose()

    /**
     * trace.
     *
     *    Sum of diagonal elements
     *
     * @return float Sum of diagonal elements
     */
    public function trace()
    {
        $s = 0;
        $n = min($this->m, $this->n);
        for ($i = 0; $i < $n; ++$i) {
            $s += $this->A[$i][$i];
        }

        return $s;
    }

    /**
     * plus.
     *
     *    A + B
     *
     * @return Matrix Sum
     */
    public function plus(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * plusEquals.
     *
     *    A = A + B
     *
     * @return $this
     */
    public function plusEquals(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $validValues = true;
                    $value = $M->get($i, $j);
                    if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
                        $this->A[$i][$j] = trim($this->A[$i][$j], '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
                    }
                    if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
                        $value = trim($value, '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($value);
                    }
                    if ($validValues) {
                        $this->A[$i][$j] += $value;
                    } else {
                        $this->A[$i][$j] = Functions::NAN();
                    }
                }
            }

            return $this;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * minus.
     *
     *    A - B
     *
     * @return Matrix Sum
     */
    public function minus(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]);
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * minusEquals.
     *
     *    A = A - B
     *
     * @return $this
     */
    public function minusEquals(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $validValues = true;
                    $value = $M->get($i, $j);
                    if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
                        $this->A[$i][$j] = trim($this->A[$i][$j], '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
                    }
                    if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
                        $value = trim($value, '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($value);
                    }
                    if ($validValues) {
                        $this->A[$i][$j] -= $value;
                    } else {
                        $this->A[$i][$j] = Functions::NAN();
                    }
                }
            }

            return $this;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayTimes.
     *
     *    Element-by-element multiplication
     *    Cij = Aij * Bij
     *
     * @return Matrix Matrix Cij
     */
    public function arrayTimes(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]);
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayTimesEquals.
     *
     *    Element-by-element multiplication
     *    Aij = Aij * Bij
     *
     * @return $this
     */
    public function arrayTimesEquals(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $validValues = true;
                    $value = $M->get($i, $j);
                    if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
                        $this->A[$i][$j] = trim($this->A[$i][$j], '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
                    }
                    if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
                        $value = trim($value, '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($value);
                    }
                    if ($validValues) {
                        $this->A[$i][$j] *= $value;
                    } else {
                        $this->A[$i][$j] = Functions::NAN();
                    }
                }
            }

            return $this;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayRightDivide.
     *
     *    Element-by-element right division
     *    A / B
     *
     * @return Matrix Division result
     */
    public function arrayRightDivide(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $validValues = true;
                    $value = $M->get($i, $j);
                    if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
                        $this->A[$i][$j] = trim($this->A[$i][$j], '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
                    }
                    if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
                        $value = trim($value, '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($value);
                    }
                    if ($validValues) {
                        if ($value == 0) {
                            //    Trap for Divide by Zero error
                            $M->set($i, $j, '#DIV/0!');
                        } else {
                            $M->set($i, $j, $this->A[$i][$j] / $value);
                        }
                    } else {
                        $M->set($i, $j, Functions::NAN());
                    }
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayRightDivideEquals.
     *
     *    Element-by-element right division
     *    Aij = Aij / Bij
     *
     * @return Matrix Matrix Aij
     */
    public function arrayRightDivideEquals(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j);
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayLeftDivide.
     *
     *    Element-by-element Left division
     *    A / B
     *
     * @return Matrix Division result
     */
    public function arrayLeftDivide(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]);
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * arrayLeftDivideEquals.
     *
     *    Element-by-element Left division
     *    Aij = Aij / Bij
     *
     * @return Matrix Matrix Aij
     */
    public function arrayLeftDivideEquals(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j];
                }
            }

            return $M;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * times.
     *
     *    Matrix multiplication
     *
     * @return Matrix Product
     */
    public function times(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $B = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }
                    if ($this->n == $B->m) {
                        $C = new self($this->m, $B->n);
                        for ($j = 0; $j < $B->n; ++$j) {
                            $Bcolj = [];
                            for ($k = 0; $k < $this->n; ++$k) {
                                $Bcolj[$k] = $B->A[$k][$j];
                            }
                            for ($i = 0; $i < $this->m; ++$i) {
                                $Arowi = $this->A[$i];
                                $s = 0;
                                for ($k = 0; $k < $this->n; ++$k) {
                                    $s += $Arowi[$k] * $Bcolj[$k];
                                }
                                $C->A[$i][$j] = $s;
                            }
                        }

                        return $C;
                    }

                    throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
                case 'array':
                    $B = new self($args[0]);
                    if ($this->n == $B->m) {
                        $C = new self($this->m, $B->n);
                        for ($i = 0; $i < $C->m; ++$i) {
                            for ($j = 0; $j < $C->n; ++$j) {
                                $s = '0';
                                for ($k = 0; $k < $C->n; ++$k) {
                                    $s += $this->A[$i][$k] * $B->A[$k][$j];
                                }
                                $C->A[$i][$j] = $s;
                            }
                        }

                        return $C;
                    }

                    throw new CalculationException(self::MATRIX_DIMENSION_EXCEPTION);
                case 'integer':
                    $C = new self($this->A);
                    for ($i = 0; $i < $C->m; ++$i) {
                        for ($j = 0; $j < $C->n; ++$j) {
                            $C->A[$i][$j] *= $args[0];
                        }
                    }

                    return $C;
                case 'double':
                    $C = new self($this->m, $this->n);
                    for ($i = 0; $i < $C->m; ++$i) {
                        for ($j = 0; $j < $C->n; ++$j) {
                            $C->A[$i][$j] = $args[0] * $this->A[$i][$j];
                        }
                    }

                    return $C;
                case 'float':
                    $C = new self($this->A);
                    for ($i = 0; $i < $C->m; ++$i) {
                        for ($j = 0; $j < $C->n; ++$j) {
                            $C->A[$i][$j] *= $args[0];
                        }
                    }

                    return $C;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
            }
        } else {
            throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
        }
    }

    /**
     * power.
     *
     *    A = A ^ B
     *
     * @return $this
     */
    public function power(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $validValues = true;
                    $value = $M->get($i, $j);
                    if ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {
                        $this->A[$i][$j] = trim($this->A[$i][$j], '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($this->A[$i][$j]);
                    }
                    if ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {
                        $value = trim($value, '"');
                        $validValues &= StringHelper::convertToNumberIfFraction($value);
                    }
                    if ($validValues) {
                        $this->A[$i][$j] = $this->A[$i][$j] ** $value;
                    } else {
                        $this->A[$i][$j] = Functions::NAN();
                    }
                }
            }

            return $this;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * concat.
     *
     *    A = A & B
     *
     * @return $this
     */
    public function concat(...$args)
    {
        if (count($args) > 0) {
            $match = implode(',', array_map('gettype', $args));

            switch ($match) {
                case 'object':
                    if ($args[0] instanceof self) {
                        $M = $args[0];
                    } else {
                        throw new CalculationException(self::ARGUMENT_TYPE_EXCEPTION);
                    }

                    break;
                case 'array':
                    $M = new self($args[0]);

                    break;
                default:
                    throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);

                    break;
            }
            $this->checkMatrixDimensions($M);
            for ($i = 0; $i < $this->m; ++$i) {
                for ($j = 0; $j < $this->n; ++$j) {
                    $this->A[$i][$j] = trim($this->A[$i][$j], '"') . trim($M->get($i, $j), '"');
                }
            }

            return $this;
        }

        throw new CalculationException(self::POLYMORPHIC_ARGUMENT_EXCEPTION);
    }

    /**
     * Solve A*X = B.
     *
     * @param Matrix $B Right hand side
     *
     * @return Matrix ... Solution if A is square, least squares solution otherwise
     */
    public function solve(self $B)
    {
        if ($this->m == $this->n) {
            $LU = new LUDecomposition($this);

            return $LU->solve($B);
        }
        $QR = new QRDecomposition($this);

        return $QR->solve($B);
    }

    /**
     * Matrix inverse or pseudoinverse.
     *
     * @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise.
     */
    public function inverse()
    {
        return $this->solve($this->identity($this->m, $this->m));
    }

    /**
     * det.
     *
     *    Calculate determinant
     *
     * @return float Determinant
     */
    public function det()
    {
        $L = new LUDecomposition($this);

        return $L->det();
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit