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