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. class LUDecomposition {
  22.   /**
  23.   * Decomposition storage
  24.   * @var array 
  25.   */
  26.   var $LU = array();
  27.   
  28.   /**
  29.   * Row dimension.
  30.   * @var int 
  31.   */
  32.   var $m;
  33.  
  34.   /**
  35.   * Column dimension.
  36.   * @var int 
  37.   */   
  38.   var $n;
  39.   
  40.   /**
  41.   * Pivot sign.
  42.   * @var int 
  43.   */      
  44.   var $pivsign;
  45.  
  46.   /**
  47.   * Internal storage of pivot vector.
  48.   * @var array 
  49.   */
  50.   var $piv = array();
  51.   
  52.   /**
  53.   * LU Decomposition constructor.
  54.   * @param $A Rectangular matrix
  55.   * @return Structure to access L, U and piv.
  56.   */
  57.   function LUDecomposition ($A{   
  58.     ifis_a($A'Matrix') ) {
  59.     // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
  60.     $this->LU = $A->getArrayCopy();
  61.     $this->m  = $A->getRowDimension();
  62.     $this->n  = $A->getColumnDimension();
  63.     for ($i 0$i $this->m$i++)
  64.       $this->piv[$i$i;
  65.     $this->pivsign = 1;   
  66.     $LUrowi array();
  67.     $LUcolj array();
  68.     // Outer loop.
  69.     for ($j 0$j $this->n$j++{
  70.       // Make a copy of the j-th column to localize references.
  71.       for ($i 0$i $this->m$i++)
  72.         $LUcolj[$i&$this->LU[$i][$j];
  73.       // Apply previous transformations.
  74.       for ($i 0$i $this->m$i++{        
  75.         $LUrowi $this->LU[$i];        
  76.         // Most of the time is spent in the following dot product.
  77.         $kmax min($i,$j);
  78.         $s 0.0;
  79.         for ($k 0$k $kmax$k++)
  80.           $s += $LUrowi[$k]*$LUcolj[$k];
  81.           $LUrowi[$j$LUcolj[$i-= $s;                                                  
  82.       }       
  83.       // Find pivot and exchange if necessary.
  84.       $p $j;
  85.       for ($i $j+1$i $this->m$i++{
  86.       if (abs($LUcolj[$i]abs($LUcolj[$p]))
  87.         $p $i;
  88.       }
  89.       if ($p != $j{
  90.       for ($k 0$k $this->n$k++{                
  91.         $t $this->LU[$p][$k];                              
  92.         $this->LU[$p][$k$this->LU[$j][$k];                              
  93.         $this->LU[$j][$k$t;                              
  94.       }
  95.       $k $this->piv[$p];
  96.       $this->piv[$p$this->piv[$j];
  97.       $this->piv[$j$k;
  98.       $this->pivsign = $this->pivsign * -1;
  99.       }
  100.       // Compute multipliers.     
  101.       if ( ($j $this->mAND ($this->LU[$j][$j!= 0.0) ) {
  102.       for ($i $j+1$i $this->m$i++)
  103.         $this->LU[$i][$j/= $this->LU[$j][$j];               
  104.       }      
  105.     }
  106.     else {
  107.     }
  108.   }
  109.   
  110.   /**
  111.   * Get lower triangular factor.
  112.   * @return array Lower triangular factor
  113.   */
  114.   function getL ({
  115.     for ($i 0$i $this->m$i++{
  116.       for ($j 0$j $this->n$j++{
  117.         if ($i $j)
  118.           $L[$i][$j$this->LU[$i][$j];
  119.         else if($i == $j)
  120.           $L[$i][$j1.0;
  121.         else
  122.           $L[$i][$j0.0;
  123.       }
  124.     }
  125.     return new Matrix($L);
  126.   }
  127.  
  128.   /**
  129.   * Get upper triangular factor.
  130.   * @return array Upper triangular factor
  131.   */  
  132.   function getU ({
  133.     for ($i 0$i $this->n$i++{
  134.       for ($j 0$j $this->n$j++{
  135.         if ($i <= $j)
  136.           $U[$i][$j$this->LU[$i][$j];
  137.         else
  138.           $U[$i][$j0.0;
  139.       }
  140.     }
  141.     return new Matrix($U);
  142.   }
  143.   
  144.   /**
  145.   * Return pivot permutation vector.
  146.   * @return array Pivot vector
  147.   */
  148.   function getPivot ({
  149.      return $this->piv;
  150.   }
  151.   
  152.   /**
  153.   * Alias for getPivot
  154.   * @see getPivot
  155.   */
  156.   function getDoublePivot ({
  157.      return $this->getPivot();
  158.   }
  159.  
  160.   /**
  161.   * Is the matrix nonsingular?
  162.   * @return true if U, and hence A, is nonsingular.
  163.   */
  164.   function isNonsingular ({
  165.     for ($j 0$j $this->n$j++{
  166.       if ($this->LU[$j][$j== 0)
  167.         return false;
  168.     }
  169.     return true;
  170.   }
  171.  
  172.   /**
  173.   * Count determinants
  174.   * @return array d matrix deterninat
  175.   */
  176.   function det({
  177.     if ($this->m == $this->n{
  178.       $d $this->pivsign;      
  179.       for ($j 0$j $this->n$j++)
  180.         $d *= $this->LU[$j][$j];            
  181.       return $d;
  182.     else {
  183.     }
  184.   }
  185.   
  186.   /**
  187.   * Solve A*X = B
  188.   * @param  $B  A Matrix with as many rows as A and any number of columns.
  189.   * @return  so that L*U*X = B(piv,:)
  190.   * @exception  IllegalArgumentException Matrix row dimensions must agree.
  191.   * @exception  RuntimeException  Matrix is singular.
  192.   */
  193.   function solve($B{          
  194.     if ($B->getRowDimension(== $this->m{
  195.       if ($this->isNonsingular()) {        
  196.         // Copy right hand side with pivoting
  197.         $nx $B->getColumnDimension();
  198.         $X  $B->getMatrix($this->piv0$nx-1);
  199.         // Solve L*Y = B(piv,:)
  200.         for ($k 0$k $this->n$k++)
  201.           for ($i $k+1$i $this->n$i++)
  202.             for ($j 0$j $nx$j++)
  203.               $X->A[$i][$j-= $X->A[$k][$j$this->LU[$i][$k];
  204.         // Solve U*X = Y;
  205.         for ($k $this->n-1$k >= 0$k--{
  206.           for ($j 0$j $nx$j++)
  207.             $X->A[$k][$j/= $this->LU[$k][$k];
  208.           for ($i 0$i $k$i++)
  209.             for ($j 0$j $nx$j++)
  210.               $X->A[$i][$j-= $X->A[$k][$j$this->LU[$i][$k];
  211.         }
  212.         return $X;
  213.       else {
  214.       }
  215.     else {
  216.       trigger_error(MatrixSquareExceptionERROR);
  217.     }
  218.   }   
  219. }

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