コード例 #1
0
ファイル: Matrix.cs プロジェクト: KaVisscher/MiStrAn
        // CBLAS matrix multiplication. See:
        // software.intel.com/en-us/node/468480#90EAA001-D4C8-4211-9EA0-B62F5ADE9CF0
        //
        public static Matrix MKLMatrixMultiplication(Matrix m1, Matrix m2, Stopwatch sw)
        {
            if (m1.cols != m2.rows)
            {
                throw new MException("Wrong dimensions of matrix!");
            }

            double[] A, B;
            int      rows1, rows2, cols1, cols2;

            m1.ConvertToMKLMatrix(out A, out rows1, out cols1);
            m2.ConvertToMKLMatrix(out B, out rows2, out cols2);
            sw.Start();
            /* Data initialization */
            int Order = CBLAS.ORDER.RowMajor;
            int TransA = CBLAS.TRANSPOSE.NoTrans;
            int TransB = CBLAS.TRANSPOSE.NoTrans;
            int M = rows1, N = cols2, K = cols1;
            int lda = K, ldb = N, ldc = N;

            double[] C = new double[cols1 * rows2];
            double   alpha = 1, beta = 0;

            /* Computation */
            MKL.dgemm(Order, TransA, TransB, M, N, K,
                      alpha, A, lda, B, ldb, beta, C, ldc);
            sw.Stop();
            return(ConvertFromMKLMatrix(C, cols1, rows2));
        }
コード例 #2
0
        public static void GeneralizedEigenTesting(SparseMatrix A, SparseMatrix B, double emin, double emax, int m0, out Vector[] eigenVectors, out double[] eigenValues)
        {
            if (A.rows != A.cols || B.rows != B.cols || A.rows != B.rows)
            {
                throw new MException("Eigenvalue; Matrix size mismatch or not square");
            }

            A.ConvertToCRS();
            B.ConvertToCRS();



            // INPUT VALUES
            char uplo = 'F'; //Store full matrices
            int  n    = A.rows;

            double[] a           = new double[A.mat.innerobj.vals.Length];
            int[]    ia /*[9]*/  = new int[A.mat.innerobj.ridx.Length];
            int[]    ja /*[18]*/ = new int[A.mat.innerobj.idx.Length];
            A.mat.innerobj.ridx.CopyTo(ia, 0);
            A.mat.innerobj.idx.CopyTo(ja, 0);
            A.mat.innerobj.vals.CopyTo(a, 0);
            double[] b           = new double[B.mat.innerobj.vals.Length];
            int[]    ib /*[9]*/  = new int[B.mat.innerobj.ridx.Length];
            int[]    jb /*[18]*/ = new int[B.mat.innerobj.idx.Length];
            B.mat.innerobj.ridx.CopyTo(ib, 0);
            B.mat.innerobj.idx.CopyTo(jb, 0);
            B.mat.innerobj.vals.CopyTo(b, 0);

            int[] fpm = new int[128];
            fpm[0]  = 0;  //do not print runtime status
            fpm[1]  = 32; //number of contour points.. ???
            fpm[2]  = 4;  //Error trace double precision stopping criteria ε (ε = 10-fpm[2]) .
            fpm[3]  = 5;  // Maximum number of Extended Eigensolver refinement loops allowed. If no convergence is reached within fpm[3] refinement loops, Extended Eigensolver routines return info=2.
            fpm[4]  = 0;  //Solver generates initial subspace
            fpm[5]  = 0;  //Stopping test..?
            fpm[6]  = 5;  // Error trace single precision stopping criteria (10 - fpm[6]).
            fpm[13] = 0;
            fpm[26] = 0;  // Check input matrices

            //OUTPUT VALUES
            double[] x      = new double[n * m0];
            double   epsout = 0;
            int      loops  = 0;

            double[] e = new double[m0];
            int      m = 0;

            double[] res  = new double[m0];
            int      info = 1;

            // Convert to one-based THIS COULD CERTAINLY BE OPTIMIZED
            for (int i = 0; i < ia.Length; i++)
            {
                ia[i] = ia[i] + 1;
            }
            for (int i = 0; i < ja.Length; i++)
            {
                ja[i] = ja[i] + 1;
            }
            for (int i = 0; i < ib.Length; i++)
            {
                ib[i] = ib[i] + 1;
            }
            for (int i = 0; i < jb.Length; i++)
            {
                jb[i] = jb[i] + 1;
            }


            double k = a.Max();

            double[] aScaled = scale(1.0 / k, a);
            emin = 0;
            MKL.GeneralizedEigenSolver(ref uplo, ref n, aScaled, ia, ja, b, ib, jb, fpm, ref epsout, ref loops, ref emin, ref emax, ref m0, e, x, ref m, res, ref info);

            eigenValues  = scale(k, e);
            eigenVectors = new Vector[x.Count() / n];

            for (int i = 0; i < x.Count() / n; i++)
            {
                Vector v = new Vector(n);
                for (int j = 0; j < n; j++)
                {
                    v[j] = x[(i * n) + j];
                }
                eigenVectors[i] = v;
            }

            Vector res1 = A * eigenVectors[0] - B * eigenValues[0] * eigenVectors[0];
        }
コード例 #3
0
        /// <summary>
        ///  https://software.intel.com/en-us/node/521750?language=es
        ///  See link for info
        ///  ASSUMES SYMMETRIC MATRIX
        /// The routine compute all the eigenvalues and eigenvectors for generalized eigenvalue problems, Ax = λBx, within a given search interval.
        /// </summary>
        /// <param name="A">Matrix A</param>
        /// <param name="B">Matrix B</param>
        /// <param name="emin">start of search interval</param>
        /// <param name="emax">end of search interval</param>
        /// <param name="m0">number of expected eigenvalues in interval</param>
        /// <param name="eigenVectors"></param>
        /// <param name="eigenValues"></param>
        public static void GeneralizedEigen(SparseMatrix A, SparseMatrix B, double emin, double emax, int m0, out Vector[] eigenVectors, out double[] eigenValues, out double[] residuals, out string infoString)
        {
            if (A.rows != A.cols || B.rows != B.cols || A.rows != B.rows)
            {
                throw new MException("Eigenvalue; Matrix size mismatch or not square");
            }

            A.ConvertToCRS();
            B.ConvertToCRS();



            // INPUT VALUES
            char uplo = 'F'; //Store full matrices
            int  n    = A.rows;

            double[] a           = new double[A.mat.innerobj.vals.Length];
            int[]    ia /*[9]*/  = new int[A.mat.innerobj.ridx.Length];
            int[]    ja /*[18]*/ = new int[A.mat.innerobj.idx.Length];
            A.mat.innerobj.ridx.CopyTo(ia, 0);
            A.mat.innerobj.idx.CopyTo(ja, 0);
            A.mat.innerobj.vals.CopyTo(a, 0);
            double[] b           = new double[B.mat.innerobj.vals.Length];
            int[]    ib /*[9]*/  = new int[B.mat.innerobj.ridx.Length];
            int[]    jb /*[18]*/ = new int[B.mat.innerobj.idx.Length];
            B.mat.innerobj.ridx.CopyTo(ib, 0);
            B.mat.innerobj.idx.CopyTo(jb, 0);
            B.mat.innerobj.vals.CopyTo(b, 0);

            int[] fpm = new int[128];
            fpm[0]  = 0; //do not print runtime status
            fpm[1]  = 4; //number of contour points.. ???
            fpm[2]  = 4; //Error trace double precision stopping criteria ε (ε = 10-fpm[2]) .
            fpm[3]  = 5; // Maximum number of Extended Eigensolver refinement loops allowed. If no convergence is reached within fpm[3] refinement loops, Extended Eigensolver routines return info=2.
            fpm[4]  = 0; //Solver generates initial subspace
            fpm[5]  = 0; //Stopping test..?
            fpm[6]  = 5; // Error trace single precision stopping criteria (10 - fpm[6]).
            fpm[13] = 0;
            fpm[26] = 0; // Check input matrices

            //OUTPUT VALUES
            double[] x      = new double[n * m0];
            double   epsout = 0;
            int      loops  = 0;

            double[] e = new double[m0];
            int      m = 0;

            double[] res  = new double[m0];
            int      info = 1;

            // Convert to one-based THIS COULD CERTAINLY BE OPTIMIZED
            for (int i = 0; i < ia.Length; i++)
            {
                ia[i] = ia[i] + 1;
            }
            for (int i = 0; i < ja.Length; i++)
            {
                ja[i] = ja[i] + 1;
            }
            for (int i = 0; i < ib.Length; i++)
            {
                ib[i] = ib[i] + 1;
            }
            for (int i = 0; i < jb.Length; i++)
            {
                jb[i] = jb[i] + 1;
            }


            MKL.GeneralizedEigenSolver(ref uplo, ref n, a, ia, ja, b, ib, jb, fpm, ref epsout, ref loops, ref emin, ref emax, ref m0, e, x, ref m, res, ref info);

            eigenValues  = e;
            eigenVectors = new Vector[x.Count() / n];

            for (int i = 0; i < x.Count() / n; i++)
            {
                Vector v = new Vector(n);
                for (int j = 0; j < n; j++)
                {
                    v[j] = x[(i * n) + j];
                }
                eigenVectors[i] = v;
            }

            residuals = res;

            switch (info)
            {
            case 2:
                infoString = "No convergence";
                break;

            case 1:
                infoString = "No eigenvalue found in the search interval.In some extreme cases the return value info=1 may indicate that the Extended Eigensolver routine has failed to find the eigenvalues in the search interval. This situation could arise if a very large search interval is used to locate a small and isolated cluster of eigenvalues (i.e. the dimension of the search interval is many orders of magnitude larger than the number of contour points. It is then either recommended to increase the number of contour points fpm[1] or simply rescale more appropriately the search interval. ";
                break;

            case 0:
                infoString = "Successful";
                break;

            default:
                infoString = "Undocumented error. Do not trust results";
                break;
            }
        }
コード例 #4
0
        public Vector SolvePARDISO(Vector b)
        {
            SparseMatrix K = this;

            K.ConvertToCRS();
            /* Matrix data. */
            int n = b.Length;

            int[]    ia /*[9]*/  = new int[K.mat.innerobj.ridx.Length];
            int[]    ja /*[18]*/ = new int[K.mat.innerobj.idx.Length];
            double[] a           = new double[K.mat.innerobj.vals.Length];
            double[] b_          = new double[n];
            K.mat.innerobj.ridx.CopyTo(ia, 0);
            K.mat.innerobj.idx.CopyTo(ja, 0);
            K.mat.innerobj.vals.CopyTo(a, 0);
            b.values.CopyTo(b_, 0);
            double[] x     = new double[n];
            int      mtype = 11; /* Real symmetric matrix */
                                 /* RHS and solution vectors. */

            int nrhs = 1;        /* Number of right hand sides. */

            /* Internal solver memory pointer pt, */
            /* 32-bit: int pt[64]; 64-bit: long int pt[64] */
            /* or void *pt[64] should be OK on both architectures */
            /* void *pt[64]; */
            IntPtr[] pt = new IntPtr[64];
            /* Pardiso control parameters. */
            int[] iparm = new int[64];
            int   maxfct, mnum, phase, error, msglvl;
            /* Auxiliary variables. */
            int i;

            double[] ddum = new double[1]; /* Double dummy */
            int[]    idum = new int[1];    /* Integer dummy. */
                                           /* ----------------------------------------------------------------- */
                                           /* .. Setup Pardiso control parameters. */
                                           /* ----------------------------------------------------------------- */
            for (i = 0; i < 64; i++)
            {
                iparm[i] = 0;
            }
            iparm[0] = 1;   /* No solver default */
            iparm[1] = 2;   /* Fill-in reordering from METIS */
                            /* Numbers of processors, value of OMP_NUM_THREADS */
            iparm[2]  = 1;
            iparm[3]  = 0;  /* No iterative-direct algorithm */
            iparm[4]  = 0;  /* No user fill-in reducing permutation */
            iparm[5]  = 0;  /* Write solution into x */
            iparm[6]  = 0;  /* Not in use */
            iparm[7]  = 10; /* Max numbers of iterative refinement steps */
            iparm[8]  = 0;  /* Not in use */
            iparm[9]  = 13; /* Perturb the pivot elements with 1E-13 */
            iparm[10] = 1;  /* Use nonsymmetric permutation and scaling MPS */
            iparm[11] = 0;  /* Not in use */
            iparm[12] = 0;  /* Maximum weighted matching algorithm is switched-off
                             * (default for symmetric). Try iparm[12] = 1 in case of
                             *  inappropriate accuracy */
            iparm[13] = 0;  /* Output: Number of perturbed pivots */
            iparm[14] = 0;  /* Not in use */
            iparm[15] = 0;  /* Not in use */
            iparm[16] = 0;  /* Not in use */
            iparm[17] = -1; /* Output: Number of nonzeros in the factor LU */
            iparm[18] = -1; /* Output: Mflops for LU factorization */
            iparm[19] = 0;  /* Output: Numbers of CG Iterations */
            iparm[34] = 1;
            maxfct    = 1;  /* Maximum number of numerical factorizations. */
            mnum      = 1;  /* Which factorization to use. */
            msglvl    = 0;  /* Print statistical information in file */
            error     = 0;  /* Initialize error flag */
                            /* ----------------------------------------------------------------- */
                            /* .. Initialize the internal solver memory pointer. This is only */
                            /* necessary for the FIRST call of the PARDISO solver. */
                            /* ----------------------------------------------------------------- */
            for (i = 0; i < 64; i++)
            {
                pt[i] = IntPtr.Zero;
            }
            /* ----------------------------------------------------------------- */
            /* .. Reordering and Symbolic Factorization. This step also allocates */
            /* all memory that is necessary for the factorization. */
            /* ----------------------------------------------------------------- */
            phase = 11;
            MKL.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                        ref n, a, ia, ja, idum, ref nrhs,
                        iparm, ref msglvl, ddum, ddum, ref error);
            if (error != 0)
            {
                MessageBox.Show("\nERROR during symbolic factorization: " + error);
                return(new Vector(n));
            }

            /* ----------------------------------------------------------------- */
            /* .. Numerical factorization. */
            /* ----------------------------------------------------------------- */
            phase = 22;
            MKL.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                        ref n, a, ia, ja, idum, ref nrhs,
                        iparm, ref msglvl, ddum, ddum, ref error);
            if (error != 0)
            {
                MessageBox.Show("\nERROR during numerical factorization: " + error);
                return(new Vector(n));
            }

            /* ----------------------------------------------------------------- */
            /* .. Back substitution and iterative refinement. */
            /* ----------------------------------------------------------------- */
            phase    = 33;
            iparm[7] = 5; /* Max numbers of iterative refinement steps. */
                          /* Set right hand side to one. */

            MKL.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                        ref n, a, ia, ja, idum, ref nrhs,
                        iparm, ref msglvl, b_, x, ref error);
            if (error != 0)
            {
                MessageBox.Show("\nERROR during solution: " + error);
                return(new Vector(n));
            }

            /* ----------------------------------------------------------------- */
            /* .. Termination and release of memory. */
            /* ----------------------------------------------------------------- */
            phase = -1; /* Release internal memory. */
            MKL.pardiso(pt, ref maxfct, ref mnum, ref mtype, ref phase,
                        ref n, ddum, ia, ja, idum, ref nrhs,
                        iparm, ref msglvl, ddum, ddum, ref error);

            return(new Vector(x));
        }