64 $A = $Arg->getArrayCopy();
65 $this->m = $Arg->getRowDimension();
66 $this->
n = $Arg->getColumnDimension();
67 $nu = min($this->m, $this->
n);
72 $nct = min($this->m - 1, $this->
n);
73 $nrt = max(0, min($this->
n - 2, $this->m));
77 for ($k = 0; $k < max($nct,$nrt); ++$k) {
85 $this->s[$k] =
hypo($this->s[$k], $A[$i][$k]);
87 if ($this->s[$k] != 0.0) {
88 if ($A[$k][$k] < 0.0) {
89 $this->s[$k] = -$this->s[$k];
92 $A[$i][$k] /= $this->s[$k];
96 $this->s[$k] = -$this->s[$k];
99 for ($j = $k + 1; $j <
$this->n; ++$j) {
100 if (($k < $nct) & ($this->s[$k] != 0.0)) {
103 for ($i = $k; $i <
$this->m; ++$i) {
104 $t += $A[$i][$k] * $A[$i][$j];
106 $t = -
$t / $A[$k][$k];
107 for ($i = $k; $i <
$this->m; ++$i) {
108 $A[$i][$j] +=
$t * $A[$i][$k];
116 if ($wantu AND ($k < $nct)) {
119 for ($i = $k; $i <
$this->m; ++$i) {
120 $this->U[$i][$k] = $A[$i][$k];
129 for ($i = $k + 1; $i <
$this->n; ++$i) {
130 $e[$k] =
hypo($e[$k], $e[$i]);
133 if ($e[$k+1] < 0.0) {
136 for ($i = $k + 1; $i <
$this->n; ++$i) {
142 if (($k+1 < $this->m) AND ($e[$k] != 0.0)) {
144 for ($i = $k+1; $i <
$this->m; ++$i) {
147 for ($j = $k+1; $j <
$this->n; ++$j) {
148 for ($i = $k+1; $i <
$this->m; ++$i) {
149 $work[$i] += $e[$j] * $A[$i][$j];
152 for ($j = $k + 1; $j <
$this->n; ++$j) {
153 $t = -$e[$j] / $e[$k+1];
154 for ($i = $k + 1; $i <
$this->m; ++$i) {
155 $A[$i][$j] +=
$t * $work[$i];
162 for ($i = $k + 1; $i <
$this->n; ++$i) {
163 $this->V[$i][$k] = $e[$i];
170 $p = min($this->
n, $this->m + 1);
171 if ($nct < $this->
n) {
172 $this->s[$nct] = $A[$nct][$nct];
175 $this->s[$p-1] = 0.0;
178 $e[$nrt] = $A[$nrt][$p-1];
183 for ($j = $nct; $j < $nu; ++$j) {
185 $this->U[$i][$j] = 0.0;
187 $this->U[$j][$j] = 1.0;
189 for ($k = $nct - 1; $k >= 0; --$k) {
190 if ($this->s[$k] != 0.0) {
191 for ($j = $k + 1; $j < $nu; ++$j) {
193 for ($i = $k; $i <
$this->m; ++$i) {
194 $t += $this->U[$i][$k] * $this->U[$i][$j];
196 $t = -
$t / $this->U[$k][$k];
197 for ($i = $k; $i <
$this->m; ++$i) {
198 $this->U[$i][$j] +=
$t * $this->U[$i][$k];
201 for ($i = $k; $i <
$this->m; ++$i ) {
202 $this->U[$i][$k] = -$this->U[$i][$k];
204 $this->U[$k][$k] = 1.0 + $this->U[$k][$k];
205 for ($i = 0; $i < $k - 1; ++$i) {
206 $this->U[$i][$k] = 0.0;
210 $this->U[$i][$k] = 0.0;
212 $this->U[$k][$k] = 1.0;
219 for ($k = $this->n - 1; $k >= 0; --$k) {
220 if (($k < $nrt) AND ($e[$k] != 0.0)) {
221 for ($j = $k + 1; $j < $nu; ++$j) {
223 for ($i = $k + 1; $i <
$this->n; ++$i) {
224 $t += $this->V[$i][$k]* $this->V[$i][$j];
226 $t = -
$t / $this->V[$k+1][$k];
227 for ($i = $k + 1; $i <
$this->n; ++$i) {
228 $this->V[$i][$j] +=
$t * $this->V[$i][$k];
233 $this->V[$i][$k] = 0.0;
235 $this->V[$k][$k] = 1.0;
242 $eps = pow(2.0, -52.0);
254 for ($k = $p - 2; $k >= -1; --$k) {
258 if (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) {
266 for ($ks = $p - 1; $ks >= $k; --$ks) {
270 $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.);
271 if (abs($this->s[$ks]) <= $eps *
$t) {
278 }
else if ($ks == $p-1) {
293 for ($j = $p - 2; $j >= $k; --$j) {
295 $cs = $this->s[$j] /
$t;
299 $f = -$sn * $e[$j-1];
300 $e[$j-1] = $cs * $e[$j-1];
304 $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1];
305 $this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1];
306 $this->V[$i][$j] =
$t;
315 for ($j = $k; $j < $p; ++$j) {
317 $cs = $this->s[$j] /
$t;
321 $e[$j] = $cs * $e[$j];
324 $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1];
325 $this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1];
326 $this->U[$i][$j] =
$t;
334 $scale = max(max(max(max(
335 abs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])),
336 abs($this->s[$k])), abs($e[$k]));
337 $sp = $this->s[$p-1] / $scale;
338 $spm1 = $this->s[$p-2] / $scale;
339 $epm1 = $e[$p-2] / $scale;
340 $sk = $this->s[$k] / $scale;
341 $ek = $e[$k] / $scale;
342 $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;
343 $c = ($sp * $epm1) * ($sp * $epm1);
345 if (($b != 0.0) || ($c != 0.0)) {
346 $shift = sqrt($b * $b + $c);
350 $shift = $c / ($b + $shift);
352 $f = ($sk + $sp) * ($sk - $sp) + $shift;
355 for ($j = $k; $j < $p-1; ++$j) {
362 $f = $cs * $this->s[$j] + $sn * $e[$j];
363 $e[$j] = $cs * $e[$j] - $sn * $this->s[$j];
364 $g = $sn * $this->s[$j+1];
365 $this->s[$j+1] = $cs * $this->s[$j+1];
368 $t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1];
369 $this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1];
370 $this->V[$i][$j] =
$t;
377 $f = $cs * $e[$j] + $sn * $this->s[$j+1];
378 $this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1];
380 $e[$j+1] = $cs * $e[$j+1];
381 if ($wantu && ($j < $this->m - 1)) {
383 $t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1];
384 $this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1];
385 $this->U[$i][$j] =
$t;
395 if ($this->s[$k] <= 0.0) {
396 $this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0);
398 for ($i = 0; $i <= $pp; ++$i) {
399 $this->V[$i][$k] = -$this->V[$i][$k];
405 if ($this->s[$k] >= $this->s[$k+1]) {
409 $this->s[$k] = $this->s[$k+1];
411 if ($wantv AND ($k < $this->n - 1)) {
413 $t = $this->V[$i][$k+1];
414 $this->V[$i][$k+1] = $this->V[$i][$k];
415 $this->V[$i][$k] =
$t;
418 if ($wantu AND ($k < $this->m-1)) {
420 $t = $this->U[$i][$k+1];
421 $this->U[$i][$k+1] = $this->U[$i][$k];
422 $this->U[$i][$k] =
$t;
443 return new Matrix($this->U, $this->m, min($this->m + 1, $this->
n));
454 return new Matrix($this->V);
480 $S[$i][$i] = $this->s[$i];
482 return new Matrix($S);
504 return $this->s[0] / $this->s[min($this->m, $this->
n) - 1];
515 $eps = pow(2.0, -52.0);
516 $tol = max($this->m, $this->
n) * $this->s[0] * $eps;
518 for ($i = 0; $i < count($this->s); ++$i) {
519 if ($this->s[$i] > $tol) {