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

Documentation generated on Mon, 05 Jan 2009 20:38:05 +0100 by phpDocumentor 1.4.1