//
// 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);
}
}