/// <summary>Gets the <see cref="System.Char"/> representation of a specific LAPACK job parameter.
        /// </summary>
        /// <param name="job">The specified LAPACK job parameter.</param>
        /// <returns>The <see cref="System.Char"/> representation of the specified LAPACK job parameter.</returns>
        private static char GetJob(MklLapackEigenvalues.DsyrdbJob job)
        {
            switch (job)
            {
            case MklLapackEigenvalues.DsyrdbJob.None:
                return('N');

            case MklLapackEigenvalues.DsyrdbJob.U:
                return('U');

            case MklLapackEigenvalues.DsyrdbJob.V:
                return('V');

            default:
                throw new NotImplementedException();
            }
        }
        /// <summary>Reduces a real symmetric matrix to tridiagonal form with Successive Bandwidth Reduction approach, i.e. A = Q * T * Q' and optionally multiplies matrix Z by Q, or simply forms Q.
        /// </summary>
        /// <param name="symmetricEigenvalueProblems">The <see cref="LapackEigenvalues.ISymmetricEigenvalueProblems"/> object.</param>
        /// <param name="job">A value indicating what kind of job to do by the LAPACK function.</param>
        /// <param name="n">The order of the matrix A.</param>
        /// <param name="kd">The bandwidth of the banded matrix B, for example 40 or 64.</param>
        /// <param name="a">The symmetric matrix provided column-by-column; depending on <paramref name="job"/> it will be overwritten by the banded matrix B and details of the orthogonal matrix Q to reduce A to B a specified by <paramref name="triangularMatrixType"/>.</param>
        /// <param name="d">The diagonal elements of the tridiagonal matrix; the array should have at least <paramref name="n"/> elements (output).</param>
        /// <param name="e">The off-diagonal elements of the tridiagonal matrix; the array should have at least <paramref name="n"/> - 1 elements (output).</param>
        /// <param name="tau">Further details of the orthogonal matrix; the array should have at least <paramref name="n"/> - <paramref name="kd"/> - 1  elements (output).</param>
        /// <param name="z">The matrix Z if <paramref name="job"/> indicates to take into account this parameter, if referenced it should have at least <paramref name="n"/> * <paramref name="n"/> elements and will be overwritten on exit by Z * Q.</param>
        /// <param name="work">A workspace array with at least (2 * <paramref name="kd"/> + 1) * <paramref name="n"/> + <paramref name="kd"/> elements.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of the symmetric input matrix is stored.</param>
        public static void dsyrdb(this LapackEigenvalues.ISymmetricEigenvalueProblems symmetricEigenvalueProblems, MklLapackEigenvalues.DsyrdbJob job, int n, int kd, double[] a, double[] d, double[] e, double[] tau, double[] z, double[] work, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            int info;
            var jobz  = GetJob(job);
            int lwork = work.Length;
            var uplo  = GetUplo(triangularMatrixType);

            _dsyrdb(ref jobz, ref uplo, ref n, ref kd, a, ref n, d, e, tau, z, ref n, work, ref lwork, out info);
            CheckForError(info, "dsyrdb");
        }
        /// <summary>Gets a optimal workspace array length for the <c>dsyrdb</c> function.
        /// </summary>
        /// <param name="symmetricEigenvalueProblems">The <see cref="LapackEigenvalues.ISymmetricEigenvalueProblems"/> object.</param>
        /// <param name="job">A value indicating what kind of job to do by the LAPACK function.</param>
        /// <param name="triangularMatrixType">A value indicating whether the upper or lower triangular part of the symmetric input matrix is stored.</param>
        /// <param name="n">The order of the matrix A.</param>
        /// <param name="kd">The bandwidth of the banded matrix B.</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 static int dsyrdbQuery(this LapackEigenvalues.ISymmetricEigenvalueProblems symmetricEigenvalueProblems, MklLapackEigenvalues.DsyrdbJob job, int n, int kd, BLAS.TriangularMatrixType triangularMatrixType = BLAS.TriangularMatrixType.LowerTriangularMatrix)
        {
            var lwork = -1;
            var jobz  = GetJob(job);
            var uplo  = GetUplo(triangularMatrixType);

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

                _dsyrdb(ref jobz, ref uplo, ref n, ref kd, null, ref n, null, null, null, null, ref n, work, ref lwork, out info);
                CheckForError(info, "dsyrdb");

                return(((int)work[0]) + 1);
            }
        }