// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // // Copyright (c) 2009-2014 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 System; using IStation.Numerics.LinearAlgebra.Factorization; using IStation.Numerics.LinearAlgebra.Solvers; namespace IStation.Numerics.LinearAlgebra { /// /// Defines the base class for Matrix classes. /// public abstract partial class Matrix { // Factorizations /// /// Computes the Cholesky decomposition for a matrix. /// /// The Cholesky decomposition object. public abstract Cholesky Cholesky(); /// /// Computes the LU decomposition for a matrix. /// /// The LU decomposition object. public abstract LU LU(); /// /// Computes the QR decomposition for a matrix. /// /// The type of QR factorization to perform. /// The QR decomposition object. public abstract QR QR(QRMethod method = QRMethod.Thin); /// /// Computes the QR decomposition for a matrix using Modified Gram-Schmidt Orthogonalization. /// /// The QR decomposition object. public abstract GramSchmidt GramSchmidt(); /// /// Computes the SVD decomposition for a matrix. /// /// Compute the singular U and VT vectors or not. /// The SVD decomposition object. public abstract Svd Svd(bool computeVectors = true); /// /// Computes the EVD decomposition for a matrix. /// /// The EVD decomposition object. public abstract Evd Evd(Symmetricity symmetricity = Symmetricity.Unknown); // Direct Solvers: Full /// /// Solves a system of linear equations, Ax = b, with A QR factorized. /// /// The right hand side vector, b. /// The left hand side , x. public void Solve(Vector input, Vector result) { if (ColumnCount == RowCount) { LU().Solve(input, result); return; } QR().Solve(input, result); } /// /// Solves a system of linear equations, AX = B, with A QR factorized. /// /// The right hand side , B. /// The left hand side , X. public void Solve(Matrix input, Matrix result) { if (ColumnCount == RowCount) { LU().Solve(input, result); return; } QR().Solve(input, result); } // Direct Solvers: Simple /// /// Solves a system of linear equations, AX = B, with A QR factorized. /// /// The right hand side , B. /// The left hand side , X. public Matrix Solve(Matrix input) { var x = Build.SameAs(this, ColumnCount, input.ColumnCount, fullyMutable: true); Solve(input, x); return x; } /// /// Solves a system of linear equations, Ax = b, with A QR factorized. /// /// The right hand side vector, b. /// The left hand side , x. public Vector Solve(Vector input) { var x = Vector.Build.SameAs(this, ColumnCount); Solve(input, x); return x; } // Iterative Solvers: Full /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The result vector x. /// The iterative solver to use. /// The iterator to use to control when to stop iterating. /// The preconditioner to use for approximations. public IterationStatus TrySolveIterative(Vector input, Vector result, IIterativeSolver solver, Iterator iterator = null, IPreconditioner preconditioner = null) { if (iterator == null) { iterator = new Iterator(Build.IterativeSolverStopCriteria()); } if (preconditioner == null) { preconditioner = new UnitPreconditioner(); } solver.Solve(this, input, result, iterator, preconditioner); return iterator.Status; } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The result matrix X /// The iterative solver to use. /// The iterator to use to control when to stop iterating. /// The preconditioner to use for approximations. public IterationStatus TrySolveIterative(Matrix input, Matrix result, IIterativeSolver solver, Iterator iterator = null, IPreconditioner preconditioner = null) { if (RowCount != input.RowCount || input.RowCount != result.RowCount || input.ColumnCount != result.ColumnCount) { throw DimensionsDontMatch(this, input, result); } if (iterator == null) { iterator = new Iterator(Build.IterativeSolverStopCriteria()); } if (preconditioner == null) { preconditioner = new UnitPreconditioner(); } for (var column = 0; column < input.ColumnCount; column++) { var solution = Vector.Build.Dense(RowCount); solver.Solve(this, input.Column(column), solution, iterator, preconditioner); foreach (var element in solution.EnumerateIndexed(Zeros.AllowSkip)) { result.At(element.Item1, column, element.Item2); } } return iterator.Status; } /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The result vector x. /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The preconditioner to use for approximations. public IterationStatus TrySolveIterative(Vector input, Vector result, IIterativeSolver solver, IPreconditioner preconditioner, params IIterationStopCriterion[] stopCriteria) { var iterator = new Iterator(stopCriteria.Length == 0 ? Build.IterativeSolverStopCriteria() : stopCriteria); return TrySolveIterative(input, result, solver, iterator, preconditioner); } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The result matrix X /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The preconditioner to use for approximations. public IterationStatus TrySolveIterative(Matrix input, Matrix result, IIterativeSolver solver, IPreconditioner preconditioner, params IIterationStopCriterion[] stopCriteria) { var iterator = new Iterator(stopCriteria.Length == 0 ? Build.IterativeSolverStopCriteria() : stopCriteria); return TrySolveIterative(input, result, solver, iterator, preconditioner); } /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The result vector x. /// The iterative solver to use. /// Criteria to control when to stop iterating. public IterationStatus TrySolveIterative(Vector input, Vector result, IIterativeSolver solver, params IIterationStopCriterion[] stopCriteria) { var iterator = new Iterator(stopCriteria.Length == 0 ? Build.IterativeSolverStopCriteria() : stopCriteria); return TrySolveIterative(input, result, solver, iterator); } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The result matrix X /// The iterative solver to use. /// Criteria to control when to stop iterating. public IterationStatus TrySolveIterative(Matrix input, Matrix result, IIterativeSolver solver, params IIterationStopCriterion[] stopCriteria) { var iterator = new Iterator(stopCriteria.Length == 0 ? Build.IterativeSolverStopCriteria() : stopCriteria); return TrySolveIterative(input, result, solver, iterator); } // Iterative Solvers: Simple /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The iterative solver to use. /// The iterator to use to control when to stop iterating. /// The preconditioner to use for approximations. /// The result vector x. public Vector SolveIterative(Vector input, IIterativeSolver solver, Iterator iterator = null, IPreconditioner preconditioner = null) { var result = Vector.Build.Dense(RowCount); TrySolveIterative(input, result, solver, iterator, preconditioner); return result; } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The iterative solver to use. /// The iterator to use to control when to stop iterating. /// The preconditioner to use for approximations. /// The result matrix X. public Matrix SolveIterative(Matrix input, IIterativeSolver solver, Iterator iterator = null, IPreconditioner preconditioner = null) { var result = Build.Dense(input.RowCount, input.ColumnCount); TrySolveIterative(input, result, solver, iterator, preconditioner); return result; } /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The preconditioner to use for approximations. /// The result vector x. public Vector SolveIterative(Vector input, IIterativeSolver solver, IPreconditioner preconditioner, params IIterationStopCriterion[] stopCriteria) { var result = Vector.Build.Dense(RowCount); TrySolveIterative(input, result, solver, preconditioner, stopCriteria); return result; } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The preconditioner to use for approximations. /// The result matrix X. public Matrix SolveIterative(Matrix input, IIterativeSolver solver, IPreconditioner preconditioner, params IIterationStopCriterion[] stopCriteria) { var result = Build.Dense(input.RowCount, input.ColumnCount); TrySolveIterative(input, result, solver, preconditioner, stopCriteria); return result; } /// /// Solves the matrix equation Ax = b, where A is the coefficient matrix (this matrix), b is the solution vector and x is the unknown vector. /// /// The solution vector b. /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The result vector x. public Vector SolveIterative(Vector input, IIterativeSolver solver, params IIterationStopCriterion[] stopCriteria) { var result = Vector.Build.Dense(RowCount); TrySolveIterative(input, result, solver, stopCriteria); return result; } /// /// Solves the matrix equation AX = B, where A is the coefficient matrix (this matrix), B is the solution matrix and X is the unknown matrix. /// /// The solution matrix B. /// The iterative solver to use. /// Criteria to control when to stop iterating. /// The result matrix X. public Matrix SolveIterative(Matrix input, IIterativeSolver solver, params IIterationStopCriterion[] stopCriteria) { var result = Build.Dense(input.RowCount, input.ColumnCount); TrySolveIterative(input, result, solver, stopCriteria); return result; } } }