forked from tsai/mathnet-numerics
6 changed files with 349 additions and 0 deletions
@ -0,0 +1,78 @@ |
|||
// <copyright file="Cholesky.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 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.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.Decomposition |
|||
{ |
|||
using System; |
|||
using Properties; |
|||
|
|||
/// <summary>
|
|||
/// <para>A class which encapsulates the functionality of a Cholesky decomposition.</para>
|
|||
/// <para>For a symmetric, positive definite matrix A, the Cholesky decomposition
|
|||
/// is an lower triangular matrix L so that A = L*L'.</para>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The computation of the Cholesky decomposition is done at construction time. If the matrix is not symmetric
|
|||
/// or positive definite, the constructor will throw an exception.
|
|||
/// </remarks>
|
|||
public abstract class Cholesky |
|||
{ |
|||
/// <summary>
|
|||
/// Internal method which routes the call to perform the Cholesky factorization to the appropriate class.
|
|||
/// </summary>
|
|||
/// <param name="matrix">The matrix to factor.</param>
|
|||
/// <returns>A cholesky factorization object.</returns>
|
|||
internal static Cholesky Create(Matrix matrix) |
|||
{ |
|||
var dense = matrix as DenseMatrix; |
|||
if (dense != null) |
|||
{ |
|||
return new DenseCholesky(dense); |
|||
} |
|||
|
|||
throw new NotImplementedException(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// A reference to the lower triangular form of the Cholesky matrix.
|
|||
/// </summary>
|
|||
public abstract Matrix Factor { get; } |
|||
|
|||
/// <summary>
|
|||
/// The determinant of the matrix for which the Cholesky matrix was computed.
|
|||
/// </summary>
|
|||
public abstract double Determinant { get; } |
|||
|
|||
/// <summary>
|
|||
/// The log determinant of the matrix for which the Cholesky matrix was computed.
|
|||
/// </summary>
|
|||
public abstract double DeterminantLn { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,117 @@ |
|||
// <copyright file="DenseCholesky.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 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.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.Decomposition |
|||
{ |
|||
using System; |
|||
using Properties; |
|||
|
|||
/// <summary>
|
|||
/// <para>A class which encapsulates the functionality of a Cholesky decomposition for dense matrices.</para>
|
|||
/// <para>For a symmetric, positive definite matrix A, the Cholesky decomposition
|
|||
/// is an lower triangular matrix L so that A = L*L'.</para>
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The computation of the Cholesky decomposition is done at construction time. If the matrix is not symmetric
|
|||
/// or positive definite, the constructor will throw an exception.
|
|||
/// </remarks>
|
|||
public class DenseCholesky : Cholesky |
|||
{ |
|||
/// <summary>
|
|||
/// Stores the Cholesky factor for the decomposition.
|
|||
/// </summary>
|
|||
private DenseMatrix _factor; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="DenseCholesky"/> class. This object will compute the
|
|||
/// Cholesky decomposition when the constructor is called and cache it's factorization.
|
|||
/// </summary>
|
|||
/// <param name="matrix">The matrix to factor.</param>
|
|||
/// <exception cref="ArgumentNullException">If <paramref name="matrix"/> is <b>null</b>.</exception>
|
|||
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not a square matrix.</exception>
|
|||
/// <exception cref="ArgumentException">If <paramref name="matrix"/> is not positive definite.</exception>
|
|||
public DenseCholesky(DenseMatrix matrix) |
|||
{ |
|||
if (matrix == null) |
|||
{ |
|||
throw new ArgumentNullException("matrix"); |
|||
} |
|||
|
|||
if (matrix.RowCount != matrix.ColumnCount) |
|||
{ |
|||
throw new ArgumentException(Resources.ArgumentMatrixSquare); |
|||
} |
|||
|
|||
// Create a new matrix for the Cholesky factor, then perform factorization (while overwriting).
|
|||
_factor = (DenseMatrix)matrix.Clone(); |
|||
Control.LinearAlgebraProvider.CholeskyFactor(_factor.Data, _factor.RowCount); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Returns the lower triangular form of the Cholesky matrix.
|
|||
/// </summary>
|
|||
public override Matrix Factor |
|||
{ |
|||
get { return _factor; } |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The determinant of the matrix for which the Cholesky matrix was computed.
|
|||
/// </summary>
|
|||
public override double Determinant |
|||
{ |
|||
get |
|||
{ |
|||
double det = 1.0; |
|||
for (int j = 0; j < _factor.RowCount; j++) |
|||
{ |
|||
det *= (_factor[j, j] * _factor[j, j]); |
|||
} |
|||
return det; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The log determinant of the matrix for which the Cholesky matrix was computed.
|
|||
/// </summary>
|
|||
public override double DeterminantLn |
|||
{ |
|||
get |
|||
{ |
|||
double det = 0.0; |
|||
for (int j = 0; j < _factor.RowCount; j++) |
|||
{ |
|||
det += (2.0 * Math.Log(_factor[j, j])); |
|||
} |
|||
return det; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,51 @@ |
|||
// <copyright file="ExtensionMethods.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 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.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.LinearAlgebra.Double.Decomposition |
|||
{ |
|||
using System; |
|||
using Properties; |
|||
|
|||
/// <summary>
|
|||
/// Extension methods which return decompositions for the various matrix classes.
|
|||
/// </summary>
|
|||
public static class ExtensionMethods |
|||
{ |
|||
/// <summary>
|
|||
/// Computes the cholesky decomposition for a matrix.
|
|||
/// </summary>
|
|||
/// <param name="matrix">The matrix to factor.</param>
|
|||
/// <returns>The Cholesky decomposition object.</returns>
|
|||
public static Cholesky Cholesky(this Matrix matrix) |
|||
{ |
|||
return Decomposition.Cholesky.Create(matrix); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,98 @@ |
|||
// <copyright file="CholeskyTests.cs" company="Math.NET">
|
|||
// Math.NET Numerics, part of the Math.NET Project
|
|||
// http://numerics.mathdotnet.com
|
|||
// http://github.com/mathnet/mathnet-numerics
|
|||
// http://mathnetnumerics.codeplex.com
|
|||
//
|
|||
// Copyright (c) 2009-2010 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.
|
|||
// </copyright>
|
|||
|
|||
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double.Decomposition |
|||
{ |
|||
using System.Collections.Generic; |
|||
using MbUnit.Framework; |
|||
using LinearAlgebra.Double; |
|||
using LinearAlgebra.Double.Decomposition; |
|||
|
|||
public class CholeskyTests |
|||
{ |
|||
[Test] |
|||
[Row(1)] |
|||
[Row(10)] |
|||
[Row(100)] |
|||
[Row(1000)] |
|||
public void CanDecomposeIdentity(int order) |
|||
{ |
|||
var I = DenseMatrix.Identity(order); |
|||
var C = I.Cholesky(); |
|||
|
|||
for (var i = 0; i < C.Factor.RowCount; i++) |
|||
{ |
|||
for (var j = 0; j < C.Factor.ColumnCount; j++) |
|||
{ |
|||
if (i == j) |
|||
{ |
|||
Assert.AreEqual(1.0, C.Factor[i, j]); |
|||
} |
|||
else |
|||
{ |
|||
Assert.AreEqual(0.0, C.Factor[i, j]); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
|
|||
[Test] |
|||
[ExpectedArgumentException] |
|||
public void CholeskyFailsWithDiagonalNonPositiveDefiniteMatrix() |
|||
{ |
|||
var I = DenseMatrix.Identity(10); |
|||
I[3, 3] = -4.0; |
|||
var C = I.Cholesky(); |
|||
} |
|||
|
|||
[Test] |
|||
[Row(3,5)] |
|||
[Row(5,3)] |
|||
[ExpectedArgumentException] |
|||
public void CholeskyFailsWithNonSquareMatrix(int row, int col) |
|||
{ |
|||
var I = new DenseMatrix(row, col); |
|||
var C = I.Cholesky(); |
|||
} |
|||
|
|||
[Test] |
|||
[Row(1)] |
|||
[Row(10)] |
|||
[Row(100)] |
|||
[Row(1000)] |
|||
public void IdentityDeterminantIsOne(int order) |
|||
{ |
|||
var I = DenseMatrix.Identity(order); |
|||
var C = I.Cholesky(); |
|||
Assert.AreEqual(1.0, C.Determinant); |
|||
Assert.AreEqual(0.0, C.DeterminantLn); |
|||
} |
|||
} |
|||
} |
|||
Loading…
Reference in new issue