// These functions compute the inverse of a matrix A from its LU decomposition (LU,p), // storing the result in the matrix inverse. // The inverse is computed by solving the system A x = b for each column of the identity matrix. // It is preferable to avoid direct use of the inverse whenever possible, // as the linear solver functions can obtain the same result more efficiently and reliably // (consult any introductory textbook on numerical linear algebra for details). public static int LUInvert(PZMath_matrix LU, PZMath_permutation p, PZMath_matrix inverse) { int i; int n = LU.RowCount; int status = PZMath_errno.PZMath_SUCCESS; inverse.SetIdentity(); for (i = 0; i < n; i++) { PZMath_vector c = inverse.Column(i); int status_i = LUSVX(LU, p, c); if (status_i == PZMath_errno.PZMath_SUCCESS) status = status_i; } return status; }
public static int BidiagUnpack2(PZMath_matrix A, PZMath_vector tau_U, PZMath_vector tau_V, PZMath_matrix V) { int M = A.RowCount; int N = A.ColumnCount; int K = System.Math.Min(M, N); if (M < N) { PZMath_errno.ERROR ("PZMath_linalg::BidiagUnpack2(),matrix A must have M >= N", PZMath_errno.PZMath_EBADLEN); } else if (tau_U.Size != K) { PZMath_errno.ERROR ("PZMath_linalg::BidiagUnpack2(),size of tau must be MIN(M,N)", PZMath_errno.PZMath_EBADLEN); } else if (tau_V.Size + 1 != K) { PZMath_errno.ERROR ("PZMath_linalg::BidiagUnpack2(),size of tau must be MIN(M,N) - 1", PZMath_errno.PZMath_EBADLEN); } else if (V.RowCount != N || V.ColumnCount != N) { PZMath_errno.ERROR ("PZMath_linalg::BidiagUnpack2(),size of V must be N x N", PZMath_errno.PZMath_EBADLEN); } else { int i, j; /* Initialize V to the identity */ V.SetIdentity(); for (i = N - 1; i > 0 && (i -- > 0);) { /* Householder row transformation to accumulate V */ PZMath_vector r = A.Row(i); PZMath_vector h = r.SubVector(i + 1, N - (i+1)); double ti = tau_V[i]; PZMath_matrix m = V.Submatrix(i + 1, i + 1, N-(i+1), N-(i+1)); PZMath_linalg.HouseholderHM (ti, h, m); } /* Copy superdiagonal into tau_v */ for (i = 0; i < N - 1; i++) { double Aij = A[i, i+1]; tau_V[i] = Aij; } /* Allow U to be unpacked into the same memory as A, copy diagonal into tau_U */ for (j = N; j > 0 && (j -- > 0);) { /* Householder column transformation to accumulate U */ double tj = tau_U[j]; double Ajj = A[j, j]; PZMath_matrix m = A.Submatrix (j, j, M-j, N-j); tau_U[j] = Ajj; PZMath_linalg.HouseholderHM1(tj, m); } } return PZMath_errno.PZMath_SUCCESS;; }