/// <summary>Computes the Cholesky decomposition of a Hermitian positive-definite matrix, i.e. A = conj(U') * U or A = L * conj(L'), where L is a lower triangular matrix and U is upper triangular.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="a">The matrix A supplied column-by-column of dimension (<paramref name="n"/>; <paramref name="n"/>); overwritten by the upper or lower triangular matrix U, L respectively.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        public void zpotrf(int n, Complex[] a, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            var uplo = LAPACK.GetUplo(triangularMatrixType);

            _zpotrf(ref uplo, ref n, a, ref n, out info);
            CheckForError(info, "zpotrf");
        }
        /// <summary>Computes the Cholesky factorization of a symmetric positive-definite matrix using packed storage, i.e.
        /// A = U' * U or A = L * L', where L is a lower triangular matrix and U is upper triangular.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="aPacked">Either the upper or lower triangular part of matrix A in packed storage, i.e. at least <paramref name="n"/> * (<paramref name="n"/> + 1)/2 elements; overwritten by the upper or lower triangular matrix U, L respectively in packed storage.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        public void dpptrf(int n, double[] aPacked, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            var uplo = LAPACK.GetUplo(triangularMatrixType);

            _dpptrf(ref uplo, ref n, aPacked, out info);
            CheckForError(info, "dpptrf");
        }
        /// <summary>Computes the Bunch-Kaufman factorization of a Hermitian matrix using packed storage, i.e. A = P * U * D * conj(U') * conj(P') or A = P * L * D * conj(L') * conj(P'), where P is a permutation matrix, U and L are upper and
        /// lower triangular matrices with unit diagonal and D is a symmetric block-diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks. U and L have 2-by-2 unit diagonal blocks corresponding to the 2-by-2 blocks of D.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="aPacked">Either the upper or lower triangular part of matrix A in packed storage, i.e. at least <paramref name="n"/> * (<paramref name="n"/> + 1)/2 elements; overwritten by details of the block-diagonal matrix D and the multiplies used to obtain the factor U (or L).</param>
        /// <param name="iPivot">Contains details of the interchanges an the block structure of D, at least <paramref name="n"/> elements (output).</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        public void zhptrf(int n, Complex[] aPacked, int[] iPivot, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            var uplo = LAPACK.GetUplo(triangularMatrixType);

            _zhptrf(ref uplo, ref n, aPacked, iPivot, out info);
            CheckForError(info, "zhptrf");
        }
        /// <summary>Computes the Cholesky factorization of a Hermitian positive-definite band matrix, i.e. i.e. A = conj(U') * U or A = L * conj(L'), where L is a lower triangular matrix and U is upper triangular.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="kd">The number of superdiagonals or subdiagonals in the input matrix.</param>
        /// <param name="a">Either the upper or lower triangular part of the input matrix in band storage of dimension (<paramref name="kd"/> + 1; <paramref name="n"/>); overwritten by the upper or lower triangular matrix U, L respectively.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        public void zpbtrf(int n, int kd, Complex[] a, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            int lda  = kd + 1;
            var uplo = LAPACK.GetUplo(triangularMatrixType);

            _zpbtrf(ref uplo, ref n, ref kd, a, ref lda, out info);
            CheckForError(info, "zpbtrf");
        }
        /// <summary>Computes the Cholesky factorization of a Hermitian positive-definite matrix using the Rectangular Full Packed (RFP) format, i.e.
        /// A = conj(U') * U or A = L * conj(L'), where L is a lower triangular matrix and U is upper triangular.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="a">The matrix A in the RFP format, i.e. an array with at least <paramref name="n"/> * (<paramref name="n"/> + 1) / 2 elements; overwritten by the upper or lower triangular matrix U, L respectively.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        /// <param name="transposeState">A value indicating whether <paramref name="a"/> represents matrix A or its transposed.</param>
        public void zpftrf(int n, Complex[] a, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix, BLAS.MatrixTransposeState transposeState = BLAS.MatrixTransposeState.NoTranspose)
        {
            int info;
            var trans = LAPACK.GetTrans(transposeState);
            var uplo  = LAPACK.GetUplo(triangularMatrixType);

            _zpftrf(ref trans, ref uplo, ref n, a, out info);
            CheckForError(info, "zpftrf");
        }
        /// <summary>Computes the Bunch-Kaufman factorization of a complex Hermitian matrix, i.e. A = P * U * D * conj(U') * conj(P') or A = P * L * D * conj(L') * conj(P'), where P is a permutation matrix, U and L are upper and
        /// lower triangular matrices with unit diagonal and D is a symmetric block-diagonal matrix with 1-by-1 and 2-by-2 diagonal blocks. U and L have 2-by-2 unit diagonal blocks corresponding to the 2-by-2 blocks of D.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="a">The upper or the lower triangular part of the input matrix of dimension (<paramref name="n"/>; <paramref name="n"/>); overwritten by details of the block-diagonal matrix D and the multiplies used to obtain the factor U (or L).</param>
        /// <param name="iPivot">Contains details of the interchanges an the block structure of D, at least <paramref name="n"/> elements (output).</param>
        /// <param name="work">A workspace array of length at least <paramref name="n"/>.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        public void zhetrf(int n, Complex[] a, int[] iPivot, Complex[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            int lwork = work.Length;
            var uplo  = LAPACK.GetUplo(triangularMatrixType);

            _zhetrf(ref uplo, ref n, a, ref n, iPivot, work, ref lwork, out info);
            CheckForError(info, "zhetrf");
        }
示例#7
0
        /// <summary>Performs a rank-1 update of a Hermitian matrix, i.e. A := \alpha * x * conj(x^t) + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements.</param>
        /// <param name="a">The Hermitian matrix A with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void zher(int n, double alpha, Complex[] x, Complex[] a, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }

            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }
            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = alpha * Complex.Conjugate(x[jx - 1]);
                    int     ix   = kx;
                    for (int i = 1; i <= j - 1; i++)
                    {
                        a[i - 1 + (j - 1) * lda] += x[ix - 1] * temp;
                        ix += incX;
                    }
                    a[j - 1 + (j - 1) * lda] = (a[j - 1 + (j - 1) * lda] + x[jx - 1] * temp).Real;

                    jx += incX;
                }
            }
            else
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = alpha * Complex.Conjugate(x[jx - 1]);
                    a[j - 1 + (j - 1) * lda] = (a[j - 1 + (j - 1) * lda] + temp * x[jx - 1]).Real;

                    int ix = jx;
                    for (int i = j + 1; i <= n; i++)
                    {
                        ix += incX;
                        a[i - 1 + (j - 1) * lda] += x[ix - 1] * temp;
                    }
                    jx += incX;
                }
            }
        }
        /// <summary>Performs a rank-1 update of a Hermitian packed matrix, i.e. A := \alpha * x * conjg(x^t) + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements.</param>
        /// <param name="aPacked">The Hermitian packed matrix A with dimension at least (<paramref name="n" /> * (<paramref name="n" /> + 1) ) / 2.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void zhpr(int n, double alpha, Complex[] x, Complex[] aPacked, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }

            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            int kk = 1;

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = alpha * Complex.Conjugate(x[jx - 1]);
                    int     ix   = kx;
                    for (int k = kk; k <= kk + j - 2; k++)
                    {
                        aPacked[k - 1] += x[ix - 1] * temp;
                        ix             += incX;
                    }
                    aPacked[kk + j - 2] = (aPacked[kk + j - 2] + x[jx - 1] * temp).Real;
                    jx += incX;
                    kk += j;
                }
            }
            else
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp = alpha * Complex.Conjugate(x[jx - 1]);

                    aPacked[kk - 1] = (aPacked[kk - 1] + temp * x[jx - 1]).Real;
                    int ix = jx;
                    for (int k = kk + 1; k <= kk + n - j; k++)
                    {
                        ix             += incX;
                        aPacked[k - 1] += x[ix - 1] * temp;
                    }
                    jx += incX;
                    kk  = kk + n - j + 1;
                }
            }
        }
示例#9
0
        /// <summary>Gets the <see cref="System.Char"/> representation of a value indicating whether the lower or upper triangular part of a matrix should take into account.
        /// </summary>
        /// <param name="triangularMatrixType">The type of the triangular matrix.</param>
        /// <returns>The <see cref="System.Char"/> representation of <paramref name="triangularMatrixType"/>.</returns>
        private static char GetUplo(BLAS.TriangularMatrixType triangularMatrixType)
        {
            switch (triangularMatrixType)
            {
            case BLAS.TriangularMatrixType.LowerTriangularMatrix:
                return('L');

            case BLAS.TriangularMatrixType.UpperTriangularMatrix:
                return('U');

            default:
                throw new NotImplementedException();
            }
        }
        /// <summary>Performs a rank-1 update of a symmetric matrix, i.e. A := \alpha * x * x^t + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements.</param>
        /// <param name="a">The symmetric matrix A of dimension (<paramref name="lda" />, <paramref name="n" />) supplied column-by-column (input/output).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void dsyr(int n, double alpha, double[] x, double[] a, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }

            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }
            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    double temp = alpha * x[jx - 1];
                    int    ix   = kx;
                    for (int i = 1; i <= j; i++)
                    {
                        a[i - 1 + (j - 1) * lda] += x[ix - 1] * temp;
                        ix += incX;
                    }
                    jx += incX;
                }
            }
            else
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    double temp = alpha * x[jx - 1];
                    int    ix   = jx;
                    for (int i = j; i <= n; i++)
                    {
                        a[i - 1 + (j - 1) * lda] += x[ix - 1] * temp;
                        ix += incX;
                    }
                    jx += incX;
                }
            }
        }
        /// <summary>Gets a optimal workspace array length for the <c>dsytrf</c> function.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        /// <returns>The optimal workspace array length.</returns>
        /// <remarks>The parameter <paramref name="triangularMatrixType"/> should not have an impact of the calculation of the optimal length of the workspace array.</remarks>
        public int dsytrfQuery(int n, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            var lwork = -1;
            var uplo  = LAPACK.GetUplo(triangularMatrixType);

            unsafe
            {
                double *work = stackalloc double[1];

                int info;
                _dsytrf(ref uplo, ref n, null, ref n, null, work, ref lwork, out info);
                CheckForError(info, "dsytrf");

                return(((int)work[0]) + 1);
            }
        }
        /// <summary>Gets a optimal workspace array length for the <c>zhetrf</c> function.
        /// </summary>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        /// <returns>The optimal workspace array length.</returns>
        /// <remarks>The parameter <paramref name="triangularMatrixType"/> should not have an impact of the calculation of the optimal length of the workspace array.</remarks>
        public int zhetrfQuery(int n, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            var lwork = -1;
            var uplo  = LAPACK.GetUplo(triangularMatrixType);

            unsafe
            {
                Complex *work = stackalloc Complex[1];

                int info;
                _zhetrf(ref uplo, ref n, null, ref n, null, work, ref lwork, out info);
                CheckForError(info, "zhetrf");

                return(((int)work[0].Real) + 1);
            }
        }
        /// <summary>Performs a rank-1 update of a symmetric packed matrix, i.e. A := \alpha * x * x^t + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements.</param>
        /// <param name="aPacked">The symmetric packed matrix A with dimension at least (<paramref name="n" /> * (<paramref name="n" /> + 1) ) / 2.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void dspr(int n, double alpha, double[] x, double[] aPacked, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }

            int kx = 1;
            int kk = 1;

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    double temp = alpha * x[jx - 1];
                    int    ix   = kx;
                    for (int k = kk; k <= kk + j - 1; k++)
                    {
                        aPacked[k - 1] += x[ix - 1] * temp;
                        ix             += incX;
                    }
                    jx += incX;
                    kk += j;
                }
            }
            else
            {
                int jx = kx;
                for (int j = 1; j <= n; j++)
                {
                    double temp = alpha * x[jx - 1];
                    int    ix   = jx;
                    for (int k = kk; k <= kk + n - j; k++)
                    {
                        aPacked[k - 1] += x[ix - 1] * temp;
                        ix             += incX;
                    }
                    jx += incX;
                    kk  = kk + n - j + 1;
                }
            }
        }
        /// <summary>Performs a rank-2 update of a Hermitian packed matrix, i.e. A := \alpha * x * conjg(y^t) + conjg(\alpha) * y * conjg(x^t) + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements.</param>
        /// <param name="y">The vector y with at least 1 + (<paramref name="n" />-1) * |<paramref name="incY" />| elements.</param>
        /// <param name="aPacked">The Hermitian packed matrix A with dimension at least (<paramref name="n" /> * (<paramref name="n" /> + 1) ) / 2.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        /// <param name="incY">The increment for the elements of <paramref name="y" />.</param>
        public void zhpr2(int n, Complex alpha, Complex[] x, Complex[] y, Complex[] aPacked, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1, int incY = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }
            int kx = 1;
            int ky = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }

            if (incY <= 0)
            {
                ky = 1 - (n - 1) * incY;
            }

            int jx = kx;
            int jy = ky;

            int kk = 1;

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * Complex.Conjugate(y[jy - 1]);
                    Complex temp2 = Complex.Conjugate(alpha * x[jx - 1]);
                    int     ix    = kx;
                    int     iy    = ky;
                    for (int k = kk; k <= kk + j - 2; k++)
                    {
                        aPacked[k - 1] = aPacked[k - 1] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                        ix            += incX;
                        iy            += incY;
                    }

                    aPacked[kk + j - 2] = (aPacked[kk + j - 2] + x[jx - 1] * temp1 + y[jy - 1] * temp2).Real;
                    jx += incX;
                    jy += incY;
                    kk += j;
                }
            }
            else
            {
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * Complex.Conjugate(y[jy - 1]);
                    Complex temp2 = Complex.Conjugate(alpha * x[jx - 1]);

                    aPacked[kk - 1] = (aPacked[kk - 1] + x[jx - 1] * temp1 + y[jy - 1] * temp2).Real;

                    int ix = jx;
                    int iy = jy;
                    for (int k = kk + 1; k <= kk + n - j; k++)
                    {
                        ix            += incX;
                        iy            += incY;
                        aPacked[k - 1] = aPacked[k - 1] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                    }
                    jx += incX;
                    jy += incY;
                    kk  = kk + n - j + 1;
                }
            }
        }
示例#15
0
        /// <summary>Performs a rank-2 update of a Hermitian matrix, i.e. A := \alpha * x * conjg(y^t) + conjg(\alpha) * y * conjg(x^t) + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements.</param>
        /// <param name="y">The vector y with at least 1 + (<paramref name="n" />-1) * |<paramref name="incY" />| elements.</param>
        /// <param name="a">The Hermitian matrix A with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        /// <param name="incY">The increment for the elements of <paramref name="y" />.</param>
        public void zher2(int n, Complex alpha, Complex[] x, Complex[] y, Complex[] a, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1, int incY = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }
            int kx = 1;
            int ky = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            if (incY <= 0)
            {
                ky = 1 - (n - 1) * incY;
            }
            int jx = kx;
            int jy = ky;

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * Complex.Conjugate(y[jy - 1]);
                    Complex temp2 = Complex.Conjugate(alpha * x[jx - 1]);
                    int     ix    = kx;
                    int     iy    = ky;

                    for (int i = 1; i <= j; i++)
                    {
                        a[i - 1 + (j - 1) * lda] = a[i - 1 + (j - 1) * lda] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                        ix += incX;
                        iy += incY;
                    }
                    jx += incX;
                    jy += incY;
                }
            }
            else
            {
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * Complex.Conjugate(y[jy - 1]);
                    Complex temp2 = Complex.Conjugate(alpha * x[jx - 1]);

                    a[j - 1 + (j - 1) * lda] = (a[j - 1 + (j - 1) * lda] + x[jx - 1] * temp1 + y[jy - 1] * temp2).Real;

                    int ix = jx;
                    int iy = jy;

                    for (int i = j + 1; i <= n; i++)
                    {
                        ix += incX;
                        iy += incY;
                        a[i - 1 + (j - 1) * lda] = a[i - 1 + (j - 1) * lda] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                    }
                    jx += incX;
                    jy += incY;
                }
            }
        }
示例#16
0
        /// <summary>Solves a system of linear equations whose coefficients are in a triangular matrix, i.e. op(A) * x = b, where op(A) = A or op(A) = A^t.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="a">The triangular matrix A with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="x">The vector b (input), x (output) with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements (input/output).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="transpose">A value indicating whether op(A) = A or op(A) = A^t.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void dtrsv(int n, double[] a, double[] x, int lda, BLAS.TriangularMatrixType triangularMatrixType, bool isUnitTriangular = true, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1)
        {
            if (n == 0)
            {
                return;
            }
            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose) // x := Inv( A ) *x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx + (n - 1) * incX;
                    for (int j = n; j >= 1; j--)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[j - 1 + (j - 1) * lda];
                        }
                        double temp = x[jx - 1];
                        int    ix   = jx;
                        for (int i = j - 1; i >= 1; i--)
                        {
                            ix        -= incX;
                            x[ix - 1] -= temp * a[i - 1 + (j - 1) * lda];
                        }
                        jx -= incX;
                    }
                }
                else
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[j - 1 + (j - 1) * lda];
                        }
                        double temp = x[jx - 1];
                        int    ix   = jx;
                        for (int i = j + 1; i <= n; i++)
                        {
                            ix        += incX;
                            x[ix - 1] -= temp * a[i - 1 + (j - 1) * lda];
                        }
                        jx += incX;
                    }
                }
            }
            else  // x := Inv( A' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        double temp = x[jx - 1];
                        int    ix   = kx;
                        for (int i = 1; i <= j - 1; i++)
                        {
                            temp -= a[i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[j - 1 + (j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                    }
                }
                else
                {
                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        double temp = x[jx - 1];
                        int    ix   = kx;
                        for (int i = n; i >= j + 1; i--)
                        {
                            temp -= a[i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[j - 1 + (j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                    }
                }
            }
        }
 /// <summary>Creates a n x r matrix B such that B * B^t is a correlation matrix and "near" to the specified symmetric, normalized matrix of dimension n. A rank reduction will apply if r is strict less than n.
 /// </summary>
 /// <param name="rawCorrelationMatrix">The symmetric, normalized matrix where to find the 'nearest' correlation matrix.</param>
 /// <param name="state">The state of the operation in its <see cref="PseudoSqrtMatrixDecomposer.State"/> representation (output).</param>
 /// <param name="outputEntries">This argument will be used to store the matrix entries of the resulting matrix B, i.e. the return value array points to this array if != <c>null</c>; otherwise a memory allocation will be done.</param>
 /// <param name="worksspaceContainer">A specific <see cref="PseudoSqrtMatrixDecomposer.WorkspaceContainer"/> object to reduce memory allocation; ignored if <c>null</c>.</param>
 /// <param name="triangularMatrixType">A value indicating which part of <paramref name="rawCorrelationMatrix"/> to take into account.</param>
 /// <returns>A <see cref="DenseMatrix"/> object that represents a matrix B such that B * B^t is the "nearest" correlation matrix with respect to <paramref name="rawCorrelationMatrix"/>.</returns>
 /// <remarks>In general the return object does <b>not</b> represents the pseudo-root of <paramref name="rawCorrelationMatrix"/>, i.e. output of the Cholesky decomposition.
 /// <para>The parameters <paramref name="outputEntries"/>, <paramref name="worksspaceContainer"/> allows to avoid memory allocation and to re-use arrays if the calculation of correlation matrices will be done often.</para></remarks>
 public abstract DenseMatrix Create(DenseMatrix rawCorrelationMatrix, out State state, double[] outputEntries = null, WorkspaceContainer worksspaceContainer = null, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix);
 public double zlansp(MatrixNormType matrixNormType, int n, Complex[] ap, Complex[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
 {
     throw new NotImplementedException();
 }
        /// <summary>Solves a system of linear equations whose coefficients are in a triangular band matrix, i.e. op(A) * x = b, where op(A) = A, op(A) = A ^t or op(A) = A^h.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="k">The number of super-diagonals of A if the matrix A is provided in its upper triangular representation; the number of sub-diagonals otherwise.</param>
        /// <param name="a">The triangular band matrix with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="x">The vector b (input), x (output) with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements (input/output).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least (1  + <paramref name="k" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A', 'op(A)=A^t' or 'op(A)=A^h'.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void ztbsv(int n, int k, Complex[] a, Complex[] x, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, bool isUnitTriangular = true, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1)
        {
            if (n == 0)
            {
                return;
            }
            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // x := Inv( A ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        kx -= incX;
                        int ix  = kx;
                        int ell = k + 1 - j;
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[k + (j - 1) * lda];
                        }
                        Complex temp = x[jx - 1];

                        for (int i = j - 1; i >= Math.Max(1, j - k); i--)
                        {
                            x[ix - 1] -= temp * a[ell + i - 1 + (j - 1) * lda];
                            ix        -= incX;
                        }
                        jx -= incX;
                    }
                }
                else
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        kx += incX;
                        int ix  = kx;
                        int ell = 1 - j;
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= a[(j - 1) * lda];
                        }
                        Complex temp = x[jx - 1];

                        for (int i = j + 1; i <= Math.Min(n, j + k); i++)
                        {
                            x[ix - 1] -= temp * a[ell + i - 1 + (j - 1) * lda];
                            ix        += incX;
                        }
                        jx += incX;
                    }
                }
            }
            else if (transpose == BLAS.MatrixTransposeState.Transpose) // x := Inv( A' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        int     ell  = k + 1 - j;

                        for (int i = Math.Max(1, j - k); i <= j - 1; i++)
                        {
                            temp -= a[ell + i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[k + (j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        if (j > k)
                        {
                            kx += incX;
                        }
                    }
                }
                else
                {
                    kx += (n - 1) * incX;
                    int jx = kx;

                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        int     ell  = 1 - j;

                        for (int i = Math.Min(n, j + k); i >= j + 1; i--)
                        {
                            temp -= a[ell + i - 1 + (j - 1) * lda] * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= a[(j - 1) * lda];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        if (n - j >= k)
                        {
                            kx -= incX;
                        }
                    }
                }
            }
            else // x := Inv( conj(A)' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        int     ell  = k + 1 - j;

                        for (int i = Math.Max(1, j - k); i <= j - 1; i++)
                        {
                            temp -= Complex.Conjugate(a[ell + i - 1 + (j - 1) * lda]) * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(a[k + (j - 1) * lda]);
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        if (j > k)
                        {
                            kx += incX;
                        }
                    }
                }
                else
                {
                    kx += (n - 1) * incX;
                    int jx = kx;

                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        int     ell  = 1 - j;

                        for (int i = Math.Min(n, j + k); i >= j + 1; i--)
                        {
                            temp -= Complex.Conjugate(a[ell + i - 1 + (j - 1) * lda]) * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(a[(j - 1) * lda]);
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        if (n - j >= k)
                        {
                            kx -= incX;
                        }
                    }
                }
            }
        }
        /// <summary>Solves a system of linear equations whose coefficients are in a triangular packed matrix, i.e. op(A) * x = b, where op(A) = A, op(A) = A ^t or op(A) = A^h.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="aPacked">The triangular packed matrix A with dimension at least (<paramref name="n" /> * (<paramref name="n" /> + 1) ) / 2.</param>
        /// <param name="x">The vector b (input), x (output) with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements (input/output).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A', 'op(A)=A^t' or 'op(A)=A^h'.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        public void ztpsv(int n, Complex[] aPacked, Complex[] x, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, bool isUnitTriangular = true, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose, int incX = 1)
        {
            if (n == 0)
            {
                return;
            }

            int kx = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            else if (incX != 1)
            {
                kx = 1;
            }

            if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // x := Inv( A ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = n * (n + 1) / 2;

                    int jx = kx + (n - 1) * incX;
                    for (int j = n; j >= 1; j--)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= aPacked[kk - 1];
                        }
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        for (int k = kk - 1; k >= kk - j + 1; k--)
                        {
                            ix        -= incX;
                            x[ix - 1] -= temp * aPacked[k - 1];
                        }
                        jx -= incX;
                        kk -= j;
                    }
                }
                else
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        if (isUnitTriangular == false)
                        {
                            x[jx - 1] /= aPacked[kk - 1];
                        }
                        Complex temp = x[jx - 1];
                        int     ix   = jx;
                        for (int k = kk + 1; k <= kk + n - j; k++)
                        {
                            ix        += incX;
                            x[ix - 1] -= temp * aPacked[k - 1];
                        }
                        jx += incX;
                        kk += n - j + 1;
                    }
                }
            }
            else if (transpose == BLAS.MatrixTransposeState.Transpose) // x := Inv( A' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k <= kk + j - 2; k++)
                        {
                            temp -= aPacked[k - 1] * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= aPacked[kk + j - 2];
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        kk       += j;
                    }
                }
                else
                {
                    int kk = n * (n + 1) / 2;

                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k >= kk - (n - (j + 1)); k--)
                        {
                            temp -= aPacked[k - 1] * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= aPacked[kk - n + j - 1];
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        kk       -= n - j + 1;
                    }
                }
            }
            else   // x := Inv( Conj(A)' ) * x
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    int kk = 1;

                    int jx = kx;
                    for (int j = 1; j <= n; j++)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k <= kk + j - 2; k++)
                        {
                            temp -= Complex.Conjugate(aPacked[k - 1]) * x[ix - 1];
                            ix   += incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(aPacked[kk + j - 2]);
                        }
                        x[jx - 1] = temp;
                        jx       += incX;
                        kk       += j;
                    }
                }
                else
                {
                    int kk = n * (n + 1) / 2;

                    kx += (n - 1) * incX;
                    int jx = kx;
                    for (int j = n; j >= 1; j--)
                    {
                        Complex temp = x[jx - 1];
                        int     ix   = kx;
                        for (int k = kk; k >= kk - (n - (j + 1)); k--)
                        {
                            temp -= Complex.Conjugate(aPacked[k - 1]) * x[ix - 1];
                            ix   -= incX;
                        }
                        if (isUnitTriangular == false)
                        {
                            temp /= Complex.Conjugate(aPacked[kk - n + j - 1]);
                        }
                        x[jx - 1] = temp;
                        jx       -= incX;
                        kk       -= n - j + 1;
                    }
                }
            }
        }
示例#21
0
        /// <summary>Performs a symmetric rank-2k update, i.e. C := alpha*A*B^t + alpha*B*A^t + beta*C or C := alpha*A^t*B + alpha*B^t*A + beta*C with a symmetric matrix C.
        /// </summary>
        /// <param name="n">The order of matrix C.</param>
        /// <param name="k">The The number of columns of matrices A and B or the number .</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The matrix A supplied column-by-column of dimension (<paramref name="lda" />, ka), where ka is <paramref name="k" /> if to calculate C := alpha*A*B^t + alpha*B*A^t + beta*C; otherwise <paramref name="n" />.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb" />, kb), where ka is at least max(1,<paramref name="n" />) if to calculate C := alpha*A*B^t + alpha*B*A^t + beta*C; otherwise at least max(1,<paramref name="k" />).</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="c">The symmetric matrix C supplied column-by-column of dimension (<paramref name="ldc" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1,<paramref name="n" />) if to calculate C:= alpha*A*B^t+alpha*B*A^t+beta*C; max(1,<paramref name="k" />) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b" />, must be at least max(1,<paramref name="n" />) if to calculate C:= alpha*A*B^t+alpha*B*A^t+beta*C; max(1,<paramref name="k" />) otherwise.</param>
        /// <param name="ldc">The leading dimension of <paramref name="c" />, must be at least max(1,<paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix C is in its upper or lower triangular representation.</param>
        /// <param name="operation">A value indicating whether to calculate C := alpha*A*B^t + alpha*B*A^t + beta*C or C := alpha*A^t*B + alpha*B^t*A + beta*C.</param>
        public void zsyr2k(int n, int k, Complex alpha, Complex[] a, Complex[] b, Complex beta, Complex[] c, int lda, int ldb, int ldc, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.Xsyr2kOperation operation = BLAS.Xsyr2kOperation.ATimesBTransPlusBTimesATrans)
        {
            if (operation == BLAS.Xsyr2kOperation.ATimesBTransPlusBTimesATrans)  // C := \alpha * A*B' + \alpha * B *A' +C
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i <= j; i++)
                        {
                            c[i + j * ldc] *= beta;
                        }
                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp  = alpha * b[j + ell * ldb];
                            Complex temp2 = alpha * a[j + ell * lda];
                            for (int i = 0; i <= j; i++)
                            {
                                c[i + j * ldc] += b[i + ell * ldb] * temp2 + a[i + ell * lda] * temp;
                            }
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = j; i < n; i++)
                        {
                            c[i + j * ldc] *= beta;
                        }
                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp  = alpha * b[j + ell * ldb];
                            Complex temp2 = alpha * a[j + ell * lda];

                            for (int i = j; i < n; i++)
                            {
                                c[i + j * ldc] += a[i + ell * lda] * temp + b[i + ell * ldb] * temp2;
                            }
                        }
                    }
                }
            }
            else  // C := \alpha * A' * B + \alpha * B' * A + C.
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i <= j; i++)
                        {
                            Complex temp  = 0.0;
                            Complex temp2 = 0.0;
                            for (int ell = 0; ell < k; ell++)
                            {
                                temp  += a[ell + i * lda] * b[ell + j * ldb];
                                temp2 += b[ell + i * ldb] * a[ell + j * lda];
                            }
                            c[i + j * ldc] = alpha * temp2 + alpha * temp + beta * c[i + j * ldc];
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = j; i < n; i++)
                        {
                            Complex temp  = 0.0;
                            Complex temp2 = 0.0;

                            for (int ell = 0; ell < k; ell++)
                            {
                                temp  += a[ell + i * lda] * b[ell + j * ldb];
                                temp2 += b[ell + i * ldb] * a[ell + j * lda];
                            }
                            c[i + j * ldc] = alpha * temp2 + alpha * temp + beta * c[i + j * ldc];
                        }
                    }
                }
            }
        }
示例#22
0
        /// <summary>Computes a matrix-vector product using a Hermitian matrix, i.e. y := \alpha * A * x + \beta * y.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" />-1) * |<paramref name="incX" />| elements.</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="y">The vector y with at least 1 + (<paramref name="n" />-1) * |<paramref name="incY" />| elements (input/output).</param>
        /// <param name="a">The Hermitian matrix A with dimension (<paramref name="lda" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        /// <param name="incY">The increment for the elements of <paramref name="y" />.</param>
        public void zhemv(int n, Complex alpha, Complex[] x, Complex beta, Complex[] y, Complex[] a, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1, int incY = 1)
        {
            if (n == 0 || alpha == 0.0 && beta == 1.0)
            {
                return;
            }

            int kx = 1;
            int ky = 1;

            if (incX <= 0)
            {
                kx = 1 - (n - 1) * incX;
            }
            if (incY <= 0)
            {
                ky = 1 - (n - 1) * incY;
            }

            /* calculate y := \beta * y:*/
            int iy = ky;

            for (int i = 1; i <= n; i++)
            {
                y[iy - 1] = beta * y[iy - 1];
                iy       += incY;
            }

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                int jx = kx;
                int jy = ky;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * x[jx - 1];
                    Complex temp2 = 0.0;
                    int     ix    = kx;
                    iy = ky;
                    for (int i = 1; i <= j - 1; i++)
                    {
                        y[iy - 1] += temp1 * a[i - 1 + (j - 1) * lda];
                        temp2     += Complex.Conjugate(a[i - 1 + (j - 1) * lda]) * x[ix - 1];
                        ix        += incX;
                        iy        += incY;
                    }
                    y[jy - 1] = y[jy - 1] + temp1 * a[j - 1 + (j - 1) * lda] + alpha * temp2;
                    jx       += incX;
                    jy       += incY;
                }
            }
            else
            {
                int jx = kx;
                int jy = ky;
                for (int j = 1; j <= n; j++)
                {
                    Complex temp1 = alpha * x[jx - 1];
                    Complex temp2 = 0.0;
                    y[jy - 1] += temp1 * a[j - 1 + (j - 1) * lda];
                    int ix = jx;
                    iy = jy;

                    for (int i = j + 1; i <= n; i++)
                    {
                        ix        += incX;
                        iy        += incY;
                        y[iy - 1] += temp1 * a[i - 1 + (j - 1) * lda];
                        temp2     += Complex.Conjugate(a[i - 1 + (j - 1) * lda]) * x[ix - 1];
                    }
                    y[jy - 1] += alpha * temp2;
                    jx        += incX;
                    jy        += incY;
                }
            }
        }
示例#23
0
        /// <summary>Creates a 'n x r' matrix B such that B * B' is a correlation matrix and 'near' to the specified symmetric, normalized matrix of dimension n. A rank reduction will apply if r is strict less than n.
        /// </summary>
        /// <param name="rawCorrelationMatrix">The symmetric, normalized matrix where to find the 'nearest' correlation matrix.</param>
        /// <param name="state">The state of the operation in its <see cref="PseudoSqrtMatrixDecomposer.State"/> representation (output).</param>
        /// <param name="triangularMatrixType">A value indicating which part of <paramref name="rawCorrelationMatrix"/> to take into account.</param>
        /// <param name="outputEntries">This argument will be used to store the matrix entries of the resulting matrix B, i.e. the return value array points to this array if != <c>null</c>; otherwise a memory allocation will be done.</param>
        /// <param name="worksspaceContainer">A specific <see cref="PseudoSqrtMatrixDecomposer.WorkspaceContainer"/> object to reduce memory allocation; ignored if <c>null</c>.</param>
        /// <returns>A <see cref="DenseMatrix"/> object that represents a matrix B such that B * B' is the 'nearest' correlation matrix with respect to <paramref name="rawCorrelationMatrix"/>.</returns>
        /// <remarks>In general the return object does <b>not</b> represents the pseudo-root of <paramref name="rawCorrelationMatrix"/>, i.e. output of the Cholesky decomposition.
        /// <para>The parameters <paramref name="outputEntries"/>, <paramref name="worksspaceContainer"/> allows to avoid memory allocation and to re-use arrays if the calculation of correlation matrices will be done often.</para></remarks>
        public override DenseMatrix Create(DenseMatrix rawCorrelationMatrix, out State state, double[] outputEntries = null, PseudoSqrtMatrixDecomposer.WorkspaceContainer worksspaceContainer = null, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            if (rawCorrelationMatrix.IsQuadratic == false)
            {
                throw new ArgumentException("rawCorrelationMatrix");
            }
            int n = rawCorrelationMatrix.RowCount;

            if ((outputEntries == null) || (outputEntries.Length < n * n))
            {
                outputEntries = new double[n * n];
            }
            var ws = worksspaceContainer as Workspace;

            if ((ws == null) || (ws.Dimension < n))
            {
                ws = new Workspace(n);
            }

            int m;

            BLAS.Level1.dcopy(n * n, rawCorrelationMatrix.Data, ws.data);
            LAPACK.EigenValues.Symmetric.driver_dsyevr(LapackEigenvalues.SymmetricGeneralJob.All, n, ws.data, out m, ws.eigenValues, outputEntries, ws.isuppz, ws.work, ws.iwork);
            var originalEigenValueDataTable = InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) ? CreateDataTableWithEigenvalues("Eigenvalues.Original", m, ws.eigenValues) : null;

            int rank = n;
            int minNumberOfEigenvaluesToSetZero = n - Math.Min(MaximalRank ?? n, n);
            int i = 0;

            while ((i < minNumberOfEigenvaluesToSetZero) || (ws.eigenValues[i] < 0.0))
            {
                ws.eigenValues[i] = 0.0;
                i++;
                rank--;
            }
            var adjustedEigenValueDataTable = InfoOutputDetailLevel.IsAtLeastAsComprehensiveAs(InfoOutputDetailLevel.High) ? CreateDataTableWithEigenvalues("Eigenvalues.Adjusted", m, ws.eigenValues) : null;

            VectorUnit.Basics.Sqrt(n, ws.eigenValues); // calculate sqrt of eigenvalues only once, i.e. the array 'eigenValues' contains the sqrt of the eigenvalues!
            for (i = 0; i < n; i++)
            {
                var t_i = 0.0;
                for (int j = n - 1; j >= n - rank; j--)
                {
                    t_i += outputEntries[i + j * n] * outputEntries[i + j * n] * ws.eigenValues[j] * ws.eigenValues[j];
                    outputEntries[i + j * n] *= ws.eigenValues[j];
                }
                BLAS.Level1.dscal(rank, 1.0 / Math.Sqrt(t_i), outputEntries, -n, i + (n - 1) * n); // [i+j*n] *= 1/Math.Sqrt(tempValue) for j = n-1, ..., n-rank
            }

            /* The eigenvalues are in ascending order. Thefore the first (and not last) 'rank' columns of the eigenvectors are not required. Therefore we swap the relevant part  */
            BLAS.Level1.dscal(n * (n - rank), 0.0, outputEntries);
            BLAS.Level1.dswap(n * rank, outputEntries, 1, outputEntries, 1, n * (n - rank), 0);

            state = State.Create(rank, detailProperties: new[] { InfoOutputProperty.Create("Eigenvalues set to 0.0", n - rank) }, detailDataTables: new[] { originalEigenValueDataTable, adjustedEigenValueDataTable }, iterationsNeeded: 1, infoOutputDetailLevel: InfoOutputDetailLevel);
            return(new DenseMatrix(n, rank, outputEntries));
        }
        /// <summary>Computes a matrix-matrix product where one input matrix is triangular, i.e. B := \alpha * op(A)*B or B:= \alpha *B * op(A), where A is a unit or non-unit upper or lower triangular matrix.
        /// </summary>
        /// <param name="m">The number of rows of matrix B.</param>
        /// <param name="n">The number of columns of matrix B.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The triangular matrix A supplied column-by-column of dimension (<paramref name="lda"/>, k), where k is <paramref name="m"/> if to calculate B := \alpha * op(A)*B; <paramref name="n"/> otherwise.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb"/>, <paramref name="n"/>).</param>
        /// <param name="lda">The leading dimension of <paramref name="a"/>, must be at least max(1,<paramref name="m"/>) if to calculate B := \alpha * op(A)*B; max(1,<paramref name="n"/>) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b"/>, must be at least max(1,<paramref name="m"/>).</param>
        /// <param name="isUnitTriangular">A value indicating whether the matrix A is unit triangular.</param>
        /// <param name="side">A value indicating whether to calculate B := \alpha * op(A)*B or B:= \alpha *B * op(A).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="transpose">A value indicating whether 'op(A)=A' or 'op(A)=A^t'.</param>
        public void dtrmm(int m, int n, double alpha, double[] a, double[] b, int lda, int ldb, bool isUnitTriangular = true, BLAS.Side side = BLAS.Side.Left, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.MatrixTransposeState transpose = BLAS.MatrixTransposeState.NoTranspose)
        {
            if (n == 0)
            {
                return; // nothing to do
            }
            if (side == BLAS.Side.Left)
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // B = \alpha *A*B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int k = 0; k < m; k++)
                            {
                                double temp = alpha * b[k + j * ldb];
                                for (int i = 0; i <= k - 1; i++)
                                {
                                    b[i + j * ldb] += temp * a[i + k * lda];
                                }
                                if (isUnitTriangular == false)
                                {
                                    temp *= a[k + k * lda];
                                }
                                b[k + j * ldb] = temp;
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int k = m - 1; k >= 0; k--)
                            {
                                double temp = alpha * b[k + j * ldb];
                                b[k + j * ldb] = temp;
                                if (isUnitTriangular == false)
                                {
                                    b[k + j * ldb] *= a[k + k * lda];
                                }
                                for (int i = k + 1; i < m; i++)
                                {
                                    b[i + j * ldb] += temp * a[i + k * lda];
                                }
                            }
                        }
                    }
                }
                else  // B = \alpha * A' *B
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = m - 1; i >= 0; i--)
                            {
                                double temp = b[i + j * ldb];
                                if (isUnitTriangular == false)
                                {
                                    temp *= a[i + i * lda];
                                }
                                for (int k = 0; k <= i - 1; k++)
                                {
                                    temp += a[k + i * lda] * b[k + j * ldb];
                                }
                                b[i + j * ldb] = alpha * temp;
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int j = 0; j < n; j++)
                        {
                            for (int i = 0; i < m; i++)
                            {
                                double temp = b[i + j * ldb];
                                if (isUnitTriangular == false)
                                {
                                    temp *= a[i + i * lda];
                                }
                                for (int k = i + 1; k < m; k++)
                                {
                                    temp += a[k + i * lda] * b[k + j * ldb];
                                }
                                b[i + j * ldb] = alpha * temp;
                            }
                        }
                    }
                }
            }
            else  // side == BLAS.Side.Right
            {
                if (transpose == BLAS.MatrixTransposeState.NoTranspose)  // B = \alpha * B * A
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int j = n - 1; j >= 0; j--)
                        {
                            double temp = alpha;
                            if (isUnitTriangular == false)
                            {
                                temp *= a[j + j * lda];
                            }
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = temp * b[i + j * ldb];
                            }
                            for (int k = 0; k <= j - 1; k++)
                            {
                                temp = alpha * a[k + j * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] += temp * b[i + k * ldb];
                                }
                            }
                        }
                    }
                    else
                    {
                        for (int j = 0; j < n; j++)
                        {
                            double temp = alpha;
                            if (isUnitTriangular == false)
                            {
                                temp *= a[j + j * lda];
                            }
                            for (int i = 0; i < m; i++)
                            {
                                b[i + j * ldb] = temp * b[i + j * ldb];
                            }

                            for (int k = j + 1; k < n; k++)
                            {
                                temp = alpha * a[k + j * lda];

                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] += temp * b[i + k * ldb];
                                }
                            }
                        }
                    }
                }
                else  // B = \alpha * B * A'
                {
                    if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                    {
                        for (int k = 0; k < n; k++)
                        {
                            double temp;
                            for (int j = 0; j < k; j++)
                            {
                                temp = alpha * a[j + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] += temp * b[i + k * ldb];
                                }
                            }

                            temp = alpha;
                            if (isUnitTriangular == false)
                            {
                                temp *= a[k + k * lda];
                            }
                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = temp * b[i + k * ldb];
                            }
                        }
                    }
                    else  // lower triangular matrix
                    {
                        for (int k = n - 1; k >= 0; k--)
                        {
                            double temp;

                            for (int j = k + 1; j < n; j++)
                            {
                                temp = alpha * a[j + k * lda];
                                for (int i = 0; i < m; i++)
                                {
                                    b[i + j * ldb] += temp * b[i + k * ldb];
                                }
                            }

                            temp = alpha;
                            if (isUnitTriangular == false)
                            {
                                temp *= a[k + k * lda];
                            }
                            for (int i = 0; i < m; i++)
                            {
                                b[i + k * ldb] = temp * b[i + k * ldb];
                            }
                        }
                    }
                }
            }
        }
示例#25
0
        /// <summary>Computes the Cholesky decomposition with complete pivoting of a complex Hermitian positive-definite matrix, i.e. P' * A * P = U' * U or P' * A * P = L * L', where L is a lower triangular matrix and U is upper triangular.
        /// </summary>
        /// <param name="matrixFactorization">The <see cref="LapackLinearEquations.IMatrixFactorization"/> object.</param>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="a">The matrix A supplied column-by-column of dimension (<paramref name="n"/>; <paramref name="n"/>); overwritten by the upper or lower triangular matrix U, L respectively.</param>
        /// <param name="pivot">The nonzero entries of permutation matrix P, i.e. P( pivot(k) , k ) = 1 for k = 1,.., <paramref name="n"/> - 1 (output).</param>
        /// <param name="work">A workspace array of length at least 2 * <paramref name="n"/>.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of matrix A is stored and how matrix A is factored.</param>
        /// <param name="tolerance">The tolerance for the termination condition of the algorithm, i.e. if pivot elements &lt; <paramref name="tolerance"/>.</param>
        /// <returns>The rank of <paramref name="a"/> given by the number of steps the algorithm completed.</returns>
        public static int zpstrf(this LapackLinearEquations.IMatrixFactorization matrixFactorization, int n, Complex[] a, int[] pivot, Complex[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix, double tolerance = MachineConsts.Epsilon)
        {
            int info;
            int lda  = Math.Max(1, n);
            var uplo = GetUplo(triangularMatrixType);

            int rank;

            _zpstrf(ref uplo, ref n, a, ref lda, pivot, out rank, ref tolerance, work, out info);
            CheckForError(info, "zpstrf");
            return(rank);
        }
        /// <summary>Computes a matrix-matrix product where one input matrix is symmetric, i.e. C := \alpha*A*B + \beta*C or C := \alpha*B*A +\beta*C.
        /// </summary>
        /// <param name="m">The number of rows of the matrix C.</param>
        /// <param name="n">The number of columns of the matrix C.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The symmetric matrix A supplied column-by-column of dimension (<paramref name="lda" />, ka), where ka is <paramref name="m" /> if to calculate C := \alpha * A*B + \beta*C; otherwise <paramref name="n" />.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb" />,<paramref name="n" />).</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="c">The matrix C supplied column-by-column of dimension (<paramref name="ldc" />,<paramref name="n" />); input/output.</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1,<paramref name="m" />) if <paramref name="side" />=left; max(1,n) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b" />, must be at least max(1,<paramref name="m" />).</param>
        /// <param name="ldc">The leading dimension of <paramref name="c" />, must be at least max(1,<paramref name="m" />).</param>
        /// <param name="side">A value indicating whether to calculate C := \alpha * A*B + \beta*C or C := \alpha * B*A +\beta*C.</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        public void zsymm(int m, int n, Complex alpha, Complex[] a, Complex[] b, Complex beta, Complex[] c, int lda, int ldb, int ldc, BLAS.Side side = BLAS.Side.Left, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix)
        {
            if (side == BLAS.Side.Left) // C := \alpha *A*B + \beta * C
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i < m; i++)
                        {
                            Complex temp  = alpha * b[i + j * ldb];
                            Complex temp2 = 0.0;

                            for (int k = 0; k <= i - 1; k++)
                            {
                                c[k + j * ldc] += temp * a[k + i * lda];
                                temp2          += b[k + j * ldb] * a[k + i * lda];
                            }
                            c[i + j * ldc] = alpha * temp2 + temp * a[i + i * lda] + beta * c[i + j * ldc];
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = m - 1; i >= 0; i--)
                        {
                            Complex temp  = alpha * b[i + j * ldb];
                            Complex temp2 = 0.0;
                            for (int k = i + 1; k < m; k++)
                            {
                                c[k + j * ldc] += temp * a[k + i * lda];
                                temp2          += b[k + j * ldb] * a[k + i * lda];
                            }
                            c[i + j * ldc] = alpha * temp2 + temp * a[i + i * lda] + beta * c[i + j * ldc];
                        }
                    }
                }
            }
            else // C := \alpha * B * A + \beta * C
            {
                for (int j = 0; j < n; j++)
                {
                    Complex temp = alpha * a[j + j * lda];
                    for (int i = 0; i < m; i++)
                    {
                        c[i + j * ldc] = temp * b[i + j * ldb] + beta * c[i + j * ldc];
                    }
                    for (int k = 0; k <= j - 1; k++)
                    {
                        if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                        {
                            temp = alpha * a[k + j * lda];
                        }
                        else
                        {
                            temp = alpha * a[j + k * lda];
                        }
                        for (int i = 0; i < m; i++)
                        {
                            c[i + j * ldc] = c[i + j * ldc] + temp * b[i + k * ldb];
                        }
                    }

                    for (int k = j + 1; k < n; k++)
                    {
                        if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                        {
                            temp = alpha * a[j + k * lda];
                        }
                        else
                        {
                            temp = alpha * a[k + j * lda];
                        }
                        for (int i = 0; i < m; i++)
                        {
                            c[i + j * ldc] = c[i + j * ldc] + temp * b[i + k * ldb];
                        }
                    }
                }
            }
        }
示例#27
0
        /// <summary>Performs a Hermitian rank-2 update, i.e. C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C or C := \alpha*B^h*A + conjg(\alpha)*A^h*B + beta*C, where C is an Hermitian matrix.
        /// </summary>
        /// <param name="n">The order of matrix C.</param>
        /// <param name="k">The number of columns of matrix A if to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C; the number of rows of the matrix A otherwise.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="a">The matrix A supplied column-by-column of dimension (<paramref name="lda" />, ka), where ka equals to <paramref name="k" /> if to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C; <paramref name="n" /> otherwise.</param>
        /// <param name="b">The matrix B supplied column-by-column of dimension (<paramref name="ldb" />, kb), where kb equals to <paramref name="k" /> if to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C; <paramref name="n" /> otherwise.</param>
        /// <param name="beta">The scalar \beta.</param>
        /// <param name="c">The Hermitian matrix C supplied column-by-column of dimension (<paramref name="ldc" />, <paramref name="n" />).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1,<paramref name="n" />) if to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C; max(1, <paramref name="k" />) otherwise.</param>
        /// <param name="ldb">The leading dimension of <paramref name="b" />, must be at least max(1,<paramref name="n" />) if to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C; max(1, <paramref name="k" />) otherwise.</param>
        /// <param name="ldc">The leading dimension of <paramref name="c" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix C is in its upper or lower triangular representation.</param>
        /// <param name="operation">A value indicating whether to calculate C := \alpha*A*B^h + conjg(\alpha)*B*A^h + \beta * C or C := \alpha*B^h*A + conjg(\alpha)*A^h*B + beta*C.</param>
        public void zher2k(int n, int k, Complex alpha, Complex[] a, Complex[] b, double beta, Complex[] c, int lda, int ldb, int ldc, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.Zher2kOperation operation = BLAS.Zher2kOperation.ATimesBHermitePlusBTimesAHermite)
        {
            if (n == 0 || ((alpha == 0.0 || k == 0) && (beta == 1.0)))
            {
                return; // nothing to do
            }

            if (operation == BLAS.Zher2kOperation.ATimesBHermitePlusBTimesAHermite)  // C := \alpha * A*conjg(B') + conjg(\alpha) *B*conjg(A') + \beta * C
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i <= j - 1; i++)
                        {
                            c[i + j * ldc] *= beta;
                        }
                        c[j + j * ldc] = beta * c[j + j * ldc].Real;

                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp  = alpha * Complex.Conjugate(b[j + ell * ldb]);
                            Complex temp2 = Complex.Conjugate(alpha * a[j + ell * lda]);

                            for (int i = 0; i <= j - 1; i++)
                            {
                                c[i + j * ldc] += a[i + ell * lda] * temp + b[i + ell * ldb] * temp2;
                            }
                            c[j + j * ldc] += a[j + ell * lda] * temp + b[j + ell * ldb] * temp2;
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = j + 1; i < n; i++)
                        {
                            c[i + j * ldc] *= beta;
                        }
                        c[j + j * ldc] = beta * c[j + j * ldc].Real;

                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp  = alpha * Complex.Conjugate(b[j + ell * ldb]);
                            Complex temp2 = Complex.Conjugate(alpha * a[j + ell * lda]);

                            for (int i = j + 1; i < n; i++)
                            {
                                c[i + j * ldc] += a[i + ell * lda] * temp + b[i + ell * ldb] * temp2;
                            }
                            c[j + j * ldc] += a[j + ell * lda] * temp + b[j + ell * ldb] * temp2;
                        }
                    }
                }
            }
            else  // C := \alpha * conjg(A')*B + conjg(\alpha) * conjg(B')*A + C
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i <= j; i++)
                        {
                            Complex temp  = 0.0;
                            Complex temp2 = 0.0;

                            for (int ell = 0; ell < k; ell++)
                            {
                                temp  += Complex.Conjugate(a[ell + i * lda]) * b[ell + j * ldb];
                                temp2 += Complex.Conjugate(b[ell + i * ldb]) * a[ell + j * lda];
                            }

                            if (i == j)
                            {
                                c[j + j * ldc] = (beta * c[j + j * ldc] + alpha * temp + Complex.Conjugate(alpha) * temp2).Real;
                            }
                            else
                            {
                                c[i + j * ldc] = beta * c[i + j * ldc] + alpha * temp + Complex.Conjugate(alpha) * temp2;
                            }
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = j; i < n; i++)
                        {
                            Complex temp  = 0.0;
                            Complex temp2 = 0.0;

                            for (int ell = 0; ell < k; ell++)
                            {
                                temp  += Complex.Conjugate(a[ell + i * lda]) * b[ell + j * ldb];
                                temp2 += Complex.Conjugate(b[ell + i * ldb]) * a[ell + j * lda];
                            }

                            if (i == j)
                            {
                                c[j + j * ldc] = (beta * c[j + j * ldc] + alpha * temp + Complex.Conjugate(alpha) * temp2).Real;
                            }
                            else
                            {
                                c[i + j * ldc] = beta * c[i + j * ldc] + alpha * temp + Complex.Conjugate(alpha) * temp2;
                            }
                        }
                    }
                }
            }
        }
示例#28
0
        /// <summary>Returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of symmetric matrix supplied in packed form.
        /// </summary>
        /// <param name="matrixNormType">The type of the matrix norm.</param>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="ap">The specified symmetric matrix in packed form, i.e. either upper or lower triangle as specified in <paramref name="triangularMatrixType"/> with at least <paramref name="n"/> * (<paramref name="n"/> + 1) / 2 elements.</param>
        /// <param name="work">A workspace array which is referenced in the case of 1- or infinity-norm only. In this case the length must be at least <paramref name="n"/>.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of the symmetric input matrix is stored.</param>
        /// <returns>The value of the specific matrix norm.</returns>
        public double dlansp(MatrixNormType matrixNormType, int n, double[] ap, double[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            var norm = LAPACK.GetMatrixNormType(matrixNormType);
            var uplo = LAPACK.GetUplo(triangularMatrixType);

            return(_dlansp(ref norm, ref uplo, ref n, ap, work));
        }
        /// <summary>Performs a rank-2 update of a symmetric matrix, i.e. A := \alpha * x * y^t + \alpha * y * x^t + A.
        /// </summary>
        /// <param name="n">The order of matrix A.</param>
        /// <param name="alpha">The scalar \alpha.</param>
        /// <param name="x">The vector x with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incX" /> | elements.</param>
        /// <param name="y">The vector y with at least 1 + (<paramref name="n" /> - 1) * | <paramref name="incY" /> | elements.</param>
        /// <param name="a">The symmetric matrix A of dimension (<paramref name="lda" />, <paramref name="n" />) supplied column-by-column (input/output).</param>
        /// <param name="lda">The leading dimension of <paramref name="a" />, must be at least max(1, <paramref name="n" />).</param>
        /// <param name="triangularMatrixType">A value whether matrix A is in its upper or lower triangular representation.</param>
        /// <param name="incX">The increment for the elements of <paramref name="x" />.</param>
        /// <param name="incY">The increment for the elements of <paramref name="y" />.</param>
        public void dsyr2(int n, double alpha, double[] x, double[] y, double[] a, int lda, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, int incX = 1, int incY = 1)
        {
            if (n == 0 || alpha == 0.0)
            {
                return;
            }
            int kx = 1;
            int ky = 1;
            int jx = 1;
            int jy = 1;

            if (incX != 1 || incY != 1)
            {
                if (incX <= 0)
                {
                    kx = 1 - (n - 1) * incX;
                }
                if (incY <= 0)
                {
                    ky = 1 - (n - 1) * incY;
                }
                jx = kx;
                jy = ky;
            }

            if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
            {
                for (int j = 1; j <= n; j++)
                {
                    double temp1 = alpha * y[jy - 1];
                    double temp2 = alpha * x[jx - 1];
                    int    ix    = kx;
                    int    iy    = ky;

                    for (int i = 1; i <= j; i++)
                    {
                        a[i - 1 + (j - 1) * lda] = a[i - 1 + (j - 1) * lda] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                        ix += incX;
                        iy += incY;
                    }
                    jx += incX;
                    jy += incY;
                }
            }
            else
            {
                for (int j = 1; j <= n; ++j)
                {
                    double temp1 = alpha * y[jy - 1];
                    double temp2 = alpha * x[jx - 1];
                    int    ix    = jx;
                    int    iy    = jy;

                    for (int i = j; i <= n; i++)
                    {
                        a[i - 1 + (j - 1) * lda] = a[i - 1 + (j - 1) * lda] + x[ix - 1] * temp1 + y[iy - 1] * temp2;
                        ix += incX;
                        iy += incY;
                    }
                    jx += incX;
                    jy += incY;
                }
            }
        }
示例#30
0
        /// <summary>Returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value of any element of symmetric matrix supplied in packed form.
        /// </summary>
        /// <param name="matrixNormType">The type of the matrix norm.</param>
        /// <param name="n">The order of the matrix.</param>
        /// <param name="ap">The specified symmetric matrix in packed form, i.e. either upper or lower triangle as specified in <paramref name="triangularMatrixType"/> with at least <paramref name="n"/> * (<paramref name="n"/> + 1) / 2 elements.</param>
        /// <param name="work">A workspace array which is referenced in the case of 1- or infinity-norm only. In this case the length must be at least <paramref name="n"/>.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of the symmetric input matrix is stored.</param>
        /// <returns>The value of the specific matrix norm.</returns>
        public double zlansp(MatrixNormType matrixNormType, int n, Complex[] ap, Complex[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            var norm = LapackNativeWrapper.GetMatrixNormType(matrixNormType);
            var uplo = LapackNativeWrapper.GetUplo(triangularMatrixType);

            return(_zlansp(ref norm, ref uplo, ref n, ap, work));
        }