// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2018 Math.NET // // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // using IStation.Numerics.LinearAlgebra.Factorization; using Complex = System.Numerics.Complex; namespace IStation.Numerics.Providers.LinearAlgebra { /// /// How to transpose a matrix. /// public enum Transpose { /// /// Don't transpose a matrix. /// DontTranspose = 111, /// /// Transpose a matrix. /// Transpose = 112, /// /// Conjugate transpose a complex matrix. /// /// If a conjugate transpose is used with a real matrix, then the matrix is just transposed. ConjugateTranspose = 113 } /// /// Types of matrix norms. /// public enum Norm : byte { /// /// The 1-norm. /// OneNorm = (byte) '1', /// /// The Frobenius norm. /// FrobeniusNorm = (byte) 'f', /// /// The infinity norm. /// InfinityNorm = (byte) 'i', /// /// The largest absolute value norm. /// LargestAbsoluteValue = (byte) 'm' } /// /// Interface to linear algebra algorithms that work off 1-D arrays. /// public interface ILinearAlgebraProvider : ILinearAlgebraProvider, ILinearAlgebraProvider, ILinearAlgebraProvider, ILinearAlgebraProvider { /// /// Try to find out whether the provider is available, at least in principle. /// Verification may still fail if available, but it will certainly fail if unavailable. /// bool IsAvailable(); /// /// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider /// void InitializeVerify(); /// /// Frees memory buffers, caches and handles allocated in or to the provider. /// Does not unload the provider itself, it is still usable afterwards. /// void FreeResources(); } /// /// Interface to linear algebra algorithms that work off 1-D arrays. /// /// Supported data types are Double, Single, Complex, and Complex32. public interface ILinearAlgebraProvider where T : struct { /*/// /// Queries the provider for the optimal, workspace block size /// for the given routine. /// /// Name of the method to query. /// -1 if the provider cannot compute the workspace size; otherwise /// the suggested block size. int QueryWorkspaceBlockSize(string methodName);*/ /// /// Adds a scaled vector to another: result = y + alpha*x. /// /// The vector to update. /// The value to scale by. /// The vector to add to . /// The result of the addition. /// This is similar to the AXPY BLAS routine. void AddVectorToScaledVector(T[] y, T alpha, T[] x, T[] result); /// /// Scales an array. Can be used to scale a vector and a matrix. /// /// The scalar. /// The values to scale. /// This result of the scaling. /// This is similar to the SCAL BLAS routine. void ScaleArray(T alpha, T[] x, T[] result); /// /// Conjugates an array. Can be used to conjugate a vector and a matrix. /// /// The values to conjugate. /// This result of the conjugation. void ConjugateArray(T[] x, T[] result); /// /// Computes the dot product of x and y. /// /// The vector x. /// The vector y. /// The dot product of x and y. /// This is equivalent to the DOT BLAS routine. T DotProduct(T[] x, T[] y); /// /// Does a point wise add of two arrays z = x + y. This can be used /// to add vectors or matrices. /// /// The array x. /// The array y. /// The result of the addition. /// There is no equivalent BLAS routine, but many libraries /// provide optimized (parallel and/or vectorized) versions of this /// routine. void AddArrays(T[] x, T[] y, T[] result); /// /// Does a point wise subtraction of two arrays z = x - y. This can be used /// to subtract vectors or matrices. /// /// The array x. /// The array y. /// The result of the subtraction. /// There is no equivalent BLAS routine, but many libraries /// provide optimized (parallel and/or vectorized) versions of this /// routine. void SubtractArrays(T[] x, T[] y, T[] result); /// /// Does a point wise multiplication of two arrays z = x * y. This can be used /// to multiply elements of vectors or matrices. /// /// The array x. /// The array y. /// The result of the point wise multiplication. /// There is no equivalent BLAS routine, but many libraries /// provide optimized (parallel and/or vectorized) versions of this /// routine. void PointWiseMultiplyArrays(T[] x, T[] y, T[] result); /// /// Does a point wise division of two arrays z = x / y. This can be used /// to divide elements of vectors or matrices. /// /// The array x. /// The array y. /// The result of the point wise division. /// There is no equivalent BLAS routine, but many libraries /// provide optimized (parallel and/or vectorized) versions of this /// routine. void PointWiseDivideArrays(T[] x, T[] y, T[] result); /// /// Does a point wise power of two arrays z = x ^ y. This can be used /// to raise elements of vectors or matrices to the powers of another vector or matrix. /// /// The array x. /// The array y. /// The result of the point wise power. /// There is no equivalent BLAS routine, but many libraries /// provide optimized (parallel and/or vectorized) versions of this /// routine. void PointWisePowerArrays(T[] x, T[] y, T[] result); /// /// Computes the requested of the matrix. /// /// The type of norm to compute. /// The number of rows. /// The number of columns. /// The matrix to compute the norm from. /// /// The requested of the matrix. /// double MatrixNorm(Norm norm, int rows, int columns, T[] matrix); /// /// Multiples two matrices. result = x * y /// /// The x matrix. /// The number of rows in the x matrix. /// The number of columns in the x matrix. /// The y matrix. /// The number of rows in the y matrix. /// The number of columns in the y matrix. /// Where to store the result of the multiplication. /// This is a simplified version of the BLAS GEMM routine with alpha /// set to 1.0 and beta set to 0.0, and x and y are not transposed. void MatrixMultiply(T[] x, int rowsX, int columnsX, T[] y, int rowsY, int columnsY, T[] result); /// /// Multiplies two matrices and updates another with the result. c = alpha*op(a)*op(b) + beta*c /// /// How to transpose the matrix. /// How to transpose the matrix. /// The value to scale matrix. /// The a matrix. /// The number of rows in the matrix. /// The number of columns in the matrix. /// The b matrix /// The number of rows in the matrix. /// The number of columns in the matrix. /// The value to scale the matrix. /// The c matrix. void MatrixMultiplyWithUpdate(Transpose transposeA, Transpose transposeB, T alpha, T[] a, int rowsA, int columnsA, T[] b, int rowsB, int columnsB, T beta, T[] c); /// /// Computes the LUP factorization of A. P*A = L*U. /// /// An by matrix. The matrix is overwritten with the /// the LU factorization on exit. The lower triangular factor L is stored in under the diagonal of (the diagonal is always 1.0 /// for the L factor). The upper triangular factor U is stored on and above the diagonal of . /// The order of the square matrix . /// On exit, it contains the pivot indices. The size of the array must be . /// This is equivalent to the GETRF LAPACK routine. void LUFactor(T[] data, int order, int[] ipiv); /// /// Computes the inverse of matrix using LU factorization. /// /// The N by N matrix to invert. Contains the inverse On exit. /// The order of the square matrix . /// This is equivalent to the GETRF and GETRI LAPACK routines. void LUInverse(T[] a, int order); /// /// Computes the inverse of a previously factored matrix. /// /// The LU factored N by N matrix. Contains the inverse On exit. /// The order of the square matrix . /// The pivot indices of . /// This is equivalent to the GETRI LAPACK routine. void LUInverseFactored(T[] a, int order, int[] ipiv); /// /// Solves A*X=B for X using LU factorization. /// /// The number of columns of B. /// The square matrix A. /// The order of the square matrix . /// On entry the B matrix; on exit the X matrix. /// This is equivalent to the GETRF and GETRS LAPACK routines. void LUSolve(int columnsOfB, T[] a, int order, T[] b); /// /// Solves A*X=B for X using a previously factored A matrix. /// /// The number of columns of B. /// The factored A matrix. /// The order of the square matrix . /// The pivot indices of . /// On entry the B matrix; on exit the X matrix. /// This is equivalent to the GETRS LAPACK routine. void LUSolveFactored(int columnsOfB, T[] a, int order, int[] ipiv, T[] b); /// /// Computes the Cholesky factorization of A. /// /// On entry, a square, positive definite matrix. On exit, the matrix is overwritten with the /// the Cholesky factorization. /// The number of rows or columns in the matrix. /// This is equivalent to the POTRF LAPACK routine. void CholeskyFactor(T[] a, int order); /// /// Solves A*X=B for X using Cholesky factorization. /// /// The square, positive definite matrix A. /// The number of rows and columns in A. /// On entry the B matrix; on exit the X matrix. /// The number of columns in the B matrix. /// This is equivalent to the POTRF add POTRS LAPACK routines. void CholeskySolve(T[] a, int orderA, T[] b, int columnsB); /// /// Solves A*X=B for X using a previously factored A matrix. /// /// The square, positive definite matrix A. /// The number of rows and columns in A. /// On entry the B matrix; on exit the X matrix. /// The number of columns in the B matrix. /// This is equivalent to the POTRS LAPACK routine. void CholeskySolveFactored(T[] a, int orderA, T[] b, int columnsB); /// /// Computes the full QR factorization of A. /// /// On entry, it is the M by N A matrix to factor. On exit, /// it is overwritten with the R matrix of the QR factorization. /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// On exit, A M by M matrix that holds the Q matrix of the /// QR factorization. /// A min(m,n) vector. On exit, contains additional information /// to be used by the QR solve routine. /// This is similar to the GEQRF and ORGQR LAPACK routines. void QRFactor(T[] a, int rowsA, int columnsA, T[] q, T[] tau); /// /// Computes the thin QR factorization of A where M > N. /// /// On entry, it is the M by N A matrix to factor. On exit, /// it is overwritten with the Q matrix of the QR factorization. /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// On exit, A N by N matrix that holds the R matrix of the /// QR factorization. /// A min(m,n) vector. On exit, contains additional information /// to be used by the QR solve routine. /// This is similar to the GEQRF and ORGQR LAPACK routines. void ThinQRFactor(T[] a, int rowsA, int columnsA, T[] r, T[] tau); /// /// Solves A*X=B for X using QR factorization of A. /// /// The A matrix. /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// The B matrix. /// The number of columns of B. /// On exit, the solution matrix. /// The type of QR factorization to perform. /// Rows must be greater or equal to columns. void QRSolve(T[] a, int rows, int columns, T[] b, int columnsB, T[] x, QRMethod method = QRMethod.Full); /// /// Solves A*X=B for X using a previously QR factored matrix. /// /// The Q matrix obtained by QR factor. This is only used for the managed provider and can be /// null for the native provider. The native provider uses the Q portion stored in the R matrix. /// The R matrix obtained by calling . /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// Contains additional information on Q. Only used for the native solver /// and can be null for the managed provider. /// On entry the B matrix; on exit the X matrix. /// The number of columns of B. /// On exit, the solution matrix. /// Rows must be greater or equal to columns. /// The type of QR factorization to perform. void QRSolveFactored(T[] q, T[] r, int rowsA, int columnsA, T[] tau, T[] b, int columnsB, T[] x, QRMethod method = QRMethod.Full); /// /// Computes the singular value decomposition of A. /// /// Compute the singular U and VT vectors or not. /// On entry, the M by N matrix to decompose. On exit, A may be overwritten. /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// The singular values of A in ascending value. /// If is true, on exit U contains the left /// singular vectors. /// If is true, on exit VT contains the transposed /// right singular vectors. /// This is equivalent to the GESVD LAPACK routine. void SingularValueDecomposition(bool computeVectors, T[] a, int rowsA, int columnsA, T[] s, T[] u, T[] vt); /// /// Solves A*X=B for X using the singular value decomposition of A. /// /// On entry, the M by N matrix to decompose. /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// The B matrix. /// The number of columns of B. /// On exit, the solution matrix. void SvdSolve(T[] a, int rowsA, int columnsA, T[] b, int columnsB, T[] x); /// /// Solves A*X=B for X using a previously SVD decomposed matrix. /// /// The number of rows in the A matrix. /// The number of columns in the A matrix. /// The s values returned by . /// The left singular vectors returned by . /// The right singular vectors returned by . /// The B matrix /// The number of columns of B. /// On exit, the solution matrix. void SvdSolveFactored(int rowsA, int columnsA, T[] s, T[] u, T[] vt, T[] b, int columnsB, T[] x); /// /// Computes the eigenvalues and eigenvectors of a matrix. /// /// Whether the matrix is symmetric or not. /// The order of the matrix. /// The matrix to decompose. The length of the array must be order * order. /// On output, the matrix contains the eigen vectors. The length of the array must be order * order. /// On output, the eigen values (λ) of matrix in ascending value. The length of the array must . /// On output, the block diagonal eigenvalue matrix. The length of the array must be order * order. void EigenDecomp(bool isSymmetric, int order, T[] matrix, T[] matrixEv, Complex[] vectorEv, T[] matrixD); } }