///<Sumary>Least squares solution of A*X = B</Sumary> ///<param name="B">A Matrix with as many rows as A and any number of columns.</param> ///<returns> X that minimizes the two norm of Q*R*X-B.</returns> public Matrix3d Solve(Matrix3d B) { if (B.RowLength() != m) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!IsFullRank()) { throw new Exception("Matrix is rank deficient."); } // Copy right hand side int nx = B.ColumnLength(); double[,] X = B.ToArray(); // Compute Y = transpose(Q)*B for (int k = 0; k < n; k++) { for (int j = 0; j < nx; j++) { double s = 0.0f; for (int i = k; i < m; i++) { s += QR[i, k] * X[i, j]; } s = -s / QR[k, k]; for (int i = k; i < m; i++) { X[i, j] += s * QR[i, k]; } } } // Solve R*X = Y; for (int k = n - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X[k, j] /= Rdiag[k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X[i, j] -= X[k, j] * QR[i, k]; } } } Matrix3d mat = new Matrix3d(); mat = mat.FromDoubleArray(X); return(mat.GetMatrix(0, n - 1, 0, nx - 1)); }
/** Solve A*X = B * @param B A Matrix with as many rows as A and any number of columns. * @return X so that L*U*X = B(piv,:) * @exception System.ArgumentException Matrix row dimensions must agree. * @exception System.Exception Matrix is singular. */ public Matrix3d solve(Matrix3d B) { if (B.RowLength() != m) { throw new ArgumentException("Matrix row dimensions must agree."); } if (!this.IsNonsingular()) { throw new Exception("Matrix is singular."); } // Copy right hand side with pivoting int nx = B.ColumnLength(); Matrix3d Xmat = B.GetMatrix(piv, 0, nx - 1); double[,] X = Xmat.ToArray(); // Solve L*Y = B(piv,:) for (int k = 0; k < n; k++) { for (int i = k + 1; i < n; i++) { for (int j = 0; j < nx; j++) { X[i, j] -= X[k, j] * LU[i, k]; } } } // Solve U*X = Y; for (int k = n - 1; k >= 0; k--) { for (int j = 0; j < nx; j++) { X[k, j] /= LU[k, k]; } for (int i = 0; i < k; i++) { for (int j = 0; j < nx; j++) { X[i, j] -= X[k, j] * LU[i, k]; } } } return(Xmat); }