示例#1
0
        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);
        }
示例#2
0
        /// <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);
            }
        }
示例#3
0
        /// <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);
        }
示例#4
0
        /// <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);
        }
示例#5
0
        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);
            }
        }