diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs index a216871e..df163041 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs @@ -727,39 +727,41 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// This is equivalent to the POTRF LAPACK routine. public void CholeskyFactor(double[] a, int order) { - double[] factor = new double[a.Length]; - - for (int j = 0; j < order; j++) + for (var j = 0; j < order; j++) { - double d = 0.0; + var d = 0.0; int index; - for (int k = 0; k < j; k++) - { - double s = 0.0; - int i; - for (i = 0; i < k; i++) + Parallel.For( + 0, + j, + k => + // for (var k = 0; k < j; k++) { - s += factor[i * order + k] * factor[i * order + j]; - } - int tmp = k * order; - index = tmp + j; - factor[index] = s = (a[index] - s) / factor[tmp + k]; - d += s * s; - } + var s = 0.0; + int i; + for (i = 0; i < k; i++) + { + s += a[i * order + k] * a[i * order + j]; + } + var tmp = k * order; + index = tmp + j; + a[index] = s = (a[index] - s) / a[tmp + k]; + d += s * s; + }); + index = j * order + j; d = a[index] - d; if (d <= 0.0) { throw new ArgumentException(Resources.ArgumentMatrixPositiveDefinite); } - factor[index] = System.Math.Sqrt(d); - for (int k = j + 1; k < order; k++) + + a[index] = System.Math.Sqrt(d); + for (var k = j + 1; k < order; k++) { - factor[k * order + j] = 0.0; + a[k * order + j] = 0.0; } } - - Buffer.BlockCopy(factor, 0, a, 0, factor.Length * Constants.SizeOfDouble); } public void CholeskySolve(int columnsOfB, double[] a, double[] b) diff --git a/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs b/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs index 8cf94b74..64084e68 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/LinearAlgebraProviderTests.cs @@ -2,6 +2,7 @@ { using System; using Algorithms.LinearAlgebra; + using LinearAlgebra.Double; using MbUnit.Framework; [TestFixture] @@ -176,10 +177,27 @@ } - [Test, Ignore] - public void CanComputeCholeskyFactor(double[] a, int order) + [Test] + public void CanComputeCholeskyFactor() { - + var matrix = new double[] { 1, 1, 1, 1, 1, 5, 5, 5, 1, 5, 14, 14, 1, 5, 14, 15 }; + Provider.CholeskyFactor(matrix, 4); + Assert.AreEqual(matrix[0], 1); + Assert.AreEqual(matrix[1], 1); + Assert.AreEqual(matrix[2], 1); + Assert.AreEqual(matrix[3], 1); + Assert.AreEqual(matrix[4], 0); + Assert.AreEqual(matrix[5], 2); + Assert.AreEqual(matrix[6], 2); + Assert.AreEqual(matrix[7], 2); + Assert.AreEqual(matrix[8], 0); + Assert.AreEqual(matrix[9], 0); + Assert.AreEqual(matrix[10], 3); + Assert.AreEqual(matrix[11], 3); + Assert.AreEqual(matrix[12], 0); + Assert.AreEqual(matrix[13], 0); + Assert.AreEqual(matrix[14], 0); + Assert.AreEqual(matrix[15], 1); } [Test, Ignore]