Ejemplo n.º 1
0
 /// <summary>Performs a Hermitian rank-k update, i.e. C := \alpha * A * A^h + \beta*C or C := alpha*A^h * A + beta*C, where C is a Hermitian matrix.
 /// </summary>
 /// <param name="level3">The BLAS level 3 implementation.</param>
 /// <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 * A^h + \beta*C; otherwise the number of rows of matrix A.</param>
 /// <param name="alpha">The scalar \alpha.</param>
 /// <param name="a">The matrix A supplied column-by-column of dimension (s, ka), where s must be at least max(1,<paramref name="n"/>) and ka equals to <paramref name="k"/> if to calculate C := \alpha * A * A^h + \beta*C; s = max(1, <paramref name="k"/>) and ka = <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="n"/>, <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 * A^h + \beta*C or C := alpha*A^h * A + beta*C.</param>
 public static void zherk(this ILevel3BLAS level3, int n, int k, double alpha, Complex[] a, double beta, Complex[] c, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.ZherkOperation operation = BLAS.ZherkOperation.AHermiteTimesA)
 {
     level3.zherk(n, k, alpha, a, beta, c, operation == BLAS.ZherkOperation.ATimesAHermite ? n : k, n, triangularMatrixType, operation);
 }
        /// <summary>Performs a Hermitian rank-k update, i.e. C := \alpha * A * A^h + \beta*C or C := alpha*A^h * A + beta*C, where C is a 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 * A^h + \beta*C; otherwise the number of rows of matrix A.</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 * 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 * 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 * A^h + \beta*C or C := alpha*A^h * A + beta*C.</param>
        public void zherk(int n, int k, double alpha, Complex[] a, double beta, Complex[] c, int lda, int ldc, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.UpperTriangularMatrix, BLAS.ZherkOperation operation = BLAS.ZherkOperation.ATimesAHermite)
        {
            if (n == 0 || ((alpha == 0.0 || k == 0) && (beta == 1.0)))
            {
                return; // nothing to do
            }

            if (operation == BLAS.ZherkOperation.ATimesAHermite)  // C = \alpha *A*conj(A^t) + \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[i + j * ldc];
                        }
                        c[j + j * ldc] = beta * c[j + j * ldc];

                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp = alpha * Complex.Conjugate(a[j + ell * lda]);
                            for (int i = 0; i <= j - 1; i++)
                            {
                                c[i + j * ldc] += temp * a[i + ell * lda];
                            }
                            c[j + j * ldc] = c[j + j * ldc].Real + (temp.Real * a[j + ell * lda].Real - temp.Imaginary * a[j + ell * lda].Imaginary);
                        }
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        c[j + j * ldc] *= beta;
                        for (int i = j + 1; i < n; i++)
                        {
                            c[i + j * ldc] = beta * c[i + j * ldc];
                        }
                        for (int ell = 0; ell < k; ell++)
                        {
                            Complex temp = alpha * Complex.Conjugate(a[j + ell * lda]);
                            for (int i = j; i < n; i++)
                            {
                                c[i + j * ldc] += temp * a[i + ell * lda];
                            }
                        }
                    }
                }
            }
            else // C = \alpha *conj(A^t)*A + \beta *C
            {
                if (triangularMatrixType == BLAS.TriangularMatrixType.UpperTriangularMatrix)
                {
                    for (int j = 0; j < n; j++)
                    {
                        for (int i = 0; i <= j - 1; i++)
                        {
                            Complex temp = 0.0;
                            for (int ell = 0; ell < k; ell++)
                            {
                                temp += Complex.Conjugate(a[ell + i * lda]) * a[ell + j * lda];
                            }
                            c[i + j * ldc] = alpha * temp + beta * c[i + j * ldc];
                        }

                        double rTemp = 0.0;
                        for (int ell = 0; ell < k; ell++)
                        {
                            rTemp += a[ell + j * lda].Real * a[ell + j * lda].Real + a[ell + j * lda].Imaginary * a[ell + j * lda].Imaginary;
                        }
                        c[j + j * ldc] = alpha * rTemp + beta * c[j + j * ldc].Real;
                    }
                }
                else
                {
                    for (int j = 0; j < n; j++)
                    {
                        double rTemp = 0.0;
                        for (int ell = 0; ell < k; ell++)
                        {
                            rTemp += a[ell + j * lda].Real * a[ell + j * lda].Real + a[ell + j * lda].Imaginary * a[ell + j * lda].Imaginary;
                        }
                        c[j + j * ldc] = alpha * rTemp + beta * c[j + j * ldc].Real;

                        for (int i = j + 1; i < n; i++)
                        {
                            Complex temp = 0.0;
                            for (int ell = 0; ell < k; ell++)
                            {
                                temp += Complex.Conjugate(a[ell + i * lda]) * a[ell + j * lda];
                            }
                            c[i + j * ldc] = alpha * temp + beta * c[i + j * ldc];
                        }
                    }
                }
            }
        }