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

Source for file LUDecomposition.php

Documentation is available at LUDecomposition.php

  1. <?php
  2. /**
  3.  *    @package JAMA
  4.  *
  5.  *     For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
  6.  *     unit lower triangular matrix L, an n-by-n upper triangular matrix U,
  7.  *     and a permutation vector piv of length m so that A(piv,:) = L*U.
  8.  *     If m < n, then L is m-by-m and U is m-by-n.
  9.  *
  10.  *     The LU decompostion with pivoting always exists, even if the matrix is
  11.  *     singular, so the constructor will never fail. The primary use of the
  12.  *     LU decomposition is in the solution of square systems of simultaneous
  13.  *     linear equations. This will fail if isNonsingular() returns false.
  14.  *
  15.  *    @author Paul Meagher
  16.  *    @author Bartosz Matosiuk
  17.  *    @author Michael Bommarito
  18.  *    @version 1.1
  19.  *    @license PHP v3.0
  20.  */
  21.  
  22.     const MatrixSingularException    "Can only perform operation on singular matrix.";
  23.     const MatrixSquareException        "Mismatched Row dimension";
  24.  
  25.     /**
  26.      *    Decomposition storage
  27.      *    @var array 
  28.      */
  29.     private $LU array();
  30.  
  31.     /**
  32.      *    Row dimension.
  33.      *    @var int 
  34.      */
  35.     private $m;
  36.  
  37.     /**
  38.      *    Column dimension.
  39.      *    @var int 
  40.      */
  41.     private $n;
  42.  
  43.     /**
  44.      *    Pivot sign.
  45.      *    @var int 
  46.      */
  47.     private $pivsign;
  48.  
  49.     /**
  50.      *    Internal storage of pivot vector.
  51.      *    @var array 
  52.      */
  53.     private $piv array();
  54.  
  55.  
  56.     /**
  57.      *    LU Decomposition constructor.
  58.      *
  59.      *    @param $A Rectangular matrix
  60.      *    @return Structure to access L, U and piv.
  61.      */
  62.     public function __construct($A{
  63.         if ($A instanceof PHPExcel_Shared_JAMA_Matrix{
  64.             // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
  65.             $this->LU $A->getArray();
  66.             $this->m  $A->getRowDimension();
  67.             $this->n  $A->getColumnDimension();
  68.             for ($i 0$i $this->m++$i{
  69.                 $this->piv[$i$i;
  70.             }
  71.             $this->pivsign 1;
  72.             $LUrowi $LUcolj array();
  73.  
  74.             // Outer loop.
  75.             for ($j 0$j $this->n++$j{
  76.                 // Make a copy of the j-th column to localize references.
  77.                 for ($i 0$i $this->m++$i{
  78.                     $LUcolj[$i&$this->LU[$i][$j];
  79.                 }
  80.                 // Apply previous transformations.
  81.                 for ($i 0$i $this->m++$i{
  82.                     $LUrowi $this->LU[$i];
  83.                     // Most of the time is spent in the following dot product.
  84.                     $kmax min($i,$j);
  85.                     $s 0.0;
  86.                     for ($k 0$k $kmax++$k{
  87.                         $s += $LUrowi[$k$LUcolj[$k];
  88.                     }
  89.                     $LUrowi[$j$LUcolj[$i-= $s;
  90.                 }
  91.                 // Find pivot and exchange if necessary.
  92.                 $p $j;
  93.                 for ($i $j+1$i $this->m++$i{
  94.                     if (abs($LUcolj[$i]abs($LUcolj[$p])) {
  95.                         $p $i;
  96.                     }
  97.                 }
  98.                 if ($p != $j{
  99.                     for ($k 0$k $this->n++$k{
  100.                         $t $this->LU[$p][$k];
  101.                         $this->LU[$p][$k$this->LU[$j][$k];
  102.                         $this->LU[$j][$k$t;
  103.                     }
  104.                     $k $this->piv[$p];
  105.                     $this->piv[$p$this->piv[$j];
  106.                     $this->piv[$j$k;
  107.                     $this->pivsign $this->pivsign * -1;
  108.                 }
  109.                 // Compute multipliers.
  110.                 if (($j $this->m&& ($this->LU[$j][$j!= 0.0)) {
  111.                     for ($i $j+1$i $this->m++$i{
  112.                         $this->LU[$i][$j/= $this->LU[$j][$j];
  113.                     }
  114.                 }
  115.             }
  116.         else {
  117.             throw new Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException);
  118.         }
  119.     }    //    function __construct()
  120.  
  121.  
  122.     /**
  123.      *    Get lower triangular factor.
  124.      *
  125.      *    @return array Lower triangular factor
  126.      */
  127.     public function getL({
  128.         for ($i 0$i $this->m++$i{
  129.             for ($j 0$j $this->n++$j{
  130.                 if ($i $j{
  131.                     $L[$i][$j$this->LU[$i][$j];
  132.                 elseif ($i == $j{
  133.                     $L[$i][$j1.0;
  134.                 else {
  135.                     $L[$i][$j0.0;
  136.                 }
  137.             }
  138.         }
  139.         return new PHPExcel_Shared_JAMA_Matrix($L);
  140.     }    //    function getL()
  141.  
  142.  
  143.     /**
  144.      *    Get upper triangular factor.
  145.      *
  146.      *    @return array Upper triangular factor
  147.      */
  148.     public function getU({
  149.         for ($i 0$i $this->n++$i{
  150.             for ($j 0$j $this->n++$j{
  151.                 if ($i <= $j{
  152.                     $U[$i][$j$this->LU[$i][$j];
  153.                 else {
  154.                     $U[$i][$j0.0;
  155.                 }
  156.             }
  157.         }
  158.         return new PHPExcel_Shared_JAMA_Matrix($U);
  159.     }    //    function getU()
  160.  
  161.  
  162.     /**
  163.      *    Return pivot permutation vector.
  164.      *
  165.      *    @return array Pivot vector
  166.      */
  167.     public function getPivot({
  168.         return $this->piv;
  169.     }    //    function getPivot()
  170.  
  171.  
  172.     /**
  173.      *    Alias for getPivot
  174.      *
  175.      *    @see getPivot
  176.      */
  177.     public function getDoublePivot({
  178.         return $this->getPivot();
  179.     }    //    function getDoublePivot()
  180.  
  181.  
  182.     /**
  183.      *    Is the matrix nonsingular?
  184.      *
  185.      *    @return true if U, and hence A, is nonsingular.
  186.      */
  187.     public function isNonsingular({
  188.         for ($j 0$j $this->n++$j{
  189.             if ($this->LU[$j][$j== 0{
  190.                 return false;
  191.             }
  192.         }
  193.         return true;
  194.     }    //    function isNonsingular()
  195.  
  196.  
  197.     /**
  198.      *    Count determinants
  199.      *
  200.      *    @return array d matrix deterninat
  201.      */
  202.     public function det({
  203.         if ($this->== $this->n{
  204.             $d $this->pivsign;
  205.             for ($j 0$j $this->n++$j{
  206.                 $d *= $this->LU[$j][$j];
  207.             }
  208.             return $d;
  209.         else {
  210.             throw new Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException);
  211.         }
  212.     }    //    function det()
  213.  
  214.  
  215.     /**
  216.      *    Solve A*X = B
  217.      *
  218.      *    @param  $B  A Matrix with as many rows as A and any number of columns.
  219.      *    @return  so that L*U*X = B(piv,:)
  220.      *    @exception  IllegalArgumentException Matrix row dimensions must agree.
  221.      *    @exception  RuntimeException  Matrix is singular.
  222.      */
  223.     public function solve($B{
  224.         if ($B->getRowDimension(== $this->m{
  225.             if ($this->isNonsingular()) {
  226.                 // Copy right hand side with pivoting
  227.                 $nx $B->getColumnDimension();
  228.                 $X  $B->getMatrix($this->piv0$nx-1);
  229.                 // Solve L*Y = B(piv,:)
  230.                 for ($k 0$k $this->n++$k{
  231.                     for ($i $k+1$i $this->n++$i{
  232.                         for ($j 0$j $nx++$j{
  233.                             $X->A[$i][$j-= $X->A[$k][$j$this->LU[$i][$k];
  234.                         }
  235.                     }
  236.                 }
  237.                 // Solve U*X = Y;
  238.                 for ($k $this->n-1$k >= 0--$k{
  239.                     for ($j 0$j $nx++$j{
  240.                         $X->A[$k][$j/= $this->LU[$k][$k];
  241.                     }
  242.                     for ($i 0$i $k++$i{
  243.                         for ($j 0$j $nx++$j{
  244.                             $X->A[$i][$j-= $X->A[$k][$j$this->LU[$i][$k];
  245.                         }
  246.                     }
  247.                 }
  248.                 return $X;
  249.             else {
  250.                 throw new Exception(self::MatrixSingularException);
  251.             }
  252.         else {
  253.             throw new Exception(self::MatrixSquareException);
  254.         }
  255.     }    //    function solve()
  256.  
  257. }    //    class PHPExcel_Shared_JAMA_LUDecomposition

Documentation generated on Sun, 27 Feb 2011 16:32:34 -0800 by phpDocumentor 1.4.3