diff --git a/src/FSharpUnitTests/FsUnit.fs b/src/FSharpUnitTests/FsUnit.fs
index 09778d30..84d2eeb2 100644
--- a/src/FSharpUnitTests/FsUnit.fs
+++ b/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))
diff --git a/src/FSharpUnitTests/Program.fs b/src/FSharpUnitTests/Program.fs
index 884475dd..85dc1b6c 100644
--- a/src/FSharpUnitTests/Program.fs
+++ b/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"
diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
index c0ef53e4..1ee92e67 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
@@ -47,7 +47,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
/// the size of the square matrix.
///
- /// If is less than one.
+ /// If is less than one.
///
public DenseMatrix(int order)
: base(order)
@@ -91,13 +91,21 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
///
- /// Initializes a new instance of the class from a 2D array.
+ /// Initializes a new instance of the class from a 2D array. This constructor
+ /// will allocate a completely new memory block for storing the dense matrix.
///
/// The 2D array to create this matrix from.
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]);
+ }
+ }
}
///
diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
index 7bb13c27..1ba95145 100644
--- a/src/Numerics/LinearAlgebra/Double/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -50,6 +50,16 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
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
///
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 column in GetColumnEnumerator())
+ var denseMatrix = target as DenseMatrix;
+ if (denseMatrix != null)
{
- foreach (KeyValuePair 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;
+ }
}
///
diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs
index 7fd45cfe..c1690ed7 100644
--- a/src/Numerics/Properties/Resources.Designer.cs
+++ b/src/Numerics/Properties/Resources.Designer.cs
@@ -501,6 +501,33 @@ namespace MathNet.Numerics.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to The number of columns of a matrix must be positive..
+ ///
+ internal static string MatrixColumnsMustBePositive {
+ get {
+ return ResourceManager.GetString("MatrixColumnsMustBePositive", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The number of rows of a matrix must be positive..
+ ///
+ internal static string MatrixRowsMustBePositive {
+ get {
+ return ResourceManager.GetString("MatrixRowsMustBePositive", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to The number of rows or columns of a matrix must be positive..
+ ///
+ internal static string MatrixRowsOrColumnsMustBePositive {
+ get {
+ return ResourceManager.GetString("MatrixRowsOrColumnsMustBePositive", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to The two arguments can't be compared (maybe they are part of a partial ordering?).
///
diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx
index 4c0de2d2..6ce30845 100644
--- a/src/Numerics/Properties/Resources.resx
+++ b/src/Numerics/Properties/Resources.resx
@@ -273,4 +273,13 @@
The two arguments can't be compared (maybe they are part of a partial ordering?)
+
+ The number of columns of a matrix must be positive.
+
+
+ The number of rows of a matrix must be positive.
+
+
+ The number of rows or columns of a matrix must be positive.
+
\ No newline at end of file
diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
index 306108d8..f4b9afb8 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
+++ b/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]);
}
diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
index 656c634e..c3014dfb 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
@@ -17,12 +17,14 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[SetUp]
public void SetupDistributions()
{
+ testData = new Dictionary();
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();
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);