JAMA
[ class tree: JAMA ] [ index: JAMA ] [ all elements ]

Source for file Matrix.php

Documentation is available at Matrix.php

  1. <?php
  2. /**
  3.  * @package JAMA
  4.  */
  5.  
  6. define('RAND_MAX'mt_getrandmax());
  7. define('RAND_MIN'0);
  8.  
  9. /** PHPExcel root directory */
  10. if (!defined('PHPEXCEL_ROOT')) {
  11.     /**
  12.      * @ignore
  13.      */
  14.     define('PHPEXCEL_ROOT'dirname(__FILE__'/../../../');
  15. }
  16.  
  17. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/utils/Error.php';
  18. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/utils/Maths.php';
  19. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/CholeskyDecomposition.php';
  20. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/LUDecomposition.php';
  21. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/QRDecomposition.php';
  22. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/EigenvalueDecomposition.php';
  23. require_once PHPEXCEL_ROOT 'PHPExcel/Shared/JAMA/SingularValueDecomposition.php';
  24.  
  25. /*
  26.  *    Matrix class
  27.  *
  28.  *    @author Paul Meagher
  29.  *    @author Michael Bommarito
  30.  *    @author Lukasz Karapuda
  31.  *    @author Bartek Matosiuk
  32.  *    @version 1.8
  33.  *    @license PHP v3.0
  34.  *    @see http://math.nist.gov/javanumerics/jama/
  35.  */
  36. class Matrix {
  37.  
  38.     /**
  39.      *    Matrix storage
  40.      *
  41.      *    @var array 
  42.      *    @access public
  43.      */
  44.     public $A = array();
  45.  
  46.     /**
  47.      *    Matrix row dimension
  48.      *
  49.      *    @var int 
  50.      *    @access private
  51.      */
  52.     private $m;
  53.  
  54.     /**
  55.      *    Matrix column dimension
  56.      *
  57.      *    @var int 
  58.      *    @access private
  59.      */
  60.     private $n;
  61.  
  62.  
  63.     /**
  64.      *    Polymorphic constructor
  65.      *
  66.      *    As PHP has no support for polymorphic constructors, we hack 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.
  67.      */
  68.     public function __construct({
  69.         if (func_num_args(0{
  70.             $args func_get_args();
  71.             $match implode(","array_map('gettype'$args));
  72.  
  73.             switch($match{
  74.                 //Square matrix - n x n
  75.                 case 'integer':
  76.                         $this->m = $args[0];
  77.                         $this->n = $args[0];
  78.                         $this->A = array_fill(0$this->marray_fill(0$this->n0));
  79.                         break;
  80.                 //Rectangular matrix - m x n
  81.                 case 'integer,integer':
  82.                         $this->m = $args[0];
  83.                         $this->n = $args[1];
  84.                         $this->A = array_fill(0$this->marray_fill(0$this->n0));
  85.                         break;
  86.                 //Rectangular matrix constant-filled - m x n filled with c
  87.                 case 'integer,integer,integer':
  88.                         $this->m = $args[0];
  89.                         $this->n = $args[1];
  90.                         $this->A = array_fill(0$this->marray_fill(0$this->n$args[2]));
  91.                         break;
  92.                 //Rectangular matrix constant-filled - m x n filled with c
  93.                 case 'integer,integer,double':
  94.                         $this->m = $args[0];
  95.                         $this->n = $args[1];
  96.                         $this->A = array_fill(0$this->marray_fill(0$this->n$args[2]));
  97.                         break;
  98.                 //Rectangular matrix - m x n initialized from 2D array
  99.                 case 'array':
  100.                         $this->m = count($args[0]);
  101.                         $this->n = count($args[0][0]);
  102.                         $this->A = $args[0];
  103.                         break;
  104.                 //Rectangular matrix - m x n initialized from 2D array
  105.                 case 'array,integer,integer':
  106.                         $this->m = $args[1];
  107.                         $this->n = $args[2];
  108.                         $this->A = $args[0];
  109.                         break;
  110.                 //Rectangular matrix - m x n initialized from packed array
  111.                 case 'array,integer':
  112.                         $this->m = $args[1];
  113.                         if ($this->m != 0{
  114.                             $this->n = count($args[0]$this->m;
  115.                         else {
  116.                             $this->n = 0;
  117.                         }
  118.                         if (($this->m * $this->n== count($args[0])) {
  119.                             for($i 0$i $this->m++$i{
  120.                                 for($j 0$j $this->n++$j{
  121.                                     $this->A[$i][$j$args[0][$i $j $this->m];
  122.                                 }
  123.                             }
  124.                         else {
  125.                             throw new Exception(JAMAError(ArrayLengthException));
  126.                         }
  127.                         break;
  128.                 default:
  129.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  130.                         break;
  131.             }
  132.         else {
  133.             throw new Exception(JAMAError(PolymorphicArgumentException));
  134.         }
  135.     }    //    function __construct()
  136.  
  137.  
  138.     /**
  139.      *    getArray
  140.      *
  141.      *    @return array Matrix array
  142.      */
  143.     public function getArray({
  144.         return $this->A;
  145.     }    //    function getArray()
  146.  
  147.  
  148.     /**
  149.      *    getArrayCopy
  150.      *
  151.      *    @return array Matrix array copy
  152.      */
  153.     public function getArrayCopy({
  154.         return $this->A;
  155.     }    //    function getArrayCopy()
  156.  
  157.  
  158.     /**
  159.      *    constructWithCopy
  160.      *    Construct a matrix from a copy of a 2-D array.
  161.      *
  162.      *    @param double A[][]        Two-dimensional array of doubles.
  163.      *    @exception    IllegalArgumentException All rows must have the same length
  164.      */
  165.     public function constructWithCopy($A{
  166.         $this->m = count($A);
  167.         $this->n = count($A[0]);
  168.         $newCopyMatrix new Matrix($this->m$this->n);
  169.         for ($i 0$i $this->m++$i{
  170.             if (count($A[$i]!= $this->n{
  171.                 throw new Exception(JAMAError(RowLengthException));
  172.             }
  173.             for ($j 0$j $this->n++$j{
  174.                 $newCopyMatrix->A[$i][$j$A[$i][$j];
  175.             }
  176.         }
  177.         return $newCopyMatrix;
  178.     }    //    function constructWithCopy()
  179.  
  180.  
  181.     /**
  182.      *    getColumnPackedCopy
  183.      *
  184.      *    Get a column-packed array
  185.      *    @return array Column-packed matrix array
  186.      */
  187.     public function getColumnPackedCopy({
  188.         $P array();
  189.         for($i 0$i $this->m++$i{
  190.             for($j 0$j $this->n++$j{
  191.                 array_push($P$this->A[$j][$i]);
  192.             }
  193.         }
  194.         return $P;
  195.     }    //    function getColumnPackedCopy()
  196.  
  197.  
  198.     /**
  199.      *    getRowPackedCopy
  200.      *
  201.      *    Get a row-packed array
  202.      *    @return array Row-packed matrix array
  203.      */
  204.     public function getRowPackedCopy({
  205.         $P array();
  206.         for($i 0$i $this->m++$i{
  207.             for($j 0$j $this->n++$j{
  208.                 array_push($P$this->A[$i][$j]);
  209.             }
  210.         }
  211.         return $P;
  212.     }    //    function getRowPackedCopy()
  213.  
  214.  
  215.     /**
  216.      *    getRowDimension
  217.      *
  218.      *    @return int Row dimension
  219.      */
  220.     public function getRowDimension({
  221.         return $this->m;
  222.     }    //    function getRowDimension()
  223.  
  224.  
  225.     /**
  226.      *    getColumnDimension
  227.      *
  228.      *    @return int Column dimension
  229.      */
  230.     public function getColumnDimension({
  231.         return $this->n;
  232.     }    //    function getColumnDimension()
  233.  
  234.  
  235.     /**
  236.      *    get
  237.      *
  238.      *    Get the i,j-th element of the matrix.
  239.      *    @param int $i Row position
  240.      *    @param int $j Column position
  241.      *    @return mixed Element (int/float/double)
  242.      */
  243.     public function get($i null$j null{
  244.         return $this->A[$i][$j];
  245.     }    //    function get()
  246.  
  247.  
  248.     /**
  249.      *    getMatrix
  250.      *
  251.      *    Get a submatrix
  252.      *    @param int $i0 Initial row index
  253.      *    @param int $iF Final row index
  254.      *    @param int $j0 Initial column index
  255.      *    @param int $jF Final column index
  256.      *    @return Matrix Submatrix
  257.      */
  258.     public function getMatrix({
  259.         if (func_num_args(0{
  260.             $args func_get_args();
  261.             $match implode(","array_map('gettype'$args));
  262.  
  263.             switch($match{
  264.                 //A($i0...; $j0...)
  265.                 case 'integer,integer':
  266.                         list($i0$j0$args;
  267.                         if ($i0 >= 0$m $this->m - $i0else throw new Exception(JAMAError(ArgumentBoundsException))}
  268.                         if ($j0 >= 0$n $this->n - $j0else throw new Exception(JAMAError(ArgumentBoundsException))}
  269.                         $R new Matrix($m$n);
  270.                         for($i $i0$i $this->m++$i{
  271.                             for($j $j0$j $this->n++$j{
  272.                                 $R->set($i$j$this->A[$i][$j]);
  273.                             }
  274.                         }
  275.                         return $R;
  276.                         break;
  277.                 //A($i0...$iF; $j0...$jF)
  278.                 case 'integer,integer,integer,integer':
  279.                         list($i0$iF$j0$jF$args;
  280.                         if (($iF $i0&& ($this->m >= $iF&& ($i0 >= 0)) $m $iF $i0else throw new Exception(JAMAError(ArgumentBoundsException))}
  281.                         if (($jF $j0&& ($this->n >= $jF&& ($j0 >= 0)) $n $jF $j0else throw new Exception(JAMAError(ArgumentBoundsException))}
  282.                         $R new Matrix($m+1$n+1);
  283.                         for($i $i0$i <= $iF++$i{
  284.                             for($j $j0$j <= $jF++$j{
  285.                                 $R->set($i $i0$j $j0$this->A[$i][$j]);
  286.                             }
  287.                         }
  288.                         return $R;
  289.                         break;
  290.                 //$R = array of row indices; $C = array of column indices
  291.                 case 'array,array':
  292.                         list($RL$CL$args;
  293.                         if (count($RL0$m count($RL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  294.                         if (count($CL0$n count($CL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  295.                         $R new Matrix($m$n);
  296.                         for($i 0$i $m++$i{
  297.                             for($j 0$j $n++$j{
  298.                                 $R->set($i $i0$j $j0$this->A[$RL[$i]][$CL[$j]]);
  299.                             }
  300.                         }
  301.                         return $R;
  302.                         break;
  303.                 //$RL = array of row indices; $CL = array of column indices
  304.                 case 'array,array':
  305.                         list($RL$CL$args;
  306.                         if (count($RL0$m count($RL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  307.                         if (count($CL0$n count($CL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  308.                         $R new Matrix($m$n);
  309.                         for($i 0$i $m++$i{
  310.                             for($j 0$j $n++$j{
  311.                                 $R->set($i$j$this->A[$RL[$i]][$CL[$j]]);
  312.                             }
  313.                         }
  314.                         return $R;
  315.                         break;
  316.                 //A($i0...$iF); $CL = array of column indices
  317.                 case 'integer,integer,array':
  318.                         list($i0$iF$CL$args;
  319.                         if (($iF $i0&& ($this->m >= $iF&& ($i0 >= 0)) $m $iF $i0else throw new Exception(JAMAError(ArgumentBoundsException))}
  320.                         if (count($CL0$n count($CL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  321.                         $R new Matrix($m$n);
  322.                         for($i $i0$i $iF++$i{
  323.                             for($j 0$j $n++$j{
  324.                                 $R->set($i $i0$j$this->A[$RL[$i]][$j]);
  325.                             }
  326.                         }
  327.                         return $R;
  328.                         break;
  329.                 //$RL = array of row indices
  330.                 case 'array,integer,integer':
  331.                         list($RL$j0$jF$args;
  332.                         if (count($RL0$m count($RL)else throw new Exception(JAMAError(ArgumentBoundsException))}
  333.                         if (($jF >= $j0&& ($this->n >= $jF&& ($j0 >= 0)) $n $jF $j0else throw new Exception(JAMAError(ArgumentBoundsException))}
  334.                         $R new Matrix($m$n+1);
  335.                         for($i 0$i $m++$i{
  336.                             for($j $j0$j <= $jF++$j{
  337.                                 $R->set($i$j $j0$this->A[$RL[$i]][$j]);
  338.                             }
  339.                         }
  340.                         return $R;
  341.                         break;
  342.                 default:
  343.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  344.                         break;
  345.             }
  346.         else {
  347.             throw new Exception(JAMAError(PolymorphicArgumentException));
  348.         }
  349.     }    //    function getMatrix()
  350.  
  351.  
  352.     /**
  353.      *    setMatrix
  354.      *
  355.      *    Set a submatrix
  356.      *    @param int $i0 Initial row index
  357.      *    @param int $j0 Initial column index
  358.      *    @param mixed $S Matrix/Array submatrix
  359.      *     ($i0, $j0, $S) $S = Matrix
  360.      *     ($i0, $j0, $S) $S = Array
  361.      */
  362.     public function setMatrix({
  363.         if (func_num_args(0{
  364.             $args func_get_args();
  365.             $match implode(","array_map('gettype'$args));
  366.  
  367.             switch($match{
  368.                 case 'integer,integer,object':
  369.                         if ($args[2instanceof Matrix$M $args[2]else throw new Exception(JAMAError(ArgumentTypeException))}
  370.                         if (($args[0$M->m<= $this->m$i0 $args[0]else throw new Exception(JAMAError(ArgumentBoundsException))}
  371.                         if (($args[1$M->n<= $this->n$j0 $args[1]else throw new Exception(JAMAError(ArgumentBoundsException))}
  372.                         for($i $i0$i $i0 $M->m++$i{
  373.                             for($j $j0$j $j0 $M->n++$j{
  374.                                 $this->A[$i][$j$M->get($i $i0$j $j0);
  375.                             }
  376.                         }
  377.                         break;
  378.                 case 'integer,integer,array':
  379.                         $M new Matrix($args[2]);
  380.                         if (($args[0$M->m<= $this->m$i0 $args[0]else throw new Exception(JAMAError(ArgumentBoundsException))}
  381.                         if (($args[1$M->n<= $this->n$j0 $args[1]else throw new Exception(JAMAError(ArgumentBoundsException))}
  382.                         for($i $i0$i $i0 $M->m++$i{
  383.                             for($j $j0$j $j0 $M->n++$j{
  384.                                 $this->A[$i][$j$M->get($i $i0$j $j0);
  385.                             }
  386.                         }
  387.                         break;
  388.                 default:
  389.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  390.                         break;
  391.             }
  392.         else {
  393.             throw new Exception(JAMAError(PolymorphicArgumentException));
  394.         }
  395.     }    //    function setMatrix()
  396.  
  397.  
  398.     /**
  399.      *    checkMatrixDimensions
  400.      *
  401.      *    Is matrix B the same size?
  402.      *    @param Matrix $B Matrix B
  403.      *    @return boolean 
  404.      */
  405.     public function checkMatrixDimensions($B null{
  406.         if ($B instanceof Matrix{
  407.             if (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {
  408.                 return true;
  409.             else {
  410.                 throw new Exception(JAMAError(MatrixDimensionException));
  411.             }
  412.         else {
  413.             throw new Exception(JAMAError(ArgumentTypeException));
  414.         }
  415.     }    //    function checkMatrixDimensions()
  416.  
  417.  
  418.  
  419.     /**
  420.      *    set
  421.      *
  422.      *    Set the i,j-th element of the matrix.
  423.      *    @param int $i Row position
  424.      *    @param int $j Column position
  425.      *    @param mixed $c Int/float/double value
  426.      *    @return mixed Element (int/float/double)
  427.      */
  428.     public function set($i null$j null$c null{
  429.         // Optimized set version just has this
  430.         $this->A[$i][$j$c;
  431.         /*
  432.         if (is_int($i) && is_int($j) && is_numeric($c)) {
  433.             if (($i < $this->m) && ($j < $this->n)) {
  434.                 $this->A[$i][$j] = $c;
  435.             } else {
  436.                 echo "A[$i][$j] = $c<br />";
  437.                 throw new Exception(JAMAError(ArgumentBoundsException));
  438.             }
  439.         } else {
  440.             throw new Exception(JAMAError(ArgumentTypeException));
  441.         }
  442.         */
  443.     }    //    function set()
  444.  
  445.  
  446.     /**
  447.      *    identity
  448.      *
  449.      *    Generate an identity matrix.
  450.      *    @param int $m Row dimension
  451.      *    @param int $n Column dimension
  452.      *    @return Matrix Identity matrix
  453.      */
  454.     public function identity($m null$n null{
  455.         return $this->diagonal($m$n1);
  456.     }    //    function identity()
  457.  
  458.  
  459.     /**
  460.      *    diagonal
  461.      *
  462.      *    Generate a diagonal matrix
  463.      *    @param int $m Row dimension
  464.      *    @param int $n Column dimension
  465.      *    @param mixed $c Diagonal value
  466.      *    @return Matrix Diagonal matrix
  467.      */
  468.     public function diagonal($m null$n null$c 1{
  469.         $R new Matrix($m$n);
  470.         for($i 0$i $m++$i{
  471.             $R->set($i$i$c);
  472.         }
  473.         return $R;
  474.     }    //    function diagonal()
  475.  
  476.  
  477.     /**
  478.      *    filled
  479.      *
  480.      *    Generate a filled matrix
  481.      *    @param int $m Row dimension
  482.      *    @param int $n Column dimension
  483.      *    @param int $c Fill constant
  484.      *    @return Matrix Filled matrix
  485.      */
  486.     public function filled($m null$n null$c 0{
  487.         if (is_int($m&& is_int($n&& is_numeric($c)) {
  488.             $R new Matrix($m$n$c);
  489.             return $R;
  490.         else {
  491.             throw new Exception(JAMAError(ArgumentTypeException));
  492.         }
  493.     }    //    function filled()
  494.  
  495.     /**
  496.      *    random
  497.      *
  498.      *    Generate a random matrix
  499.      *    @param int $m Row dimension
  500.      *    @param int $n Column dimension
  501.      *    @return Matrix Random matrix
  502.      */
  503.     public function random($m null$n null$a RAND_MIN$b RAND_MAX{
  504.         if (is_int($m&& is_int($n&& is_numeric($a&& is_numeric($b)) {
  505.             $R new Matrix($m$n);
  506.             for($i 0$i $m++$i{
  507.                 for($j 0$j $n++$j{
  508.                     $R->set($i$jmt_rand($a$b));
  509.                 }
  510.             }
  511.             return $R;
  512.         else {
  513.             throw new Exception(JAMAError(ArgumentTypeException));
  514.         }
  515.     }    //    function random()
  516.  
  517.  
  518.     /**
  519.      *    packed
  520.      *
  521.      *    Alias for getRowPacked
  522.      *    @return array Packed array
  523.      */
  524.     public function packed({
  525.         return $this->getRowPacked();
  526.     }    //    function packed()
  527.  
  528.  
  529.     /**
  530.      *    getMatrixByRow
  531.      *
  532.      *    Get a submatrix by row index/range
  533.      *    @param int $i0 Initial row index
  534.      *    @param int $iF Final row index
  535.      *    @return Matrix Submatrix
  536.      */
  537.     public function getMatrixByRow($i0 null$iF null{
  538.         if (is_int($i0)) {
  539.             if (is_int($iF)) {
  540.                 return $this->getMatrix($i00$iF 1$this->n);
  541.             else {
  542.                 return $this->getMatrix($i00$i0 1$this->n);
  543.             }
  544.         else {
  545.             throw new Exception(JAMAError(ArgumentTypeException));
  546.         }
  547.     }    //    function getMatrixByRow()
  548.  
  549.  
  550.     /**
  551.      *    getMatrixByCol
  552.      *
  553.      *    Get a submatrix by column index/range
  554.      *    @param int $i0 Initial column index
  555.      *    @param int $iF Final column index
  556.      *    @return Matrix Submatrix
  557.      */
  558.     public function getMatrixByCol($j0 null$jF null{
  559.         if (is_int($j0)) {
  560.             if (is_int($jF)) {
  561.                 return $this->getMatrix(0$j0$this->m$jF 1);
  562.             else {
  563.                 return $this->getMatrix(0$j0$this->m$j0 1);
  564.             }
  565.         else {
  566.             throw new Exception(JAMAError(ArgumentTypeException));
  567.         }
  568.     }    //    function getMatrixByCol()
  569.  
  570.  
  571.     /**
  572.      *    transpose
  573.      *
  574.      *    Tranpose matrix
  575.      *    @return Matrix Transposed matrix
  576.      */
  577.     public function transpose({
  578.         $R new Matrix($this->n$this->m);
  579.         for($i 0$i $this->m++$i{
  580.             for($j 0$j $this->n++$j{
  581.                 $R->set($j$i$this->A[$i][$j]);
  582.             }
  583.         }
  584.         return $R;
  585.     }    //    function transpose()
  586.  
  587.  
  588.     /**
  589.      *    norm1
  590.      *
  591.      *    One norm
  592.      *    @return float Maximum column sum
  593.      */
  594.     public function norm1({
  595.         $r 0;
  596.         for($j 0$j $this->n++$j{
  597.             $s 0;
  598.             for($i 0$i $this->m++$i{
  599.                 $s += abs($this->A[$i][$j]);
  600.             }
  601.             $r ($r $s$r $s;
  602.         }
  603.         return $r;
  604.     }    //    function norm1()
  605.  
  606.  
  607.     /**
  608.      *    norm2
  609.      *
  610.      *    Maximum singular value
  611.      *    @return float Maximum singular value
  612.      */
  613.     public function norm2({
  614.     }    //    function norm2()
  615.  
  616.  
  617.     /**
  618.      *    normInf
  619.      *
  620.      *    Infinite norm
  621.      *    @return float Maximum row sum
  622.      */
  623.     public function normInf({
  624.         $r 0;
  625.         for($i 0$i $this->m++$i{
  626.             $s 0;
  627.             for($j 0$j $this->n++$j{
  628.                 $s += abs($this->A[$i][$j]);
  629.             }
  630.             $r ($r $s$r $s;
  631.         }
  632.         return $r;
  633.     }    //    function normInf()
  634.  
  635.  
  636.     /**
  637.      *    normF
  638.      *
  639.      *    Frobenius norm
  640.      *    @return float Square root of the sum of all elements squared
  641.      */
  642.     public function normF({
  643.         $f 0;
  644.         for ($i 0$i $this->m++$i{
  645.             for ($j 0$j $this->n++$j{
  646.                 $f hypo($f,$this->A[$i][$j]);
  647.             }
  648.         }
  649.         return $f;
  650.     }    //    function normF()
  651.  
  652.  
  653.     /**
  654.      *    Matrix rank
  655.      *
  656.      *    @return effective numerical rank, obtained from SVD.
  657.      */
  658.     public function rank ({
  659.         $svd new SingularValueDecomposition($this);
  660.         return $svd->rank();
  661.     }    //    function rank ()
  662.  
  663.  
  664.     /**
  665.      *    Matrix condition (2 norm)
  666.      *
  667.      *    @return ratio of largest to smallest singular value.
  668.      */
  669.     public function cond ({
  670.         $svd new SingularValueDecomposition($this);
  671.         return $svd->cond();
  672.     }    //    function cond ()
  673.  
  674.  
  675.     /**
  676.      *    trace
  677.      *
  678.      *    Sum of diagonal elements
  679.      *    @return float Sum of diagonal elements
  680.      */
  681.     public function trace({
  682.         $s 0;
  683.         $n min($this->m$this->n);
  684.         for($i 0$i $n++$i{
  685.             $s += $this->A[$i][$i];
  686.         }
  687.         return $s;
  688.     }    //    function trace()
  689.  
  690.  
  691.     /**
  692.      *    uminus
  693.      *
  694.      *    Unary minus matrix -A
  695.      *    @return Matrix Unary minus matrix
  696.      */
  697.     public function uminus({
  698.     }    //    function uminus()
  699.  
  700.  
  701.     /**
  702.      *    plus
  703.      *
  704.      *    A + B
  705.      *    @param mixed $B Matrix/Array
  706.      *    @return Matrix Sum
  707.      */
  708.     public function plus({
  709.         if (func_num_args(0{
  710.             $args func_get_args();
  711.             $match implode(","array_map('gettype'$args));
  712.  
  713.             switch($match{
  714.                 case 'object':
  715.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  716.                         break;
  717.                 case 'array':
  718.                         $M new Matrix($args[0]);
  719.                         break;
  720.                 default:
  721.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  722.                         break;
  723.             }
  724.             $this->checkMatrixDimensions($M);
  725.             for($i 0$i $this->m++$i{
  726.                 for($j 0$j $this->n++$j{
  727.                     $M->set($i$j$M->get($i$j$this->A[$i][$j]);
  728.                 }
  729.             }
  730.             return $M;
  731.         else {
  732.             throw new Exception(JAMAError(PolymorphicArgumentException));
  733.         }
  734.     }    //    function plus()
  735.  
  736.  
  737.     /**
  738.      *    plusEquals
  739.      *
  740.      *    A = A + B
  741.      *    @param mixed $B Matrix/Array
  742.      *    @return Matrix Sum
  743.      */
  744.     public function plusEquals({
  745.         if (func_num_args(0{
  746.             $args func_get_args();
  747.             $match implode(","array_map('gettype'$args));
  748.  
  749.             switch($match{
  750.                 case 'object':
  751.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  752.                         break;
  753.                 case 'array':
  754.                         $M new Matrix($args[0]);
  755.                         break;
  756.                 default:
  757.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  758.                         break;
  759.             }
  760.             $this->checkMatrixDimensions($M);
  761.             for($i 0$i $this->m++$i{
  762.                 for($j 0$j $this->n++$j{
  763.                     $this->A[$i][$j+= $M->get($i$j);
  764.                 }
  765.             }
  766.             return $this;
  767.         else {
  768.             throw new Exception(JAMAError(PolymorphicArgumentException));
  769.         }
  770.     }    //    function plusEquals()
  771.  
  772.  
  773.     /**
  774.      *    minus
  775.      *
  776.      *    A - B
  777.      *    @param mixed $B Matrix/Array
  778.      *    @return Matrix Sum
  779.      */
  780.     public function minus({
  781.         if (func_num_args(0{
  782.             $args func_get_args();
  783.             $match implode(","array_map('gettype'$args));
  784.  
  785.             switch($match{
  786.                 case 'object':
  787.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  788.                         break;
  789.                 case 'array':
  790.                         $M new Matrix($args[0]);
  791.                         break;
  792.                 default:
  793.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  794.                         break;
  795.             }
  796.             $this->checkMatrixDimensions($M);
  797.             for($i 0$i $this->m++$i{
  798.                 for($j 0$j $this->n++$j{
  799.                     $M->set($i$j$M->get($i$j$this->A[$i][$j]);
  800.                 }
  801.             }
  802.             return $M;
  803.         else {
  804.             throw new Exception(JAMAError(PolymorphicArgumentException));
  805.         }
  806.     }    //    function minus()
  807.  
  808.  
  809.     /**
  810.      *    minusEquals
  811.      *
  812.      *    A = A - B
  813.      *    @param mixed $B Matrix/Array
  814.      *    @return Matrix Sum
  815.      */
  816.     public function minusEquals({
  817.         if (func_num_args(0{
  818.             $args func_get_args();
  819.             $match implode(","array_map('gettype'$args));
  820.  
  821.             switch($match{
  822.                 case 'object':
  823.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  824.                         break;
  825.                 case 'array':
  826.                         $M new Matrix($args[0]);
  827.                         break;
  828.                 default:
  829.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  830.                         break;
  831.             }
  832.             $this->checkMatrixDimensions($M);
  833.             for($i 0$i $this->m++$i{
  834.                 for($j 0$j $this->n++$j{
  835.                     $this->A[$i][$j-= $M->get($i$j);
  836.                 }
  837.             }
  838.             return $this;
  839.         else {
  840.             throw new Exception(JAMAError(PolymorphicArgumentException));
  841.         }
  842.     }    //    function minusEquals()
  843.  
  844.  
  845.     /**
  846.      *    arrayTimes
  847.      *
  848.      *    Element-by-element multiplication
  849.      *    Cij = Aij * Bij
  850.      *    @param mixed $B Matrix/Array
  851.      *    @return Matrix Matrix Cij
  852.      */
  853.     public function arrayTimes({
  854.         if (func_num_args(0{
  855.             $args func_get_args();
  856.             $match implode(","array_map('gettype'$args));
  857.  
  858.             switch($match{
  859.                 case 'object':
  860.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  861.                         break;
  862.                 case 'array':
  863.                         $M new Matrix($args[0]);
  864.                         break;
  865.                 default:
  866.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  867.                         break;
  868.             }
  869.             $this->checkMatrixDimensions($M);
  870.             for($i 0$i $this->m++$i{
  871.                 for($j 0$j $this->n++$j{
  872.                     $M->set($i$j$M->get($i$j$this->A[$i][$j]);
  873.                 }
  874.             }
  875.             return $M;
  876.         else {
  877.             throw new Exception(JAMAError(PolymorphicArgumentException));
  878.         }
  879.     }    //    function arrayTimes()
  880.  
  881.  
  882.     /**
  883.      *    arrayTimesEquals
  884.      *
  885.      *    Element-by-element multiplication
  886.      *    Aij = Aij * Bij
  887.      *    @param mixed $B Matrix/Array
  888.      *    @return Matrix Matrix Aij
  889.      */
  890.     public function arrayTimesEquals({
  891.         if (func_num_args(0{
  892.             $args func_get_args();
  893.             $match implode(","array_map('gettype'$args));
  894.  
  895.             switch($match{
  896.                 case 'object':
  897.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  898.                         break;
  899.                 case 'array':
  900.                         $M new Matrix($args[0]);
  901.                         break;
  902.                 default:
  903.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  904.                         break;
  905.             }
  906.             $this->checkMatrixDimensions($M);
  907.             for($i 0$i $this->m++$i{
  908.                 for($j 0$j $this->n++$j{
  909.                     $this->A[$i][$j*= $M->get($i$j);
  910.                 }
  911.             }
  912.             return $this;
  913.         else {
  914.             throw new Exception(JAMAError(PolymorphicArgumentException));
  915.         }
  916.     }    //    function arrayTimesEquals()
  917.  
  918.  
  919.     /**
  920.      *    arrayRightDivide
  921.      *
  922.      *    Element-by-element right division
  923.      *    A / B
  924.      *    @param Matrix $B Matrix B
  925.      *    @return Matrix Division result
  926.      */
  927.     public function arrayRightDivide({
  928.         if (func_num_args(0{
  929.             $args func_get_args();
  930.             $match implode(","array_map('gettype'$args));
  931.  
  932.             switch($match{
  933.                 case 'object':
  934.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  935.                         break;
  936.                 case 'array':
  937.                         $M new Matrix($args[0]);
  938.                         break;
  939.                 default:
  940.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  941.                         break;
  942.             }
  943.             $this->checkMatrixDimensions($M);
  944.             for($i 0$i $this->m++$i{
  945.                 for($j 0$j $this->n++$j{
  946.                     $M->set($i$j$this->A[$i][$j$M->get($i$j));
  947.                 }
  948.             }
  949.             return $M;
  950.         else {
  951.             throw new Exception(JAMAError(PolymorphicArgumentException));
  952.         }
  953.     }    //    function arrayRightDivide()
  954.  
  955.  
  956.     /**
  957.      *    arrayRightDivideEquals
  958.      *
  959.      *    Element-by-element right division
  960.      *    Aij = Aij / Bij
  961.      *    @param mixed $B Matrix/Array
  962.      *    @return Matrix Matrix Aij
  963.      */
  964.     public function arrayRightDivideEquals({
  965.         if (func_num_args(0{
  966.             $args func_get_args();
  967.             $match implode(","array_map('gettype'$args));
  968.  
  969.             switch($match{
  970.                 case 'object':
  971.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  972.                         break;
  973.                 case 'array':
  974.                         $M new Matrix($args[0]);
  975.                         break;
  976.                 default:
  977.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  978.                         break;
  979.             }
  980.             $this->checkMatrixDimensions($M);
  981.             for($i 0$i $this->m++$i{
  982.                 for($j 0$j $this->n++$j{
  983.                     $this->A[$i][$j$this->A[$i][$j$M->get($i$j);
  984.                 }
  985.             }
  986.             return $M;
  987.         else {
  988.             throw new Exception(JAMAError(PolymorphicArgumentException));
  989.         }
  990.     }    //    function arrayRightDivideEquals()
  991.  
  992.  
  993.     /**
  994.      *    arrayLeftDivide
  995.      *
  996.      *    Element-by-element Left division
  997.      *    A / B
  998.      *    @param Matrix $B Matrix B
  999.      *    @return Matrix Division result
  1000.      */
  1001.     public function arrayLeftDivide({
  1002.         if (func_num_args(0{
  1003.             $args func_get_args();
  1004.             $match implode(","array_map('gettype'$args));
  1005.  
  1006.             switch($match{
  1007.                 case 'object':
  1008.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  1009.                         break;
  1010.                 case 'array':
  1011.                         $M new Matrix($args[0]);
  1012.                         break;
  1013.                 default:
  1014.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  1015.                         break;
  1016.             }
  1017.             $this->checkMatrixDimensions($M);
  1018.             for($i 0$i $this->m++$i{
  1019.                 for($j 0$j $this->n++$j{
  1020.                     $M->set($i$j$M->get($i$j$this->A[$i][$j]);
  1021.                 }
  1022.             }
  1023.             return $M;
  1024.         else {
  1025.             throw new Exception(JAMAError(PolymorphicArgumentException));
  1026.         }
  1027.     }    //    function arrayLeftDivide()
  1028.  
  1029.  
  1030.     /**
  1031.      *    arrayLeftDivideEquals
  1032.      *
  1033.      *    Element-by-element Left division
  1034.      *    Aij = Aij / Bij
  1035.      *    @param mixed $B Matrix/Array
  1036.      *    @return Matrix Matrix Aij
  1037.      */
  1038.     public function arrayLeftDivideEquals({
  1039.         if (func_num_args(0{
  1040.             $args func_get_args();
  1041.             $match implode(","array_map('gettype'$args));
  1042.  
  1043.             switch($match{
  1044.                 case 'object':
  1045.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  1046.                         break;
  1047.                 case 'array':
  1048.                         $M new Matrix($args[0]);
  1049.                         break;
  1050.                 default:
  1051.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  1052.                         break;
  1053.             }
  1054.             $this->checkMatrixDimensions($M);
  1055.             for($i 0$i $this->m++$i{
  1056.                 for($j 0$j $this->n++$j{
  1057.                     $this->A[$i][$j$M->get($i$j$this->A[$i][$j];
  1058.                 }
  1059.             }
  1060.             return $M;
  1061.         else {
  1062.             throw new Exception(JAMAError(PolymorphicArgumentException));
  1063.         }
  1064.     }    //    function arrayLeftDivideEquals()
  1065.  
  1066.  
  1067.     /**
  1068.      *    times
  1069.      *
  1070.      *    Matrix multiplication
  1071.      *    @param mixed $n Matrix/Array/Scalar
  1072.      *    @return Matrix Product
  1073.      */
  1074.     public function times({
  1075.         if (func_num_args(0{
  1076.             $args  func_get_args();
  1077.             $match implode(","array_map('gettype'$args));
  1078.  
  1079.             switch($match{
  1080.                 case 'object':
  1081.                         if ($args[0instanceof Matrix$B $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  1082.                         if ($this->n == $B->m{
  1083.                             $C new Matrix($this->m$B->n);
  1084.                             for($j 0$j $B->n++$j{
  1085.                                 for ($k 0$k $this->n++$k{
  1086.                                     $Bcolj[$k$B->A[$k][$j];
  1087.                                 }
  1088.                                 for($i 0$i $this->m++$i{
  1089.                                     $Arowi $this->A[$i];
  1090.                                     $s 0;
  1091.                                     for($k 0$k $this->n++$k{
  1092.                                         $s += $Arowi[$k$Bcolj[$k];
  1093.                                     }
  1094.                                     $C->A[$i][$j$s;
  1095.                                 }
  1096.                             }
  1097.                             return $C;
  1098.                         else {
  1099.                             throw new Exception(JAMAError(MatrixDimensionMismatch));
  1100.                         }
  1101.                         break;
  1102.                 case 'array':
  1103.                         $B new Matrix($args[0]);
  1104.                         if ($this->n == $B->m{
  1105.                             $C new Matrix($this->m$B->n);
  1106.                             for($i 0$i $C->m++$i{
  1107.                                 for($j 0$j $C->n++$j{
  1108.                                     $s "0";
  1109.                                     for($k 0$k $C->n++$k{
  1110.                                         $s += $this->A[$i][$k$B->A[$k][$j];
  1111.                                     }
  1112.                                     $C->A[$i][$j$s;
  1113.                                 }
  1114.                             }
  1115.                             return $C;
  1116.                         else {
  1117.                             throw new Exception(JAMAError(MatrixDimensionMismatch));
  1118.                         }
  1119.                         return $M;
  1120.                         break;
  1121.                 case 'integer':
  1122.                         $C new Matrix($this->A);
  1123.                         for($i 0$i $C->m++$i{
  1124.                             for($j 0$j $C->n++$j{
  1125.                                 $C->A[$i][$j*= $args[0];
  1126.                             }
  1127.                         }
  1128.                         return $C;
  1129.                         break;
  1130.                 case 'double':
  1131.                         $C new Matrix($this->m$this->n);
  1132.                         for($i 0$i $C->m++$i{
  1133.                             for($j 0$j $C->n++$j{
  1134.                                 $C->A[$i][$j$args[0$this->A[$i][$j];
  1135.                             }
  1136.                         }
  1137.                         return $C;
  1138.                         break;
  1139.                 case 'float':
  1140.                         $C new Matrix($this->A);
  1141.                         for($i 0$i $C->m++$i{
  1142.                             for($j 0$j $C->n++$j{
  1143.                                 $C->A[$i][$j*= $args[0];
  1144.                             }
  1145.                         }
  1146.                         return $C;
  1147.                         break;
  1148.                 default:
  1149.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  1150.                         break;
  1151.             }
  1152.         else {
  1153.             throw new Exception(PolymorphicArgumentException);
  1154.         }
  1155.     }    //    function times()
  1156.  
  1157.  
  1158.     /**
  1159.      *    power
  1160.      *
  1161.      *    A = A ^ B
  1162.      *    @param mixed $B Matrix/Array
  1163.      *    @return Matrix Sum
  1164.      */
  1165.     public function power({
  1166.         if (func_num_args(0{
  1167.             $args func_get_args();
  1168.             $match implode(","array_map('gettype'$args));
  1169.  
  1170.             switch($match{
  1171.                 case 'object':
  1172.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  1173.                         break;
  1174.                 case 'array':
  1175.                         $M new Matrix($args[0]);
  1176.                         break;
  1177.                 default:
  1178.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  1179.                         break;
  1180.             }
  1181.             $this->checkMatrixDimensions($M);
  1182.             for($i 0$i $this->m++$i{
  1183.                 for($j 0$j $this->n++$j{
  1184.                     $this->A[$i][$jpow($this->A[$i][$j],$M->get($i$j));
  1185.                 }
  1186.             }
  1187.             return $this;
  1188.         else {
  1189.             throw new Exception(JAMAError(PolymorphicArgumentException));
  1190.         }
  1191.     }    //    function power()
  1192.  
  1193.  
  1194.     /**
  1195.      *    concat
  1196.      *
  1197.      *    A = A & B
  1198.      *    @param mixed $B Matrix/Array
  1199.      *    @return Matrix Sum
  1200.      */
  1201.     public function concat({
  1202.         if (func_num_args(0{
  1203.             $args func_get_args();
  1204.             $match implode(","array_map('gettype'$args));
  1205.  
  1206.             switch($match{
  1207.                 case 'object':
  1208.                         if ($args[0instanceof Matrix$M $args[0]else throw new Exception(JAMAError(ArgumentTypeException))}
  1209.                 case 'array':
  1210.                         $M new Matrix($args[0]);
  1211.                         break;
  1212.                 default:
  1213.                         throw new Exception(JAMAError(PolymorphicArgumentException));
  1214.                         break;
  1215.             }
  1216.             $this->checkMatrixDimensions($M);
  1217.             for($i 0$i $this->m++$i{
  1218.                 for($j 0$j $this->n++$j{
  1219. //                    $this->A[$i][$j] = '"'.trim($this->A[$i][$j],'"').trim($M->get($i, $j),'"').'"';
  1220.                     $this->A[$i][$jtrim($this->A[$i][$j],'"').trim($M->get($i$j),'"');
  1221.                 }
  1222.             }
  1223.             return $this;
  1224.         else {
  1225.             throw new Exception(JAMAError(PolymorphicArgumentException));
  1226.         }
  1227.     }    //    function concat()
  1228.  
  1229.  
  1230.     /**
  1231.      *    chol
  1232.      *
  1233.      *    Cholesky decomposition
  1234.      *    @return Matrix Cholesky decomposition
  1235.      */
  1236.     public function chol({
  1237.         return new CholeskyDecomposition($this);
  1238.     }    //    function chol()
  1239.  
  1240.  
  1241.     /**
  1242.      *    lu
  1243.      *
  1244.      *    LU decomposition
  1245.      *    @return Matrix LU decomposition
  1246.      */
  1247.     public function lu({
  1248.         return new LUDecomposition($this);
  1249.     }    //    function lu()
  1250.  
  1251.  
  1252.     /**
  1253.      *    qr
  1254.      *
  1255.      *    QR decomposition
  1256.      *    @return Matrix QR decomposition
  1257.      */
  1258.     public function qr({
  1259.         return new QRDecomposition($this);
  1260.     }    //    function qr()
  1261.  
  1262.  
  1263.     /**
  1264.      *    eig
  1265.      *
  1266.      *    Eigenvalue decomposition
  1267.      *    @return Matrix Eigenvalue decomposition
  1268.      */
  1269.     public function eig({
  1270.         return new EigenvalueDecomposition($this);
  1271.     }    //    function eig()
  1272.  
  1273.  
  1274.     /**
  1275.      *    svd
  1276.      *
  1277.      *    Singular value decomposition
  1278.      *    @return Singular value decomposition
  1279.      */
  1280.     public function svd({
  1281.         return new SingularValueDecomposition($this);
  1282.     }    //    function svd()
  1283.  
  1284.  
  1285.     /**
  1286.      *    Solve A*X = B.
  1287.      *
  1288.      *    @param Matrix $B Right hand side
  1289.      *    @return Matrix ... Solution if A is square, least squares solution otherwise
  1290.      */
  1291.     public function solve($B{
  1292.         if ($this->m == $this->n{
  1293.             $LU new LUDecomposition($this);
  1294.             return $LU->solve($B);
  1295.         else {
  1296.             $QR new QRDecomposition($this);
  1297.             return $QR->solve($B);
  1298.         }
  1299.     }    //    function solve()
  1300.  
  1301.  
  1302.     /**
  1303.      *    Matrix inverse or pseudoinverse.
  1304.      *
  1305.      *    @return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise.
  1306.      */
  1307.     public function inverse({
  1308.         return $this->solve($this->identity($this->m$this->m));
  1309.     }    //    function inverse()
  1310.  
  1311.  
  1312.     /**
  1313.      *    det
  1314.      *
  1315.      *    Calculate determinant
  1316.      *    @return float Determinant
  1317.      */
  1318.     public function det({
  1319.         $L new LUDecomposition($this);
  1320.         return $L->det();
  1321.     }    //    function det()
  1322.  
  1323.  
  1324.     /**
  1325.      *    Older debugging utility for backwards compatability.
  1326.      *
  1327.      *    @return html version of matrix
  1328.      */
  1329.     public function mprint($A$format="%01.2f"$width=2{
  1330.         $m count($A);
  1331.         $n count($A[0]);
  1332.         $spacing str_repeat('&nbsp;',$width);
  1333.  
  1334.         for ($i 0$i $m++$i{
  1335.             for ($j 0$j $n++$j{
  1336.                 $formatted sprintf($format$A[$i][$j]);
  1337.                 echo $formatted.$spacing;
  1338.             }
  1339.             echo "<br />";
  1340.         }
  1341.     }    //    function mprint()
  1342.  
  1343.  
  1344.     /**
  1345.      *    Debugging utility.
  1346.      *
  1347.      *    @return Output HTML representation of matrix
  1348.      */
  1349.     public function toHTML($width=2{
  1350.         print('<table style="background-color:#eee;">');
  1351.         for($i 0$i $this->m++$i{
  1352.             print('<tr>');
  1353.             for($j 0$j $this->n++$j{
  1354.                 print('<td style="background-color:#fff;border:1px solid #000;padding:2px;text-align:center;vertical-align:middle;">' $this->A[$i][$j'</td>');
  1355.             }
  1356.             print('</tr>');
  1357.         }
  1358.         print('</table>');
  1359.     }    //    function toHTML()
  1360.  
  1361. }    //    class Matrix

Documentation generated on Mon, 10 Aug 2009 08:06:33 +0200 by phpDocumentor 1.4.1