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);
internal static string Translate(this StoredTriangle uplo) => (uplo == StoredTriangle.Upper) ? "U" : "L";