/*************************************************************************
        Tests whether A is HPD
        *************************************************************************/
        private static bool ishpd(complex[,] a,
            int n)
        {
            bool result = new bool();
            int j = 0;
            double ajj = 0;
            complex v = 0;
            double r = 0;
            complex[] t = new complex[0];
            complex[] t2 = new complex[0];
            complex[] t3 = new complex[0];
            int i = 0;
            complex[,] a1 = new complex[0,0];
            int i_ = 0;

            a = (complex[,])a.Clone();

            t = new complex[n-1+1];
            t2 = new complex[n-1+1];
            t3 = new complex[n-1+1];
            result = true;
            
            //
            // Compute the Cholesky factorization A = U'*U.
            //
            for(j=0; j<=n-1; j++)
            {
                
                //
                // Compute U(J,J) and test for non-positive-definiteness.
                //
                v = 0.0;
                for(i_=0; i_<=j-1;i_++)
                {
                    v += math.conj(a[i_,j])*a[i_,j];
                }
                ajj = (a[j,j]-v).x;
                if( (double)(ajj)<=(double)(0) )
                {
                    a[j,j] = ajj;
                    result = false;
                    return result;
                }
                ajj = Math.Sqrt(ajj);
                a[j,j] = ajj;
                
                //
                // Compute elements J+1:N-1 of row J.
                //
                if( j<n-1 )
                {
                    for(i_=0; i_<=j-1;i_++)
                    {
                        t2[i_] = math.conj(a[i_,j]);
                    }
                    for(i_=j+1; i_<=n-1;i_++)
                    {
                        t3[i_] = a[j,i_];
                    }
                    for(i=j+1; i<=n-1; i++)
                    {
                        v = 0.0;
                        for(i_=0; i_<=j-1;i_++)
                        {
                            v += a[i_,i]*t2[i_];
                        }
                        t3[i] = t3[i]-v;
                    }
                    for(i_=j+1; i_<=n-1;i_++)
                    {
                        a[j,i_] = t3[i_];
                    }
                    r = 1/ajj;
                    for(i_=j+1; i_<=n-1;i_++)
                    {
                        a[j,i_] = r*a[j,i_];
                    }
                }
            }
            return result;
        }
        /*************************************************************************
        Checks whether inverse is correct
        Returns True on success.
        *************************************************************************/
        private static bool hpdmatrixcheckinverse(complex[,] a,
            complex[,] inva,
            bool isupper,
            int n,
            double threshold,
            int info,
            matinv.matinvreport rep)
        {
            bool result = new bool();
            int i = 0;
            int j = 0;
            complex v = 0;
            int i_ = 0;

            a = (complex[,])a.Clone();
            inva = (complex[,])inva.Clone();

            for(i=0; i<=n-2; i++)
            {
                if( isupper )
                {
                    for(i_=i+1; i_<=n-1;i_++)
                    {
                        a[i_,i] = math.conj(a[i,i_]);
                    }
                    for(i_=i+1; i_<=n-1;i_++)
                    {
                        inva[i_,i] = math.conj(inva[i,i_]);
                    }
                }
                else
                {
                    for(i_=i+1; i_<=n-1;i_++)
                    {
                        a[i,i_] = math.conj(a[i_,i]);
                    }
                    for(i_=i+1; i_<=n-1;i_++)
                    {
                        inva[i,i_] = math.conj(inva[i_,i]);
                    }
                }
            }
            result = true;
            if( info<=0 )
            {
                result = false;
            }
            else
            {
                result = result & !((double)(rep.r1)<(double)(100*math.machineepsilon) | (double)(rep.r1)>(double)(1+1000*math.machineepsilon));
                result = result & !((double)(rep.rinf)<(double)(100*math.machineepsilon) | (double)(rep.rinf)>(double)(1+1000*math.machineepsilon));
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        v = 0.0;
                        for(i_=0; i_<=n-1;i_++)
                        {
                            v += a[i,i_]*inva[i_,j];
                        }
                        if( i==j )
                        {
                            v = v-1;
                        }
                        result = result & (double)(math.abscomplex(v))<=(double)(threshold);
                    }
                }
            }
            return result;
        }
Esempio n. 3
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Estimate of a matrix condition number (infinity-norm).

        The algorithm calculates a lower bound of the condition number. In this case,
        the algorithm does not return a lower bound of the condition number, but an
        inverse number (to avoid an overflow in case of a singular matrix).

        Input parameters:
            A   -   matrix. Array whose indexes range within [0..N-1, 0..N-1].
            N   -   size of matrix A.

        Result: 1/LowerBound(cond(A))

        NOTE:
            if k(A) is very large, then matrix is  assumed  degenerate,  k(A)=INF,
            0.0 is returned in such cases.
        *************************************************************************/
        public static double cmatrixrcondinf(complex[,] a,
            int n)
        {
            double result = 0;
            int i = 0;
            int j = 0;
            double v = 0;
            double nrm = 0;
            int[] pivots = new int[0];

            a = (complex[,])a.Clone();

            ap.assert(n>=1, "CMatrixRCondInf: N<1!");
            nrm = 0;
            for(i=0; i<=n-1; i++)
            {
                v = 0;
                for(j=0; j<=n-1; j++)
                {
                    v = v+math.abscomplex(a[i,j]);
                }
                nrm = Math.Max(nrm, v);
            }
            trfac.cmatrixlu(ref a, n, n, ref pivots);
            cmatrixrcondluinternal(a, n, false, true, nrm, ref v);
            result = v;
            return result;
        }
Esempio n. 4
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Calculation of the determinant of a general matrix

        Input parameters:
            A       -   matrix, array[0..N-1, 0..N-1]
            N       -   (optional) size of matrix A:
                        * if given, only principal NxN submatrix is processed and
                          overwritten. other elements are unchanged.
                        * if not given, automatically determined from matrix size
                          (A must be square matrix)

        Result: determinant of matrix A.

          -- ALGLIB --
             Copyright 2005 by Bochkanov Sergey
        *************************************************************************/
        public static complex cmatrixdet(complex[,] a,
            int n)
        {
            complex result = 0;
            int[] pivots = new int[0];

            a = (complex[,])a.Clone();

            ap.assert(n>=1, "CMatrixDet: N<1!");
            ap.assert(ap.rows(a)>=n, "CMatrixDet: rows(A)<N!");
            ap.assert(ap.cols(a)>=n, "CMatrixDet: cols(A)<N!");
            ap.assert(apserv.apservisfinitecmatrix(a, n, n), "CMatrixDet: A contains infinite or NaN values!");
            trfac.cmatrixlu(ref a, n, n, ref pivots);
            result = cmatrixludet(a, pivots, n);
            return result;
        }
Esempio n. 5
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Condition number estimate of a Hermitian positive definite matrix.

        The algorithm calculates a lower bound of the condition number. In this case,
        the algorithm does not return a lower bound of the condition number, but an
        inverse number (to avoid an overflow in case of a singular matrix).

        It should be noted that 1-norm and inf-norm of condition numbers of symmetric
        matrices are equal, so the algorithm doesn't take into account the
        differences between these types of norms.

        Input parameters:
            A       -   Hermitian positive definite matrix which is given by its
                        upper or lower triangle depending on the value of
                        IsUpper. Array with elements [0..N-1, 0..N-1].
            N       -   size of matrix A.
            IsUpper -   storage format.

        Result:
            1/LowerBound(cond(A)), if matrix A is positive definite,
           -1, if matrix A is not positive definite, and its condition number
            could not be found by this algorithm.

        NOTE:
            if k(A) is very large, then matrix is  assumed  degenerate,  k(A)=INF,
            0.0 is returned in such cases.
        *************************************************************************/
        public static double hpdmatrixrcond(complex[,] a,
            int n,
            bool isupper)
        {
            double result = 0;
            int i = 0;
            int j = 0;
            int j1 = 0;
            int j2 = 0;
            double v = 0;
            double nrm = 0;
            double[] t = new double[0];

            a = (complex[,])a.Clone();

            t = new double[n];
            for(i=0; i<=n-1; i++)
            {
                t[i] = 0;
            }
            for(i=0; i<=n-1; i++)
            {
                if( isupper )
                {
                    j1 = i;
                    j2 = n-1;
                }
                else
                {
                    j1 = 0;
                    j2 = i;
                }
                for(j=j1; j<=j2; j++)
                {
                    if( i==j )
                    {
                        t[i] = t[i]+math.abscomplex(a[i,i]);
                    }
                    else
                    {
                        t[i] = t[i]+math.abscomplex(a[i,j]);
                        t[j] = t[j]+math.abscomplex(a[i,j]);
                    }
                }
            }
            nrm = 0;
            for(i=0; i<=n-1; i++)
            {
                nrm = Math.Max(nrm, t[i]);
            }
            if( trfac.hpdmatrixcholesky(ref a, n, isupper) )
            {
                hpdmatrixrcondcholeskyinternal(a, n, isupper, true, nrm, ref v);
                result = v;
            }
            else
            {
                result = -1;
            }
            return result;
        }
Esempio n. 6
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Estimate of a matrix condition number (1-norm)

        The algorithm calculates a lower bound of the condition number. In this case,
        the algorithm does not return a lower bound of the condition number, but an
        inverse number (to avoid an overflow in case of a singular matrix).

        Input parameters:
            A   -   matrix. Array whose indexes range within [0..N-1, 0..N-1].
            N   -   size of matrix A.

        Result: 1/LowerBound(cond(A))

        NOTE:
            if k(A) is very large, then matrix is  assumed  degenerate,  k(A)=INF,
            0.0 is returned in such cases.
        *************************************************************************/
        public static double cmatrixrcond1(complex[,] a,
            int n)
        {
            double result = 0;
            int i = 0;
            int j = 0;
            double v = 0;
            double nrm = 0;
            int[] pivots = new int[0];
            double[] t = new double[0];

            a = (complex[,])a.Clone();

            ap.assert(n>=1, "CMatrixRCond1: N<1!");
            t = new double[n];
            for(i=0; i<=n-1; i++)
            {
                t[i] = 0;
            }
            for(i=0; i<=n-1; i++)
            {
                for(j=0; j<=n-1; j++)
                {
                    t[j] = t[j]+math.abscomplex(a[i,j]);
                }
            }
            nrm = 0;
            for(i=0; i<=n-1; i++)
            {
                nrm = Math.Max(nrm, t[i]);
            }
            trfac.cmatrixlu(ref a, n, n, ref pivots);
            cmatrixrcondluinternal(a, n, true, true, nrm, ref v);
            result = v;
            return result;
        }
Esempio n. 7
0
            /*************************************************************************
            Finding the eigenvalues and eigenvectors of a Hermitian matrix

            The algorithm finds eigen pairs of a Hermitian matrix by  reducing  it  to
            real tridiagonal form and using the QL/QR algorithm.

            Input parameters:
                A       -   Hermitian matrix which is given  by  its  upper  or  lower
                            triangular part.
                            Array whose indexes range within [0..N-1, 0..N-1].
                N       -   size of matrix A.
                IsUpper -   storage format.
                ZNeeded -   flag controlling whether the eigenvectors  are  needed  or
                            not. If ZNeeded is equal to:
                             * 0, the eigenvectors are not returned;
                             * 1, the eigenvectors are returned.

            Output parameters:
                D       -   eigenvalues in ascending order.
                            Array whose index ranges within [0..N-1].
                Z       -   if ZNeeded is equal to:
                             * 0, Z hasn’t changed;
                             * 1, Z contains the eigenvectors.
                            Array whose indexes range within [0..N-1, 0..N-1].
                            The eigenvectors are stored in the matrix columns.

            Result:
                True, if the algorithm has converged.
                False, if the algorithm hasn't converged (rare case).

            Note:
                eigenvectors of Hermitian matrix are defined up to  multiplication  by
                a complex number L, such that |L|=1.

              -- ALGLIB --
                 Copyright 2005, 23 March 2007 by Bochkanov Sergey
            *************************************************************************/
            public static bool hmatrixevd(complex[,] a,
                int n,
                int zneeded,
                bool isupper,
                ref double[] d,
                ref complex[,] z)
            {
                bool result = new bool();
                complex[] tau = new complex[0];
                double[] e = new double[0];
                double[] work = new double[0];
                double[,] t = new double[0, 0];
                complex[,] q = new complex[0, 0];
                int i = 0;
                int k = 0;
                double v = 0;
                int i_ = 0;

                a = (complex[,])a.Clone();
                d = new double[0];
                z = new complex[0, 0];

                alglib.ap.assert(zneeded == 0 || zneeded == 1, "HermitianEVD: incorrect ZNeeded");

                //
                // Reduce to tridiagonal form
                //
                ortfac.hmatrixtd(ref a, n, isupper, ref tau, ref d, ref e);
                if (zneeded == 1)
                {
                    ortfac.hmatrixtdunpackq(a, n, isupper, tau, ref q);
                    zneeded = 2;
                }

                //
                // TDEVD
                //
                result = smatrixtdevd(ref d, e, n, zneeded, ref t);

                //
                // Eigenvectors are needed
                // Calculate Z = Q*T = Re(Q)*T + i*Im(Q)*T
                //
                if (result && zneeded != 0)
                {
                    work = new double[n - 1 + 1];
                    z = new complex[n - 1 + 1, n - 1 + 1];
                    for (i = 0; i <= n - 1; i++)
                    {

                        //
                        // Calculate real part
                        //
                        for (k = 0; k <= n - 1; k++)
                        {
                            work[k] = 0;
                        }
                        for (k = 0; k <= n - 1; k++)
                        {
                            v = q[i, k].x;
                            for (i_ = 0; i_ <= n - 1; i_++)
                            {
                                work[i_] = work[i_] + v * t[k, i_];
                            }
                        }
                        for (k = 0; k <= n - 1; k++)
                        {
                            z[i, k].x = work[k];
                        }

                        //
                        // Calculate imaginary part
                        //
                        for (k = 0; k <= n - 1; k++)
                        {
                            work[k] = 0;
                        }
                        for (k = 0; k <= n - 1; k++)
                        {
                            v = q[i, k].y;
                            for (i_ = 0; i_ <= n - 1; i_++)
                            {
                                work[i_] = work[i_] + v * t[k, i_];
                            }
                        }
                        for (k = 0; k <= n - 1; k++)
                        {
                            z[i, k].y = work[k];
                        }
                    }
                }
                return result;
            }
Esempio n. 8
0
File: linalg.cs Progetto: Ring-r/opt
        /*************************************************************************
        Subroutine for finding the eigenvalues and  eigenvectors  of  a  Hermitian
        matrix with given indexes by using bisection and inverse iteration methods

        Input parameters:
            A       -   Hermitian matrix which is given  by  its  upper  or  lower
                        triangular part.
                        Array whose indexes range within [0..N-1, 0..N-1].
            N       -   size of matrix A.
            ZNeeded -   flag controlling whether the eigenvectors  are  needed  or
                        not. If ZNeeded is equal to:
                         * 0, the eigenvectors are not returned;
                         * 1, the eigenvectors are returned.
            IsUpperA -  storage format of matrix A.
            I1, I2 -    index interval for searching (from I1 to I2).
                        0 <= I1 <= I2 <= N-1.

        Output parameters:
            W       -   array of the eigenvalues found.
                        Array whose index ranges within [0..I2-I1].
            Z       -   if ZNeeded is equal to:
                         * 0, Z hasn’t changed;
                         * 1, Z contains eigenvectors.
                        Array whose indexes range within [0..N-1, 0..I2-I1].
                        In  that  case,  the eigenvectors are stored in the matrix
                        columns.

        Result:
            True, if successful. W contains the eigenvalues, Z contains the
            eigenvectors (if needed).

            False, if the bisection method subroutine  wasn't  able  to  find  the
            eigenvalues  in  the  given  interval  or  if  the  inverse  iteration
            subroutine wasn't able to find  all  the  corresponding  eigenvectors.
            In that case, the eigenvalues and eigenvectors are not returned.

        Note:
            eigen vectors of Hermitian matrix are defined up to multiplication  by
            a complex number L, such as |L|=1.

          -- ALGLIB --
             Copyright 07.01.2006, 24.03.2007 by Bochkanov Sergey.
        *************************************************************************/
        public static bool hmatrixevdi(complex[,] a,
            int n,
            int zneeded,
            bool isupper,
            int i1,
            int i2,
            ref double[] w,
            ref complex[,] z)
        {
            bool result = new bool();
            complex[,] q = new complex[0,0];
            double[,] t = new double[0,0];
            complex[] tau = new complex[0];
            double[] e = new double[0];
            double[] work = new double[0];
            int i = 0;
            int k = 0;
            double v = 0;
            int m = 0;
            int i_ = 0;

            a = (complex[,])a.Clone();
            w = new double[0];
            z = new complex[0,0];

            ap.assert(zneeded==0 | zneeded==1, "HermitianEigenValuesAndVectorsByIndexes: incorrect ZNeeded");
            
            //
            // Reduce to tridiagonal form
            //
            ortfac.hmatrixtd(ref a, n, isupper, ref tau, ref w, ref e);
            if( zneeded==1 )
            {
                ortfac.hmatrixtdunpackq(a, n, isupper, tau, ref q);
                zneeded = 2;
            }
            
            //
            // Bisection and inverse iteration
            //
            result = smatrixtdevdi(ref w, e, n, zneeded, i1, i2, ref t);
            
            //
            // Eigenvectors are needed
            // Calculate Z = Q*T = Re(Q)*T + i*Im(Q)*T
            //
            m = i2-i1+1;
            if( result & zneeded!=0 )
            {
                work = new double[m-1+1];
                z = new complex[n-1+1, m-1+1];
                for(i=0; i<=n-1; i++)
                {
                    
                    //
                    // Calculate real part
                    //
                    for(k=0; k<=m-1; k++)
                    {
                        work[k] = 0;
                    }
                    for(k=0; k<=n-1; k++)
                    {
                        v = q[i,k].x;
                        for(i_=0; i_<=m-1;i_++)
                        {
                            work[i_] = work[i_] + v*t[k,i_];
                        }
                    }
                    for(k=0; k<=m-1; k++)
                    {
                        z[i,k].x = work[k];
                    }
                    
                    //
                    // Calculate imaginary part
                    //
                    for(k=0; k<=m-1; k++)
                    {
                        work[k] = 0;
                    }
                    for(k=0; k<=n-1; k++)
                    {
                        v = q[i,k].y;
                        for(i_=0; i_<=m-1;i_++)
                        {
                            work[i_] = work[i_] + v*t[k,i_];
                        }
                    }
                    for(k=0; k<=m-1; k++)
                    {
                        z[i,k].y = work[k];
                    }
                }
            }
            return result;
        }
Esempio n. 9
0
        /*************************************************************************
        Finding the eigenvalues and eigenvectors of a Hermitian matrix

        The algorithm finds eigen pairs of a Hermitian matrix by  reducing  it  to
        real tridiagonal form and using the QL/QR algorithm.

        COMMERCIAL EDITION OF ALGLIB:

          ! Commercial version of ALGLIB includes one  important  improvement   of
          ! this function, which can be used from C++ and C#:
          ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB)
          !
          ! Intel MKL gives approximately constant  (with  respect  to  number  of
          ! worker threads) acceleration factor which depends on CPU  being  used,
          ! problem  size  and  "baseline"  ALGLIB  edition  which  is  used   for
          ! comparison.
          !
          ! Generally, commercial ALGLIB is several times faster than  open-source
          ! generic C edition, and many times faster than open-source C# edition.
          !
          ! Multithreaded acceleration is NOT supported for this function.
          !
          ! We recommend you to read 'Working with commercial version' section  of
          ! ALGLIB Reference Manual in order to find out how to  use  performance-
          ! related features provided by commercial edition of ALGLIB.

        Input parameters:
            A       -   Hermitian matrix which is given  by  its  upper  or  lower
                        triangular part.
                        Array whose indexes range within [0..N-1, 0..N-1].
            N       -   size of matrix A.
            IsUpper -   storage format.
            ZNeeded -   flag controlling whether the eigenvectors  are  needed  or
                        not. If ZNeeded is equal to:
                         * 0, the eigenvectors are not returned;
                         * 1, the eigenvectors are returned.

        Output parameters:
            D       -   eigenvalues in ascending order.
                        Array whose index ranges within [0..N-1].
            Z       -   if ZNeeded is equal to:
                         * 0, Z hasn’t changed;
                         * 1, Z contains the eigenvectors.
                        Array whose indexes range within [0..N-1, 0..N-1].
                        The eigenvectors are stored in the matrix columns.

        Result:
            True, if the algorithm has converged.
            False, if the algorithm hasn't converged (rare case).

        Note:
            eigenvectors of Hermitian matrix are defined up to  multiplication  by
            a complex number L, such that |L|=1.

          -- ALGLIB --
             Copyright 2005, 23 March 2007 by Bochkanov Sergey
        *************************************************************************/
        public static bool hmatrixevd(complex[,] a,
            int n,
            int zneeded,
            bool isupper,
            ref double[] d,
            ref complex[,] z)
        {
            bool result = new bool();
            complex[] tau = new complex[0];
            double[] e = new double[0];
            double[,] t = new double[0,0];
            double[,] qz = new double[0,0];
            complex[,] q = new complex[0,0];
            int i = 0;
            int j = 0;

            a = (complex[,])a.Clone();
            d = new double[0];
            z = new complex[0,0];

            alglib.ap.assert(zneeded==0 || zneeded==1, "HermitianEVD: incorrect ZNeeded");
            
            //
            // Reduce to tridiagonal form
            //
            ortfac.hmatrixtd(ref a, n, isupper, ref tau, ref d, ref e);
            if( zneeded==1 )
            {
                ortfac.hmatrixtdunpackq(a, n, isupper, tau, ref q);
                zneeded = 2;
            }
            
            //
            // TDEVD
            //
            result = smatrixtdevd(ref d, e, n, zneeded, ref t);
            
            //
            // Eigenvectors are needed
            // Calculate Z = Q*T = Re(Q)*T + i*Im(Q)*T
            //
            if( result && zneeded!=0 )
            {
                z = new complex[n, n];
                qz = new double[n, 2*n];
                
                //
                // Calculate Re(Q)*T
                //
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        qz[i,j] = q[i,j].x;
                    }
                }
                ablas.rmatrixgemm(n, n, n, 1.0, qz, 0, 0, 0, t, 0, 0, 0, 0.0, qz, 0, n);
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        z[i,j].x = qz[i,n+j];
                    }
                }
                
                //
                // Calculate Im(Q)*T
                //
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        qz[i,j] = q[i,j].y;
                    }
                }
                ablas.rmatrixgemm(n, n, n, 1.0, qz, 0, 0, 0, t, 0, 0, 0, 0.0, qz, 0, n);
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=n-1; j++)
                    {
                        z[i,j].y = qz[i,n+j];
                    }
                }
            }
            return result;
        }
Esempio n. 10
0
        /*************************************************************************
        Dense solver for A*x=b, with N*N Hermitian positive definite matrix A, and
        N*1 complex vectors  x  and  b.  "Fast-but-lightweight"  version  of   the
        solver without additional functions.

        Algorithm features:
        * O(N^3) complexity
        * matrix is represented by its upper or lower triangle
        * no additional time consuming functions

        COMMERCIAL EDITION OF ALGLIB:

          ! Commercial version of ALGLIB includes two  important  improvements  of
          ! this function, which can be used from C++ and C#:
          ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB)
          ! * multicore support
          !
          ! Intel MKL gives approximately constant  (with  respect  to  number  of
          ! worker threads) acceleration factor which depends on CPU  being  used,
          ! problem  size  and  "baseline"  ALGLIB  edition  which  is  used   for
          ! comparison.
          !
          ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be:
          ! * about 2-3x faster than ALGLIB for C++ without MKL
          ! * about 7-10x faster than "pure C#" edition of ALGLIB
          ! Difference in performance will be more striking  on  newer  CPU's with
          ! support for newer SIMD instructions. Generally,  MKL  accelerates  any
          ! problem whose size is at least 128, with best  efficiency achieved for
          ! N's larger than 512.
          !
          ! Commercial edition of ALGLIB also supports multithreaded  acceleration
          ! of this function. We should note that Cholesky decomposition is harder
          ! to parallelize than, say, matrix-matrix product - this  algorithm  has
          ! several synchronization points which  can  not  be  avoided.  However,
          ! parallelism starts to be profitable starting from N=500.
          !
          ! In order to use multicore features you have to:
          ! * use commercial version of ALGLIB
          ! * call  this  function  with  "smp_"  prefix,  which  indicates  that
          !   multicore code will be used (for multicore support)
          !
          ! We recommend you to read 'Working with commercial version' section  of
          ! ALGLIB Reference Manual in order to find out how to  use  performance-
          ! related features provided by commercial edition of ALGLIB.

        INPUT PARAMETERS
            A       -   array[0..N-1,0..N-1], system matrix
            N       -   size of A
            IsUpper -   what half of A is provided
            B       -   array[0..N-1], right part

        OUTPUT PARAMETERS
            Info    -   return code:
                        * -3    A is is exactly singular or not positive definite
                                X is filled by zeros in such cases.
                        * -1    N<=0 was passed
                        *  1    task was solved 
            B       -   array[0..N-1]:
                        * overwritten by solution
                        * zeros, if A is exactly singular (diagonal of its LU
                          decomposition has exact zeros).

          -- ALGLIB --
             Copyright 17.03.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void hpdmatrixsolvefast(complex[,] a,
            int n,
            bool isupper,
            complex[] b,
            ref int info)
        {
            int i = 0;

            a = (complex[,])a.Clone();
            info = 0;

            info = 1;
            if( n<=0 )
            {
                info = -1;
                return;
            }
            if( !trfac.hpdmatrixcholesky(ref a, n, isupper) )
            {
                for(i=0; i<=n-1; i++)
                {
                    b[i] = 0.0;
                }
                info = -3;
                return;
            }
            hpdbasiccholeskysolve(a, n, isupper, b);
        }
Esempio n. 11
0
        /*************************************************************************
        Dense solver for A*X=B, with N*N Hermitian positive definite matrix A  and
        N*M complex matrices X and B. "Fast-but-lightweight" version of the solver.

        Algorithm features:
        * O(N^3+M*N^2) complexity
        * matrix is represented by its upper or lower triangle
        * no additional time consuming features like condition number estimation

        COMMERCIAL EDITION OF ALGLIB:

          ! Commercial version of ALGLIB includes two  important  improvements  of
          ! this function, which can be used from C++ and C#:
          ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB)
          ! * multicore support
          !
          ! Intel MKL gives approximately constant  (with  respect  to  number  of
          ! worker threads) acceleration factor which depends on CPU  being  used,
          ! problem  size  and  "baseline"  ALGLIB  edition  which  is  used   for
          ! comparison.
          !
          ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be:
          ! * about 2-3x faster than ALGLIB for C++ without MKL
          ! * about 7-10x faster than "pure C#" edition of ALGLIB
          ! Difference in performance will be more striking  on  newer  CPU's with
          ! support for newer SIMD instructions. Generally,  MKL  accelerates  any
          ! problem whose size is at least 128, with best  efficiency achieved for
          ! N's larger than 512.
          !
          ! Commercial edition of ALGLIB also supports multithreaded  acceleration
          ! of this function. We should note that Cholesky decomposition is harder
          ! to parallelize than, say, matrix-matrix product - this  algorithm  has
          ! several synchronization points which  can  not  be  avoided.  However,
          ! parallelism starts to be profitable starting from N=500.
          !
          ! In order to use multicore features you have to:
          ! * use commercial version of ALGLIB
          ! * call  this  function  with  "smp_"  prefix,  which  indicates  that
          !   multicore code will be used (for multicore support)
          !
          ! We recommend you to read 'Working with commercial version' section  of
          ! ALGLIB Reference Manual in order to find out how to  use  performance-
          ! related features provided by commercial edition of ALGLIB.

        INPUT PARAMETERS
            A       -   array[0..N-1,0..N-1], system matrix
            N       -   size of A
            IsUpper -   what half of A is provided
            B       -   array[0..N-1,0..M-1], right part
            M       -   right part size

        OUTPUT PARAMETERS
            Info    -   return code:
                        * -3    A is is exactly  singular or is not positive definite.
                                B is filled by zeros in such cases.
                        * -1    N<=0 was passed
                        *  1    task is solved
            B       -   array[0..N-1]:
                        * overwritten by solution
                        * zeros, if problem was not solved

          -- ALGLIB --
             Copyright 17.03.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void hpdmatrixsolvemfast(complex[,] a,
            int n,
            bool isupper,
            complex[,] b,
            int m,
            ref int info)
        {
            int i = 0;
            int j = 0;

            a = (complex[,])a.Clone();
            info = 0;

            info = 1;
            if( n<=0 )
            {
                info = -1;
                return;
            }
            if( !trfac.hpdmatrixcholesky(ref a, n, isupper) )
            {
                for(i=0; i<=n-1; i++)
                {
                    for(j=0; j<=m-1; j++)
                    {
                        b[i,j] = 0.0;
                    }
                }
                info = -3;
                return;
            }
            if( isupper )
            {
                ablas.cmatrixlefttrsm(n, m, a, 0, 0, true, false, 2, b, 0, 0);
                ablas.cmatrixlefttrsm(n, m, a, 0, 0, true, false, 0, b, 0, 0);
            }
            else
            {
                ablas.cmatrixlefttrsm(n, m, a, 0, 0, false, false, 0, b, 0, 0);
                ablas.cmatrixlefttrsm(n, m, a, 0, 0, false, false, 2, b, 0, 0);
            }
        }
Esempio n. 12
0
        /*************************************************************************
        Complex dense solver for A*x=B with N*N complex matrix A and  N*1  complex
        vectors x and b. "Fast-but-lightweight" version of the solver.

        Algorithm features:
        * O(N^3) complexity
        * no additional time consuming features, just triangular solver

        COMMERCIAL EDITION OF ALGLIB:

          ! Commercial version of ALGLIB includes two  important  improvements  of
          ! this function, which can be used from C++ and C#:
          ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB)
          ! * multicore support
          !
          ! Intel MKL gives approximately constant  (with  respect  to  number  of
          ! worker threads) acceleration factor which depends on CPU  being  used,
          ! problem  size  and  "baseline"  ALGLIB  edition  which  is  used   for
          ! comparison.
          !
          ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be:
          ! * about 2-3x faster than ALGLIB for C++ without MKL
          ! * about 7-10x faster than "pure C#" edition of ALGLIB
          ! Difference in performance will be more striking  on  newer  CPU's with
          ! support for newer SIMD instructions. Generally,  MKL  accelerates  any
          ! problem whose size is at least 128, with best  efficiency achieved for
          ! N's larger than 512.
          !
          ! Commercial edition of ALGLIB also supports multithreaded  acceleration
          ! of this function. We should note that LU decomposition  is  harder  to
          ! parallelize than, say, matrix-matrix  product  -  this  algorithm  has
          ! many internal synchronization points which can not be avoided. However
          ! parallelism starts to be profitable starting  from  N=1024,  achieving
          ! near-linear speedup for N=4096 or higher.
          !
          ! In order to use multicore features you have to:
          ! * use commercial version of ALGLIB
          ! * call  this  function  with  "smp_"  prefix,  which  indicates  that
          !   multicore code will be used (for multicore support)
          !
          ! We recommend you to read 'Working with commercial version' section  of
          ! ALGLIB Reference Manual in order to find out how to  use  performance-
          ! related features provided by commercial edition of ALGLIB.

        INPUT PARAMETERS:
            A       -   array[0..N-1,0..N-1], system matrix
            N       -   size of A
            B       -   array[0..N-1], right part

        OUTPUT PARAMETERS:
            Info    -   return code:
                        * -3    matrix is exactly singular (ill conditioned matrices
                                are not recognized).
                        * -1    N<=0 was passed
                        *  1    task is solved 
            B       -   array[N]:
                        * info>0    =>  overwritten by solution
                        * info=-3   =>  filled by zeros

          -- ALGLIB --
             Copyright 27.01.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void cmatrixsolvefast(complex[,] a,
            int n,
            complex[] b,
            ref int info)
        {
            int i = 0;
            int j = 0;
            int[] p = new int[0];

            a = (complex[,])a.Clone();
            info = 0;

            if( n<=0 )
            {
                info = -1;
                return;
            }
            trfac.cmatrixlu(ref a, n, n, ref p);
            for(i=0; i<=n-1; i++)
            {
                if( a[i,i]==0 )
                {
                    for(j=0; j<=n-1; j++)
                    {
                        b[j] = 0.0;
                    }
                    info = -3;
                    return;
                }
            }
            cbasiclusolve(a, p, n, b);
            info = 1;
        }
Esempio n. 13
0
        /*************************************************************************
        Complex dense solver for A*X=B with N*N  complex  matrix  A,  N*M  complex
        matrices  X  and  B.  "Fast-but-lightweight" version which  provides  just
        triangular solver - and no additional functions like iterative  refinement
        or condition number estimation.

        Algorithm features:
        * O(N^3+M*N^2) complexity
        * no additional time consuming functions

        COMMERCIAL EDITION OF ALGLIB:

          ! Commercial version of ALGLIB includes two  important  improvements  of
          ! this function, which can be used from C++ and C#:
          ! * Intel MKL support (lightweight Intel MKL is shipped with ALGLIB)
          ! * multicore support
          !
          ! Intel MKL gives approximately constant  (with  respect  to  number  of
          ! worker threads) acceleration factor which depends on CPU  being  used,
          ! problem  size  and  "baseline"  ALGLIB  edition  which  is  used   for
          ! comparison.
          !
          ! Say, on SSE2-capable CPU with N=1024, HPC ALGLIB will be:
          ! * about 2-3x faster than ALGLIB for C++ without MKL
          ! * about 7-10x faster than "pure C#" edition of ALGLIB
          ! Difference in performance will be more striking  on  newer  CPU's with
          ! support for newer SIMD instructions. Generally,  MKL  accelerates  any
          ! problem whose size is at least 128, with best  efficiency achieved for
          ! N's larger than 512.
          !
          ! Commercial edition of ALGLIB also supports multithreaded  acceleration
          ! of this function. We should note that LU decomposition  is  harder  to
          ! parallelize than, say, matrix-matrix  product  -  this  algorithm  has
          ! many internal synchronization points which can not be avoided. However
          ! parallelism starts to be profitable starting  from  N=1024,  achieving
          ! near-linear speedup for N=4096 or higher.
          !
          ! In order to use multicore features you have to:
          ! * use commercial version of ALGLIB
          ! * call  this  function  with  "smp_"  prefix,  which  indicates  that
          !   multicore code will be used (for multicore support)
          !
          ! We recommend you to read 'Working with commercial version' section  of
          ! ALGLIB Reference Manual in order to find out how to  use  performance-
          ! related features provided by commercial edition of ALGLIB.

        INPUT PARAMETERS
            A       -   array[0..N-1,0..N-1], system matrix
            N       -   size of A
            B       -   array[0..N-1,0..M-1], right part
            M       -   right part size

        OUTPUT PARAMETERS:
            Info    -   return code:
                        * -3    matrix is exactly singular (ill conditioned matrices
                                are not recognized).
                        * -1    N<=0 was passed
                        *  1    task is solved 
            B       -   array[N,M]:
                        * info>0    =>  overwritten by solution
                        * info=-3   =>  filled by zeros

          -- ALGLIB --
             Copyright 16.03.2015 by Bochkanov Sergey
        *************************************************************************/
        public static void cmatrixsolvemfast(complex[,] a,
            int n,
            complex[,] b,
            int m,
            ref int info)
        {
            complex v = 0;
            int i = 0;
            int j = 0;
            int k = 0;
            int[] p = new int[0];

            a = (complex[,])a.Clone();
            info = 0;

            
            //
            // Check for exact degeneracy
            //
            if( n<=0 || m<=0 )
            {
                info = -1;
                return;
            }
            trfac.cmatrixlu(ref a, n, n, ref p);
            for(i=0; i<=n-1; i++)
            {
                if( a[i,i]==0 )
                {
                    for(j=0; j<=n-1; j++)
                    {
                        for(k=0; k<=m-1; k++)
                        {
                            b[j,k] = 0.0;
                        }
                    }
                    info = -3;
                    return;
                }
            }
            
            //
            // Solve with TRSM()
            //
            for(i=0; i<=n-1; i++)
            {
                if( p[i]!=i )
                {
                    for(j=0; j<=m-1; j++)
                    {
                        v = b[i,j];
                        b[i,j] = b[p[i],j];
                        b[p[i],j] = v;
                    }
                }
            }
            ablas.cmatrixlefttrsm(n, m, a, 0, 0, false, true, 0, b, 0, 0);
            ablas.cmatrixlefttrsm(n, m, a, 0, 0, true, false, 0, b, 0, 0);
            info = 1;
        }