//void decompose(); private void decompose() { bool flag; int i, its, j, jj, k, nm = int.MinValue; int l = int.MinValue; double anorm, c, f, g, h, s, scale, x, y, z; VecDoub rv1 = new VecDoub(n); g = scale = anorm = 0.0; for (i = 0; i < n; i++) { l = i + 2; rv1[i] = scale * g; g = s = scale = 0.0; if (i < m) { for (k = i; k < m; k++) { scale += Math.Abs(u[k][i]); } if (scale != 0.0) { for (k = i; k < m; k++) { u[k][i] /= scale; s += u[k][i] * u[k][i]; } f = u[i][i]; g = -NR.SIGN(Math.Sqrt(s), f); h = f * g - s; u[i][i] = f - g; for (j = l - 1; j < n; j++) { for (s = 0.0, k = i; k < m; k++) { s += u[k][i] * u[k][j]; } f = s / h; for (k = i; k < m; k++) { u[k][j] += f * u[k][i]; } } for (k = i; k < m; k++) { u[k][i] *= scale; } } } w[i] = scale * g; g = s = scale = 0.0; if (i + 1 <= m && i + 1 != n) { for (k = l - 1; k < n; k++) { scale += Math.Abs(u[i][k]); } if (scale != 0.0) { for (k = l - 1; k < n; k++) { u[i][k] /= scale; s += u[i][k] * u[i][k]; } f = u[i][l - 1]; g = -NR.SIGN(Math.Sqrt(s), f); h = f * g - s; u[i][l - 1] = f - g; for (k = l - 1; k < n; k++) { rv1[k] = u[i][k] / h; } for (j = l - 1; j < m; j++) { for (s = 0.0, k = l - 1; k < n; k++) { s += u[j][k] * u[i][k]; } for (k = l - 1; k < n; k++) { u[j][k] += s * rv1[k]; } } for (k = l - 1; k < n; k++) { u[i][k] *= scale; } } } anorm = Math.Max(anorm, (Math.Abs(w[i]) + Math.Abs(rv1[i]))); } for (i = n - 1; i >= 0; i--) { if (i < n - 1) { if (g != 0.0) { for (j = l; j < n; j++) { v[j][i] = (u[i][j] / u[i][l]) / g; } for (j = l; j < n; j++) { for (s = 0.0, k = l; k < n; k++) { s += u[i][k] * v[k][j]; } for (k = l; k < n; k++) { v[k][j] += s * v[k][i]; } } } for (j = l; j < n; j++) { v[i][j] = v[j][i] = 0.0; } } v[i][i] = 1.0; g = rv1[i]; l = i; } for (i = Math.Min(m, n) - 1; i >= 0; i--) { l = i + 1; g = w[i]; for (j = l; j < n; j++) { u[i][j] = 0.0; } if (g != 0.0) { g = 1.0 / g; for (j = l; j < n; j++) { for (s = 0.0, k = l; k < m; k++) { s += u[k][i] * u[k][j]; } f = (s / u[i][i]) * g; for (k = i; k < m; k++) { u[k][j] += f * u[k][i]; } } for (j = i; j < m; j++) { u[j][i] *= g; } } else { for (j = i; j < m; j++) { u[j][i] = 0.0; } } ++u[i][i]; } for (k = n - 1; k >= 0; k--) { for (its = 0; its < 30; its++) { flag = true; for (l = k; l >= 0; l--) { nm = l - 1; if (l == 0 || Math.Abs(rv1[l]) <= eps * anorm) { flag = false; break; } if (Math.Abs(w[nm]) <= eps * anorm) { break; } } if (flag) { c = 0.0; s = 1.0; for (i = l; i < k + 1; i++) { f = s * rv1[i]; rv1[i] = c * rv1[i]; if (Math.Abs(f) <= eps * anorm) { break; } g = w[i]; h = pythag(f, g); w[i] = h; h = 1.0 / h; c = g * h; s = -f * h; for (j = 0; j < m; j++) { y = u[j][nm]; z = u[j][i]; u[j][nm] = y * c + z * s; u[j][i] = z * c - y * s; } } } z = w[k]; if (l == k) { if (z < 0.0) { w[k] = -z; for (j = 0; j < n; j++) { v[j][k] = -v[j][k]; } } break; } if (its == 29) { throw new Exception("no convergence in 30 svdcmp iterations"); } x = w[l]; nm = k - 1; y = w[nm]; g = rv1[nm]; h = rv1[k]; f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0 * h * y); g = pythag(f, 1.0); f = ((x - z) * (x + z) + h * ((y / (f + NR.SIGN(g, f))) - h)) / x; c = s = 1.0; for (j = l; j <= nm; j++) { i = j + 1; g = rv1[i]; y = w[i]; h = s * g; g = c * g; z = pythag(f, h); rv1[j] = z; c = f / z; s = h / z; f = x * c + g * s; g = g * c - x * s; h = y * s; y *= c; for (jj = 0; jj < n; jj++) { x = v[jj][j]; z = v[jj][i]; v[jj][j] = x * c + z * s; v[jj][i] = z * c - x * s; } z = pythag(f, h); w[j] = z; if (z != 0.0) { z = 1.0 / z; c = f * z; s = h * z; } f = c * g + s * y; x = c * y - s * g; for (jj = 0; jj < m; jj++) { y = u[jj][j]; z = u[jj][i]; u[jj][j] = y * c + z * s; u[jj][i] = z * c - y * s; } } rv1[l] = 0.0; rv1[k] = f; w[k] = x; } } }
private bool sing; // Indicates whether A is singular. public QRdcmp(MatDoub a) { n = a.nrows(); MatDoub qt = new MatDoub(n, n); MatDoub r = new MatDoub(a); sing = (false); int i, j, k; VecDoub c = new VecDoub(n); VecDoub d = new VecDoub(n); double scale, sigma, sum, tau; for (k = 0; k < n - 1; k++) { scale = 0.0; for (i = k; i < n; i++) { scale = Math.Max(scale, Math.Abs(r[i][k])); } if (scale == 0.0) { // Singular case. sing = true; c[k] = d[k] = 0.0; } else { // Form Qk and Qk A. for (i = k; i < n; i++) { r[i][k] /= scale; } for (sum = 0.0, i = k; i < n; i++) { sum += r[i][k] * r[i][k]; } sigma = NR.SIGN(Math.Sqrt(sum), r[k][k]); r[k][k] += sigma; c[k] = sigma * r[k][k]; d[k] = -scale * sigma; for (j = k + 1; j < n; j++) { for (sum = 0.0, i = k; i < n; i++) { sum += r[i][k] * r[i][j]; } tau = sum / c[k]; for (i = k; i < n; i++) { r[i][j] -= tau * r[i][k]; } } } } d[n - 1] = r[n - 1][n - 1]; if (d[n - 1] == 0.0) { sing = true; } /////////////////////////// for (i = 0; i < n; i++) { // Form QT explicitly. for (j = 0; j < n; j++) { qt[i][j] = 0.0; } qt[i][i] = 1.0; } for (k = 0; k < n - 1; k++) { if (c[k] != 0.0) { for (j = 0; j < n; j++) { sum = 0.0; for (i = k; i < n; i++) { sum += r[i][k] * qt[i][j]; } sum /= c[k]; for (i = k; i < n; i++) { qt[i][j] -= sum * r[i][k]; } } } } for (i = 0; i < n; i++) { // Form R explicitly. r[i][i] = d[i]; for (j = 0; j < i; j++) { r[i][j] = 0.0; } } }