internal void Dpotrs(StoredTriangle triangle, int orderA, int numRhs, double[] factorizedMatrixA, int offsetA,
                             int leadingDimA, double[] rhsB, int offsetB, int leadingDimB)
        {
            int info = DefaultInfo;

            Provider.Dpotrs(triangle.Translate(), orderA, numRhs, factorizedMatrixA, offsetA, leadingDimA,
                            rhsB, offsetB, leadingDimB, ref info);

            if (info < 0) // info can only be 0 or negative
            {
                // The indices of negative pivots must take into account the offset parameters
                if (info == -5)
                {
                    info = -6;
                }
                else if (info == -6)
                {
                    info = -7;
                }
                else if (info == -7)
                {
                    info = -9;
                }
                ProcessNegativeInfo(info);
            }
        }
        /// <summary>
        /// If the return value is a non-negative int i, then the entry (i, i) of the factor U or L is 0 and the inverse could
        /// not be computed.
        /// </summary>
        internal int Dpotri(StoredTriangle triangle, int orderA, double[] factorizedMatrixA, int offsetA, int leadingDimA)
        {
            int info = DefaultInfo;

            Provider.Dpotri(triangle.Translate(), orderA, factorizedMatrixA, offsetA, leadingDimA, ref info);

            if (info < 0)
            {
                // The indices of negative pivots must take into account the offset parameters
                if (info == -4)
                {
                    info = -5;
                }
                ProcessNegativeInfo(info);
            }

            //TODO: is there the same problem as LU, i.e. can the last minor not be positive definite, while the info = 0?
            if (info > 0)
            {
                return(info - 1);
            }
            else
            {
                return(int.MinValue);
            }
        }
        public void Dspmv(StoredTriangle uplo, int n,
                          double alpha, double[] a, int offsetA, double[] x, int offsetX, int incX,
                          double beta, double[] y, int offsetY, int incY)
        {
            // y = alpha * L * x + beta * y
            CblasLevel2Implementations.LowerTimesVectorPackedRowMajor(
                CblasLevel2Implementations.Diagonal.Regular, n, alpha, a, offsetA, x, offsetX, incX, beta, y, offsetY, incY);

            // y = alpha * U * x + y, where U has 0 diagonal
            CblasLevel2Implementations.UpperTimesVectorPackedColMajor(
                CblasLevel2Implementations.Diagonal.Zero, n, alpha, a, offsetA, x, offsetX, incX, 1.0, y, offsetY, incY);
        }
        public void Dtpsv(StoredTriangle uplo, TransposeMatrix transA, DiagonalValues diag, int n,
                          double[] a, int offsetA, double[] x, int offsetX, int incX)
        {
            bool unit = (diag == DiagonalValues.Unit) ? true : false;

            if (UseUpperImplementation(uplo, transA))
            {
                CblasLevel2Implementations.BackSubstitutionPackedColMajor(unit, n, a, offsetA, x, offsetX, incX);
            }
            else
            {
                CblasLevel2Implementations.ForwardSubstitutionPackedRowMajor(unit, n, a, offsetA, x, offsetX, incX);
            }
        }
        internal void Dsyev(EigensystemJob job, StoredTriangle triangle, int orderA, double[] matrixA, int offsetA,
                            int leadingDimA, double[] eigenvalues, int offsetEigenvalues)
        {
            int info = DefaultInfo;

            QueryWorkspaceAndExecute((work, offsetWork, lWork) => Provider.Dsyev(
                                         job.Translate(), triangle.Translate(), orderA, ref matrixA, offsetA, leadingDimA, ref eigenvalues,
                                         offsetEigenvalues, ref work, offsetWork, lWork, ref info));

            if (info > 0)
            {
                throw new LapackException($"The algorithm failed to converge. There were {info} elements of an intermediate"
                                          + " tridiagonal form which did not converge to zero");
            }
            else if (info < 0)
            {
                ProcessNegativeInfo(info);
            }
        }
        public void Dtpmv(StoredTriangle uplo, TransposeMatrix transA, DiagonalValues diag, int n,
                          double[] a, int offsetA, double[] x, int offsetX, int incX)
        {
            // The copy may be avoidable in trangular operations, if we start the dot products from the bottom
            var input = new double[x.Length];

            Array.Copy(x, input, x.Length);

            CblasLevel2Implementations.Diagonal managedDiag = (diag == DiagonalValues.NonUnit) ?
                                                              CblasLevel2Implementations.Diagonal.Regular : CblasLevel2Implementations.Diagonal.Unit;
            if (UseUpperImplementation(uplo, transA))
            {
                CblasLevel2Implementations.UpperTimesVectorPackedColMajor(
                    managedDiag, n, 1.0, a, offsetA, input, offsetX, incX, 0.0, x, offsetX, incX);
            }
            else
            {
                CblasLevel2Implementations.LowerTimesVectorPackedRowMajor(
                    managedDiag, n, 1.0, a, offsetA, input, offsetX, incX, 0.0, x, offsetX, incX);
            }
        }
        /// <summary>
        /// If the return value is a non-negative int i, then the entry (i, i) of the factor U or L is 0 and the inverse could
        /// not be computed.
        /// </summary>
        internal int Dpptri(StoredTriangle triangle, int orderA, double[] factorizedMatrixA, int offsetA)
        {
            int info = DefaultInfo;

            Provider.Dpptri(triangle.Translate(), orderA, factorizedMatrixA, offsetA, ref info);

            if (info < 0)
            {
                ProcessNegativeInfo(info);
            }

            //TODO: is there the same problem as LU, i.e. can the last minor not be positive definite, while the info = 0?
            if (info > 0)
            {
                return(info - 1);
            }
            else
            {
                return(int.MinValue);
            }
        }
        private static bool UseUpperImplementation(StoredTriangle uplo, TransposeMatrix transA)
        {
            //if (transA == TransposeMatrix.ConjugateTranspose)
            //    throw new ArgumentException("Cannot use conjugate transpose operations for double matrices and vectors.");

            if (uplo == StoredTriangle.Upper && transA == TransposeMatrix.NoTranspose)
            {
                return(true);
            }
            if (uplo == StoredTriangle.Upper && transA == TransposeMatrix.Transpose)
            {
                return(false);
            }
            if (uplo == StoredTriangle.Lower && transA == TransposeMatrix.NoTranspose)
            {
                return(true);
            }
            if (uplo == StoredTriangle.Lower && transA == TransposeMatrix.Transpose)
            {
                return(false);
            }
            throw new Exception("This code should not have been reached");
        }
 /// <summary>
 /// See http://www.dotnumerics.com/NumericalLibraries/LinearAlgebra/CSharpCodeFiles/dtrsv.aspx
 /// </summary>
 public void Dtrsv(StoredTriangle uplo, TransposeMatrix transA, DiagonalValues diag, int n,
                   double[] a, int offsetA, int ldA, double[] x, int offsetX, int incX)
 => dtrsv.Run(uplo.Translate(), transA.Translate(), diag.Translate(), n, a, offsetA, ldA, ref x, offsetX, incX);
 /// <summary>
 /// See https://software.intel.com/en-us/mkl-developer-reference-fortran-trsv#D8733073-F041-4AA1-B82C-123DFA993AD7
 /// </summary>
 public void Dtrsv(StoredTriangle uplo, TransposeMatrix transA, DiagonalValues diag, int n,
                   double[] a, int offsetA, int ldA, double[] x, int offsetX, int incX)
 => Blas.Dtrsv(uplo.Translate(), transA.Translate(), diag.Translate(), ref n, ref a[offsetA], ref ldA,
               ref x[offsetX], ref incX);
 /// <summary>
 /// See https://software.intel.com/en-us/mkl-developer-reference-fortran-spmv#16CB58C4-105B-486C-B6AA-42BB0C721A76
 /// </summary>
 public void Dspmv(StoredTriangle uplo, int n,
                   double alpha, double[] a, int offsetA, double[] x, int offsetX, int incX,
                   double beta, double[] y, int offsetY, int incY)
 => Blas.Dspmv(uplo.Translate(), ref n, ref alpha, ref a[offsetA],
               ref x[offsetX], ref incX, ref beta, ref y[offsetY], ref incY);
Beispiel #12
0
 internal static string Translate(this StoredTriangle uplo) => (uplo == StoredTriangle.Upper) ? "U" : "L";