/// <summary> /// Creates a new householder decomposition. /// </summary> /// <param name="A">The matrix to decompose.</param> public HouseholderDecomposition(MatrixValue A) : base(A) { QR = A.GetComplexMatrix(); Rdiag = new ScalarValue[n]; // Main loop. for (int k = 0; k < n; k++) { var nrm = 0.0; for (int i = k; i < m; i++) nrm = Helpers.Hypot(nrm, QR[i][k].Re); if (nrm != 0.0) { // Form k-th Householder vector. if (QR[k][k].Re < 0) nrm = -nrm; for (int i = k; i < m; i++) QR[i][k] /= nrm; QR[k][k] += ScalarValue.One; // Apply transformation to remaining columns. for (int j = k + 1; j < n; j++) { var s = ScalarValue.Zero; for (int i = k; i < m; i++) s += QR[i][k] * QR[i][j]; s = (-s) / QR[k][k]; for (int i = k; i < m; i++) QR[i][j] += s * QR[i][k]; } } else FullRank = false; Rdiag[k] = new ScalarValue(-nrm); } }
/// <summary> /// Cholesky algorithm for symmetric and positive definite matrix. /// </summary> /// <param name="Arg">Square, symmetric matrix.</param> /// <returns>Structure to access L and isspd flag.</returns> public CholeskyDecomposition(MatrixValue Arg) { // Initialize. var A = Arg.GetComplexMatrix(); n = Arg.DimensionY; L = new ScalarValue[n][]; for (int i = 0; i < n; i++) L[i] = new ScalarValue[n]; isspd = Arg.DimensionX == n; // Main loop. for (int i = 0; i < n; i++) { var Lrowi = L[i]; var d = ScalarValue.Zero; for (int j = 0; j < i; j++) { var Lrowj = L[j]; var s = new ScalarValue(); for (int k = 0; k < j; k++) s += Lrowi[k] * Lrowj[k].Conjugate(); s = (A[i][j] - s) / L[j][j]; Lrowi[j] = s; d += s * s.Conjugate(); isspd = isspd && (A[j][i] == A[i][j]); } d = A[i][i] - d; isspd = isspd & (d.Abs() > 0.0); L[i][i] = d.Sqrt(); for (int k = i + 1; k < n; k++) L[i][k] = ScalarValue.Zero; } }
/// <summary> /// LU Decomposition /// </summary> /// <param name="A">Rectangular matrix</param> /// <returns>Structure to access L, U and piv.</returns> public LUDecomposition(MatrixValue A) { // Use a "left-looking", dot-product, Crout / Doolittle algorithm. LU = A.GetComplexMatrix(); m = A.DimensionY; n = A.DimensionX; piv = new int[m]; for (int i = 0; i < m; i++) piv[i] = i; pivsign = 1; var LUrowi = new ScalarValue[0]; var LUcolj = new ScalarValue[m]; // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; i++) LUcolj[i] = LU[i][j]; // Apply previous transformations. for (int i = 0; i < m; i++) { LUrowi = LU[i]; // Most of the time is spent in the following dot product. var kmax = Math.Min(i, j); var s = ScalarValue.Zero; for (int k = 0; k < kmax; k++) s += LUrowi[k] * LUcolj[k]; LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. var p = j; for (int i = j + 1; i < m; i++) { if (LUcolj[i].Abs() > LUcolj[p].Abs()) p = i; } if (p != j) { for (int k = 0; k < n; k++) { var t = LU[p][k]; LU[p][k] = LU[j][k]; LU[j][k] = t; } var k2 = piv[p]; piv[p] = piv[j]; piv[j] = k2; pivsign = -pivsign; } // Compute multipliers. if (j < m & LU[j][j] != 0.0) { for (int i = j + 1; i < m; i++) LU[i][j] = LU[i][j] / LU[j][j]; } } }