Browse Source

Fixed some bugs in the DenseMatrix implementation.

la-knuth
Jurgen Van Gael 17 years ago
parent
commit
e0ad31caaf
  1. 23
      src/FSharpUnitTests/FsUnit.fs
  2. 4
      src/FSharpUnitTests/Program.fs
  3. 14
      src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
  4. 34
      src/Numerics/LinearAlgebra/Double/Matrix.cs
  5. 27
      src/Numerics/Properties/Resources.Designer.cs
  6. 9
      src/Numerics/Properties/Resources.resx
  7. 2
      src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
  8. 8
      src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs

23
src/FSharpUnitTests/FsUnit.fs

@ -146,6 +146,27 @@ module SpecOps =
else Fail (sprintf "Expected actual to be same reference as expected %A" other))
(sprintf "Expected %A to have different reference than %A" x other)
let array_equal (expected: float []) (actual: float []) =
make (fun () ->
let mutable f = true
for i=0 to expected.Length-1 do
f <- f && (expected.[i] = actual.[i])
if f
then Pass
else Fail (sprintf "Expected: %A\nActual: %A" expected actual))
(sprintf "NOT Expected: %A\nActual: %A" expected actual)
let array2_equal (expected: float [,]) (actual: float [,]) =
make (fun () ->
let mutable f = true
for i=0 to expected.GetLength(0)-1 do
for j=0 to expected.GetLength(1)-1 do
f <- f && (expected.[i,j] = actual.[i,j])
if f
then Pass
else Fail (sprintf "Expected: %A\nActual: %A" expected actual))
(sprintf "NOT Expected: %A\nActual: %A" expected actual)
let approximately_equal (places : int) (expected: float) (actual: float) =
make (fun () ->
if Precision.AlmostEqualInDecimalPlaces(actual, expected, places)
@ -157,7 +178,7 @@ module SpecOps =
make (fun () ->
let mutable f = true
for i=0 to expected.Count-1 do
f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i], actual.[i], places)
f <- f && Precision.AlmostEqualInDecimalPlaces(expected.[i], actual.[i], places)
if f
then Pass
else Fail (sprintf "Expected: %A\nActual: %A" expected actual))

4
src/FSharpUnitTests/Program.fs

@ -36,7 +36,7 @@ let VectorTests =
specs "Vector" [
spec "Vector.to_array"
(Vector.to_array smallv |> should equal [|0.3;0.3;0.3;0.3;0.3|])
(Vector.to_array smallv |> should array_equal [|0.3;0.3;0.3;0.3;0.3|])
spec "Vector.to_list"
(Vector.to_list smallv |> should equal [0.3;0.3;0.3;0.3;0.3])
spec "Vector.mapInPlace"
@ -97,7 +97,7 @@ let MatrixTests =
spec "Matrix.foldi"
(Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2)
spec "Matrix.toArray2"
(Matrix.toArray2 smallM |> should equal (Array2D.create 2 2 0.3))
(Matrix.toArray2 smallM |> should array2_equal (Array2D.create 2 2 0.3))
spec "Matrix.forall"
(Matrix.forall (fun x -> x = 0.3) smallM |> should equal true)
spec "Matrix.exists"

14
src/Numerics/LinearAlgebra/Double/DenseMatrix.cs

@ -47,7 +47,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <param name="order">the size of the square matrix.</param>
/// <exception cref="ArgumentException">
/// If <paramref name="size"/> is less than one.
/// If <paramref name="order"/> is less than one.
/// </exception>
public DenseMatrix(int order)
: base(order)
@ -91,13 +91,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Initializes a new instance of the <see cref="DenseMatrix"/> class from a 2D array.
/// Initializes a new instance of the <see cref="DenseMatrix"/> class from a 2D array. This constructor
/// will allocate a completely new memory block for storing the dense matrix.
/// </summary>
/// <param name="array">The 2D array to create this matrix from.</param>
public DenseMatrix(double[,] array)
: base(array.GetLength(0), array.GetLength(1))
{
throw new NotImplementedException();
Data = new double[array.GetLength(0) * array.GetLength(1)];
for (int i = 0; i < array.GetLength(0); i++)
{
for (int j = 0; j < array.GetLength(1); j++)
{
At(i, j, array[i,j]);
}
}
}
/// <summary>

34
src/Numerics/LinearAlgebra/Double/Matrix.cs

@ -50,6 +50,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param>
protected Matrix(int rows, int columns)
{
if (rows <= 0)
{
throw new ArgumentOutOfRangeException(Resources.MatrixRowsMustBePositive);
}
if (columns <= 0)
{
throw new ArgumentOutOfRangeException(Resources.MatrixColumnsMustBePositive);
}
RowCount = rows;
ColumnCount = columns;
}
@ -62,6 +72,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </param>
protected Matrix(int order)
{
if (order <= 0)
{
throw new ArgumentOutOfRangeException(Resources.MatrixRowsOrColumnsMustBePositive);
}
RowCount = order;
ColumnCount = order;
}
@ -175,16 +190,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException("target", Resources.ArgumentMatrixSameDimensions);
}
throw new NotImplementedException();
/*
foreach (KeyValuePair<int, Vector> column in GetColumnEnumerator())
var denseMatrix = target as DenseMatrix;
if (denseMatrix != null)
{
foreach (KeyValuePair<int, double> element in column.Value.GetIndexedEnumerator())
// TODO this assumes that all entries matter; if "this" is a sparse matrix,
// we might be able to optimize the copying a bit.
for (int i = 0; i < RowCount; i++)
{
target.ValueAt(element.Key, column.Key, element.Value);
for (int j = 0; j < ColumnCount; j++)
{
denseMatrix.At(i, j, this.At(i, j));
}
}
}*/
return;
}
}
/// <summary>

27
src/Numerics/Properties/Resources.Designer.cs

@ -501,6 +501,33 @@ namespace MathNet.Numerics.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to The number of columns of a matrix must be positive..
/// </summary>
internal static string MatrixColumnsMustBePositive {
get {
return ResourceManager.GetString("MatrixColumnsMustBePositive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The number of rows of a matrix must be positive..
/// </summary>
internal static string MatrixRowsMustBePositive {
get {
return ResourceManager.GetString("MatrixRowsMustBePositive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The number of rows or columns of a matrix must be positive..
/// </summary>
internal static string MatrixRowsOrColumnsMustBePositive {
get {
return ResourceManager.GetString("MatrixRowsOrColumnsMustBePositive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to The two arguments can&apos;t be compared (maybe they are part of a partial ordering?).
/// </summary>

9
src/Numerics/Properties/Resources.resx

@ -273,4 +273,13 @@
<data name="PartialOrderException" xml:space="preserve">
<value>The two arguments can't be compared (maybe they are part of a partial ordering?)</value>
</data>
<data name="MatrixColumnsMustBePositive" xml:space="preserve">
<value>The number of columns of a matrix must be positive.</value>
</data>
<data name="MatrixRowsMustBePositive" xml:space="preserve">
<value>The number of rows of a matrix must be positive.</value>
</data>
<data name="MatrixRowsOrColumnsMustBePositive" xml:space="preserve">
<value>The number of rows or columns of a matrix must be positive.</value>
</data>
</root>

2
src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs

@ -29,7 +29,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
var matrix = new DenseMatrix(testData[name]);
for (var i = 0; i < testData[name].GetLength(0); i++)
{
for (var j = 0; j < testData[name].GetLength(0); j++)
for (var j = 0; j < testData[name].GetLength(1); j++)
{
Assert.AreEqual(testData[name][i,j], matrix[i,j]);
}

8
src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs

@ -17,12 +17,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[SetUp]
public void SetupDistributions()
{
testData = new Dictionary<string, double[,]>();
testData.Add("Singular3x3", new double[,] { { 1, 1, 2 }, { 1, 1, 2 }, { 1, 1, 2 } });
testData.Add("Square3x3", new double[,] { { -1.1, -2.2, -3.3 }, { 0, 1.1, 2.2 }, { -4.4, 5.5, 6.6 } });
testData.Add("Square4x4", new double[,] { { -1.1, -2.2, -3.3, -4.4 }, { 0, 1.1, 2.2, 3.3 }, { -4.4, 5.5, 6.6, -7.7 } });
testData.Add("Tall3x2", new double[,] { { -1.1, -2.2 }, { 0, 1.1 }, { -4.4, 5.5 } });
testData.Add("Wide2x3", new double[,] { { -1.1, -2.2, -3.3 }, { 0, 1.1, 2.2 } });
testMatrices = new Dictionary<string, Matrix>();
foreach(var name in testData.Keys)
{
testMatrices.Add(name, CreateMatrix(testData[name]));
@ -46,7 +48,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.AreEqual(matrix.ColumnCount, clone.ColumnCount);
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.RowCount; j++)
for (var j = 0; j < matrix.ColumnCount; j++)
{
Assert.AreEqual(matrix[i,j], clone[i,j]);
}
@ -70,7 +72,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.AreEqual(matrix.ColumnCount, clone.ColumnCount);
for (var i = 0; i < matrix.RowCount; i++)
{
for (var j = 0; j < matrix.RowCount; j++)
for (var j = 0; j < matrix.ColumnCount; j++)
{
Assert.AreEqual(matrix[i, j], clone[i, j]);
}
@ -112,7 +114,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
[Row(0, 2)]
[Row(-1, 1)]
[ExpectedArgumentException]
[ExpectedArgumentOutOfRangeException]
public void ThrowsArgumentExceptionIfSizeIsNotPositive(int rows, int columns)
{
var A = CreateMatrix(rows, columns);

Loading…
Cancel
Save