ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
LUDecomposition.php
Go to the documentation of this file.
1 <?php
22 
27  private $LU = array();
28 
33  private $m;
34 
39  private $n;
40 
45  private $pivsign;
46 
51  private $piv = array();
52 
53 
60  public function __construct($A) {
61  if ($A instanceof Matrix) {
62  // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
63  $this->LU = $A->getArrayCopy();
64  $this->m = $A->getRowDimension();
65  $this->n = $A->getColumnDimension();
66  for ($i = 0; $i < $this->m; ++$i) {
67  $this->piv[$i] = $i;
68  }
69  $this->pivsign = 1;
70  $LUrowi = $LUcolj = array();
71 
72  // Outer loop.
73  for ($j = 0; $j < $this->n; ++$j) {
74  // Make a copy of the j-th column to localize references.
75  for ($i = 0; $i < $this->m; ++$i) {
76  $LUcolj[$i] = &$this->LU[$i][$j];
77  }
78  // Apply previous transformations.
79  for ($i = 0; $i < $this->m; ++$i) {
80  $LUrowi = $this->LU[$i];
81  // Most of the time is spent in the following dot product.
82  $kmax = min($i,$j);
83  $s = 0.0;
84  for ($k = 0; $k < $kmax; ++$k) {
85  $s += $LUrowi[$k] * $LUcolj[$k];
86  }
87  $LUrowi[$j] = $LUcolj[$i] -= $s;
88  }
89  // Find pivot and exchange if necessary.
90  $p = $j;
91  for ($i = $j+1; $i < $this->m; ++$i) {
92  if (abs($LUcolj[$i]) > abs($LUcolj[$p])) {
93  $p = $i;
94  }
95  }
96  if ($p != $j) {
97  for ($k = 0; $k < $this->n; ++$k) {
98  $t = $this->LU[$p][$k];
99  $this->LU[$p][$k] = $this->LU[$j][$k];
100  $this->LU[$j][$k] = $t;
101  }
102  $k = $this->piv[$p];
103  $this->piv[$p] = $this->piv[$j];
104  $this->piv[$j] = $k;
105  $this->pivsign = $this->pivsign * -1;
106  }
107  // Compute multipliers.
108  if (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) {
109  for ($i = $j+1; $i < $this->m; ++$i) {
110  $this->LU[$i][$j] /= $this->LU[$j][$j];
111  }
112  }
113  }
114  } else {
116  }
117  } // function __construct()
118 
119 
125  public function getL() {
126  for ($i = 0; $i < $this->m; ++$i) {
127  for ($j = 0; $j < $this->n; ++$j) {
128  if ($i > $j) {
129  $L[$i][$j] = $this->LU[$i][$j];
130  } elseif ($i == $j) {
131  $L[$i][$j] = 1.0;
132  } else {
133  $L[$i][$j] = 0.0;
134  }
135  }
136  }
137  return new Matrix($L);
138  } // function getL()
139 
140 
146  public function getU() {
147  for ($i = 0; $i < $this->n; ++$i) {
148  for ($j = 0; $j < $this->n; ++$j) {
149  if ($i <= $j) {
150  $U[$i][$j] = $this->LU[$i][$j];
151  } else {
152  $U[$i][$j] = 0.0;
153  }
154  }
155  }
156  return new Matrix($U);
157  } // function getU()
158 
159 
165  public function getPivot() {
166  return $this->piv;
167  } // function getPivot()
168 
169 
175  public function getDoublePivot() {
176  return $this->getPivot();
177  } // function getDoublePivot()
178 
179 
185  public function isNonsingular() {
186  for ($j = 0; $j < $this->n; ++$j) {
187  if ($this->LU[$j][$j] == 0) {
188  return false;
189  }
190  }
191  return true;
192  } // function isNonsingular()
193 
194 
200  public function det() {
201  if ($this->m == $this->n) {
202  $d = $this->pivsign;
203  for ($j = 0; $j < $this->n; ++$j) {
204  $d *= $this->LU[$j][$j];
205  }
206  return $d;
207  } else {
209  }
210  } // function det()
211 
212 
221  public function solve($B) {
222  if ($B->getRowDimension() == $this->m) {
223  if ($this->isNonsingular()) {
224  // Copy right hand side with pivoting
225  $nx = $B->getColumnDimension();
226  $X = $B->getMatrix($this->piv, 0, $nx-1);
227  // Solve L*Y = B(piv,:)
228  for ($k = 0; $k < $this->n; ++$k) {
229  for ($i = $k+1; $i < $this->n; ++$i) {
230  for ($j = 0; $j < $nx; ++$j) {
231  $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
232  }
233  }
234  }
235  // Solve U*X = Y;
236  for ($k = $this->n-1; $k >= 0; --$k) {
237  for ($j = 0; $j < $nx; ++$j) {
238  $X->A[$k][$j] /= $this->LU[$k][$k];
239  }
240  for ($i = 0; $i < $k; ++$i) {
241  for ($j = 0; $j < $nx; ++$j) {
242  $X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];
243  }
244  }
245  }
246  return $X;
247  } else {
249  }
250  } else {
251  throw new Exception(JAMAError(MatrixSquareException));
252  }
253  } // function solve()
254 
255 } // class LUDecomposition