68 $A = $Arg->getArray();
69 $this->m = $Arg->getRowDimension();
70 $this->
n = $Arg->getColumnDimension();
71 $nu = min($this->m, $this->
n);
76 $nct = min($this->m - 1, $this->
n);
77 $nrt = max(0, min($this->
n - 2, $this->m));
81 $kMax = max($nct, $nrt);
82 for ($k = 0; $k < $kMax; ++$k) {
89 $this->
s[$k] =
hypo($this->
s[$k], $A[
$i][$k]);
91 if ($this->
s[$k] != 0.0) {
92 if ($A[$k][$k] < 0.0) {
93 $this->
s[$k] = -$this->
s[$k];
96 $A[
$i][$k] /= $this->
s[$k];
100 $this->
s[$k] = -$this->
s[$k];
103 for ($j = $k + 1; $j <
$this->n; ++$j) {
104 if (($k < $nct) & ($this->
s[$k] != 0.0)) {
108 $t += $A[
$i][$k] * $A[
$i][$j];
110 $t = -
$t / $A[$k][$k];
112 $A[
$i][$j] +=
$t * $A[
$i][$k];
120 if ($wantu && ($k < $nct)) {
124 $this->U[
$i][$k] = $A[
$i][$k];
134 $e[$k] =
hypo($e[$k], $e[
$i]);
137 if ($e[$k + 1] < 0.0) {
146 if (($k + 1 < $this->m) && ($e[$k] != 0.0)) {
151 for ($j = $k + 1; $j <
$this->n; ++$j) {
153 $work[
$i] += $e[$j] * $A[
$i][$j];
156 for ($j = $k + 1; $j <
$this->n; ++$j) {
157 $t = -$e[$j] / $e[$k + 1];
159 $A[
$i][$j] +=
$t * $work[
$i];
167 $this->V[
$i][$k] = $e[
$i];
174 $p = min($this->
n, $this->m + 1);
175 if ($nct < $this->
n) {
176 $this->
s[$nct] = $A[$nct][$nct];
179 $this->
s[$p - 1] = 0.0;
182 $e[$nrt] = $A[$nrt][$p - 1];
187 for ($j = $nct; $j < $nu; ++$j) {
189 $this->U[
$i][$j] = 0.0;
191 $this->U[$j][$j] = 1.0;
193 for ($k = $nct - 1; $k >= 0; --$k) {
194 if ($this->
s[$k] != 0.0) {
195 for ($j = $k + 1; $j < $nu; ++$j) {
198 $t += $this->U[
$i][$k] * $this->U[
$i][$j];
200 $t = -
$t / $this->U[$k][$k];
202 $this->U[
$i][$j] +=
$t * $this->U[
$i][$k];
206 $this->U[
$i][$k] = -$this->U[
$i][$k];
208 $this->U[$k][$k] = 1.0 + $this->U[$k][$k];
209 for (
$i = 0;
$i < $k - 1; ++
$i) {
210 $this->U[
$i][$k] = 0.0;
214 $this->U[
$i][$k] = 0.0;
216 $this->U[$k][$k] = 1.0;
223 for ($k = $this->n - 1; $k >= 0; --$k) {
224 if (($k < $nrt) && ($e[$k] != 0.0)) {
225 for ($j = $k + 1; $j < $nu; ++$j) {
228 $t += $this->V[
$i][$k] * $this->V[
$i][$j];
230 $t = -
$t / $this->V[$k + 1][$k];
232 $this->V[
$i][$j] +=
$t * $this->V[
$i][$k];
237 $this->V[
$i][$k] = 0.0;
239 $this->V[$k][$k] = 1.0;
246 $eps = 2.0 ** (-52.0);
258 for ($k = $p - 2; $k >= -1; --$k) {
262 if (abs($e[$k]) <=
$eps * (abs($this->
s[$k]) + abs($this->
s[$k + 1]))) {
271 for ($ks = $p - 1; $ks >= $k; --$ks) {
275 $t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks - 1]) : 0.);
276 if (abs($this->
s[$ks]) <=
$eps *
$t) {
284 } elseif ($ks == $p - 1) {
299 for ($j = $p - 2; $j >= $k; --$j) {
301 $cs = $this->
s[$j] /
$t;
305 $f = -$sn * $e[$j - 1];
306 $e[$j - 1] = $cs * $e[$j - 1];
310 $t = $cs * $this->V[
$i][$j] + $sn * $this->V[
$i][$p - 1];
311 $this->V[
$i][$p - 1] = -$sn * $this->V[
$i][$j] + $cs * $this->V[
$i][$p - 1];
312 $this->V[
$i][$j] =
$t;
322 for ($j = $k; $j < $p; ++$j) {
324 $cs = $this->
s[$j] /
$t;
328 $e[$j] = $cs * $e[$j];
331 $t = $cs * $this->U[
$i][$j] + $sn * $this->U[
$i][$k - 1];
332 $this->U[
$i][$k - 1] = -$sn * $this->U[
$i][$j] + $cs * $this->U[
$i][$k - 1];
333 $this->U[
$i][$j] =
$t;
342 $scale = max(max(max(max(abs($this->
s[$p - 1]), abs($this->
s[$p - 2])), abs($e[$p - 2])), abs($this->
s[$k])), abs($e[$k]));
343 $sp = $this->
s[$p - 1] / $scale;
344 $spm1 = $this->
s[$p - 2] / $scale;
345 $epm1 = $e[$p - 2] / $scale;
346 $sk = $this->
s[$k] / $scale;
347 $ek = $e[$k] / $scale;
348 $b = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;
349 $c = ($sp * $epm1) * ($sp * $epm1);
351 if (($b != 0.0) || (
$c != 0.0)) {
352 $shift = sqrt($b * $b +
$c);
356 $shift =
$c / ($b + $shift);
358 $f = ($sk + $sp) * ($sk - $sp) + $shift;
361 for ($j = $k; $j < $p - 1; ++$j) {
368 $f = $cs * $this->
s[$j] + $sn * $e[$j];
369 $e[$j] = $cs * $e[$j] - $sn * $this->
s[$j];
370 $g = $sn * $this->s[$j + 1];
371 $this->s[$j + 1] = $cs * $this->s[$j + 1];
374 $t = $cs * $this->V[
$i][$j] + $sn * $this->V[
$i][$j + 1];
375 $this->V[
$i][$j + 1] = -$sn * $this->V[
$i][$j] + $cs * $this->V[
$i][$j + 1];
376 $this->V[
$i][$j] =
$t;
383 $f = $cs * $e[$j] + $sn * $this->s[$j + 1];
384 $this->s[$j + 1] = -$sn * $e[$j] + $cs * $this->s[$j + 1];
385 $g = $sn * $e[$j + 1];
386 $e[$j + 1] = $cs * $e[$j + 1];
387 if ($wantu && ($j < $this->m - 1)) {
389 $t = $cs * $this->U[
$i][$j] + $sn * $this->U[
$i][$j + 1];
390 $this->U[
$i][$j + 1] = -$sn * $this->U[
$i][$j] + $cs * $this->U[
$i][$j + 1];
391 $this->U[
$i][$j] =
$t;
402 if ($this->
s[$k] <= 0.0) {
403 $this->
s[$k] = ($this->
s[$k] < 0.0 ? -$this->
s[$k] : 0.0);
405 for (
$i = 0;
$i <= $pp; ++
$i) {
406 $this->V[
$i][$k] = -$this->V[
$i][$k];
412 if ($this->
s[$k] >= $this->
s[$k + 1]) {
416 $this->
s[$k] = $this->
s[$k + 1];
417 $this->
s[$k + 1] =
$t;
418 if ($wantv && ($k < $this->n - 1)) {
420 $t = $this->V[
$i][$k + 1];
421 $this->V[
$i][$k + 1] = $this->V[
$i][$k];
422 $this->V[
$i][$k] =
$t;
425 if ($wantu && ($k < $this->m - 1)) {
427 $t = $this->U[
$i][$k + 1];
428 $this->U[
$i][$k + 1] = $this->U[
$i][$k];
429 $this->U[
$i][$k] =
$t;
449 return new Matrix($this->U, $this->m, min($this->m + 1, $this->
n));
459 return new Matrix($this->V);
507 return $this->
s[0] / $this->
s[min($this->m, $this->
n) - 1];
517 $eps = 2.0 ** (-52.0);
518 $tol = max($this->m, $this->
n) * $this->
s[0] *
$eps;
520 $iMax = count($this->
s);
521 for (
$i = 0;
$i < $iMax; ++
$i) {
522 if ($this->
s[
$i] > $tol) {
cond()
Two norm condition number.
__construct($Arg)
Construct the singular value decomposition.
For an m-by-n matrix A with m >= n, the singular value decomposition is an m-by-n orthogonal matrix U...
if(! $in) print Initializing normalization quick check tables n
getU()
Return the left singular vectors.
rank()
Effective numerical matrix rank.
hypo($a, $b)
Pythagorean Theorem:.
getV()
Return the right singular vectors.
getS()
Return the diagonal matrix of singular values.
Class for the creating "special" Matrices.
getSingularValues()
Return the one-dimensional array of singular values.