public void ComputeLU(Matrix A) { _N = A.RowCount; _LU = (double[])A.Data.Clone(); _IPIV = new int[_N]; _Info = 0; DGETRF _dgetrf = new DGETRF(); _dgetrf.Run(_N, _N, ref _LU, 0, _N, ref _IPIV, 0, ref _Info); }
/// <summary> /// Computes the LU and caches the results locally. /// Either the native .NET library or Intel MKL is used. /// </summary> /// <param name="A"></param> public void ComputeLU(Matrix A) { _N = A.RowCount; _LU = (double[])A.Data.Clone(); _IPIV = new int[_N]; _Info = 0; if (UseIntelMathKernel) { IntelMathKernel.dgetrf(ref _N, ref _N, _LU, ref _N, _IPIV, ref _Info); } else { DGETRF _dgetrf = new DGETRF(); _dgetrf.Run(_N, _N, ref _LU, 0, _N, ref _IPIV, 0, ref _Info); } }
/// <summary> /// Calculates the determinant of the matrix. /// </summary> /// <returns>The determinant of the matrix.</returns> public double Determinant() { double det = 1.0; if (this.IsSquare != true) { throw new System.ArgumentException("This is not a square matrix."); } if (BaseMatrix._dgetrf == null) { BaseMatrix._dgetrf = new DGETRF(); } Matrix clonMatrix = new Matrix(this.RowCount, this.ColumnCount, this.Data); double[] clonData = clonMatrix.Data; int[] ipiv = new int[this.RowCount]; int Info = 0; BaseMatrix._dgetrf.Run(this.RowCount, this.ColumnCount, ref clonData, 0, this.RowCount, ref ipiv, 0, ref Info); #region Error // <param name="INFO"> // (output) INTEGER //= 0: successful exit // .LT. 0: if INFO = -i, the i-th argument had an illegal value // .GT. 0: if INFO = i, U(i,i) is exactly zero. The factorization // has been completed, but the factor U is exactly // singular, and division by zero will occur if it is used // to solve a system of equations. if (Info < 0) { string infoSTg = Math.Abs(Info).ToString(); throw new ArgumentException("the " + infoSTg + " -th argument had an illegal value"); } //else if (Info > 0) //{ // string infoSTg = Math.Abs(Info).ToString(); // throw new Exception("The matrix is numerically singular.."); //} #endregion //The LU factorization yields three matrices, the product of which is the original //complex matrix. Therefore the determinat is the product of the three determinants //of P, L and U. The determinant of the triangular matrices L and U is the product //of the elements on the diagonal - as for any triangular matrix (for L this is 1 //as all elements of the diagonal are one.) The determinant of P is either +1 or -1 //depending of whether the number of row permutations is even or odd. //Thank you very much for your answer. It seems to be that your message got tructated somehow, but I think I got the point. //I also did some searching on the web and found the following two pieces of code which both claim to calculate the determinant of a square matrix. //============================================ //call dgetrf(n,n,a,n,piv,info) //det = 0d0 //if (info.ne.0) then //return //endif //det = 1d0 //do 10,i=1,n //if (piv(i).ne.i) then //det = -det * a(i,i) //else //det = det * a(i,i) //endif //10 continue //end for (int i = 0; i < this._RowCount; i++) { if (ipiv[i] != (i + 1)) // i+1 debido a que aqui la base es 0 y en fortran es 1 { det *= -clonMatrix[i, i]; } else { det *= clonMatrix[i, i]; } } return(det); }
/// <summary> /// Calculates the inverse of the matrix. /// </summary> /// <returns>The inverse of the matrix.</returns> public Matrix Inverse() { if (this.IsSquare != true) { throw new System.ArgumentException("This is not a square matrix."); } if (BaseMatrix._dgetrf == null) { BaseMatrix._dgetrf = new DGETRF(); } if (BaseMatrix._dgetri == null) { BaseMatrix._dgetri = new DGETRI(); } Matrix inverseMatrix = new Matrix(this.RowCount, this.ColumnCount, this.Data); double[] inverseData = inverseMatrix.Data; int[] ipiv = new int[this.RowCount]; int Info = 0; double[] Work = new double[1]; int LWork = -1; //Calculamos LWORK BaseMatrix._dgetri.Run(this.RowCount, ref inverseData, 0, this.RowCount, ipiv, 0, ref Work, 0, LWork, ref Info); LWork = Convert.ToInt32(Work[0]); if (LWork > 0) { Work = new double[LWork]; BaseMatrix._dgetrf.Run(this.RowCount, this.ColumnCount, ref inverseData, 0, this.RowCount, ref ipiv, 0, ref Info); #region Error /// = 0: successful exit /// .LT. 0: if INFO = -i, the i-th argument had an illegal value /// .GT. 0: if INFO = i, U(i,i) is exactly zero. The factorization /// has been completed, but the factor U is exactly /// singular, and division by zero will occur if it is used /// to solve a system of equations. if (Info < 0) { string infoSTg = Math.Abs(Info).ToString(); throw new ArgumentException("the " + infoSTg + " -th argument had an illegal value"); } else if (Info > 0) { string infoSTg = Math.Abs(Info).ToString(); throw new Exception("The matrix is numerically singular.."); } #endregion BaseMatrix._dgetri.Run(this.RowCount, ref inverseData, 0, this.RowCount, ipiv, 0, ref Work, 0, LWork, ref Info); } else { //Error } #region Error /// (output) INTEGER /// = 0: successful exit /// .LT. 0: if INFO = -i, the i-th argument had an illegal value /// .GT. 0: if INFO = i, U(i,i) is exactly zero; the matrix is /// singular and its inverse could not be computed. if (Info < 0) { string infoSTg = Math.Abs(Info).ToString(); throw new ArgumentException("the " + infoSTg + " -th argument had an illegal value"); } else if (Info > 0) { string infoSTg = Math.Abs(Info).ToString(); throw new Exception("The matrix is numerically singular.."); } #endregion return(inverseMatrix); }
public static bool Start() { Console.WriteLine("Testing LU decomposition"); int n = 3; int info = 0; int[] ipiv = new int[3]; Matrix Mtx = new Matrix(3); Mtx[0, 0] = 1; Mtx[0, 1] = 9; Mtx[0, 2] = 5; Mtx[1, 0] = 1; Mtx[1, 1] = 3; Mtx[1, 2] = 4; Mtx[2, 0] = 5; Mtx[2, 1] = 6; Mtx[2, 2] = 7; try { // Case 1 Console.WriteLine("Computing LU with MKL dgetrf..."); double[] A = (double[])Mtx.Data.Clone(); IntelMathKernel.dgetrf(ref n, ref n, A, ref n, ipiv, ref info); // Case 2 Console.WriteLine("Computing LU with with .NET dgetrf..."); double[] B = (double[])Mtx.Data.Clone(); DGETRF _dgetrf = new DGETRF(); _dgetrf.Run(n, n, ref B, 0, n, ref ipiv, 0, ref info); Console.WriteLine("Comparing results..."); for (int i = 0; i < 5; i++) { if (A[i] != B[i] || (B[i] > 0.0 & (A[i] - B[i]) / B[i] > 1E-5)) { Console.WriteLine("TEST NOT PASSED"); return(false); } } // Case 3 Console.WriteLine("Solving linear equations with MKL dgetrs..."); info = 0; int nrhs = 1; double[] R = new double[3]; R[0] = 1; R[1] = 2; R[2] = 5; char[] trans = "No transponse".ToCharArray(); IntelMathKernel.dgetrs(trans, ref n, ref nrhs, A, ref n, ipiv, R, ref n, ref info); Console.WriteLine("TEST PASSED"); return(true); } catch { Console.WriteLine("TEST NOT PASSED"); return(false); } }