diff --git a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
index 5e8930d4..d5294bc6 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseMatrix.cs
@@ -78,7 +78,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
///
/// The number of columns.
- ///
/// The value which we assign to each element of the matrix.
public DenseMatrix(int rows, int columns, double value)
: base(rows, columns)
@@ -95,7 +95,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// will reference the one dimensional array and not copy it.
///
/// The number of rows.
- /// The number of columns.The number of columns.
/// The one dimensional array to create this matrix from. This array should store the matrix in column-major order.
public DenseMatrix(int rows, int columns, double[] array)
: base(rows, columns)
@@ -148,6 +148,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return new DenseMatrix(numberOfRows, numberOfColumns);
}
+ ///
+ /// Creates a with a the given dimension.
+ ///
+ /// The size of the vector.
+ ///
+ /// A with the given dimension.
+ ///
+ public override Vector CreateVector(int size)
+ {
+ return new DenseVector(size);
+ }
+
///
/// Retrieves the requested element without range checking.
///
diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs
index 03f2dce7..2ac79729 100644
--- a/src/Numerics/LinearAlgebra/Double/Matrix.cs
+++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs
@@ -194,7 +194,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
if (RowCount != target.RowCount || ColumnCount != target.ColumnCount)
{
- throw new ArgumentException(Resources.ArgumentMatrixSameDimensions, "target");
+ throw new ArgumentException(Resources.ArgumentMatrixDimensions, "target");
}
// TODO this assumes that all entries matter; if "this" is a sparse matrix,
@@ -225,6 +225,18 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
public abstract Matrix CreateMatrix(int numberOfRows, int numberOfColumns);
+ ///
+ /// Creates a with a the given dimension.
+ ///
+ /// The size of the vector.
+ ///
+ /// A with the given dimension.
+ ///
+ ///
+ /// Creates a vector of the same type as the current matrix.
+ ///
+ public abstract Vector CreateVector(int size);
+
///
/// Returns a that represents this instance.
///
@@ -236,6 +248,211 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return ToString(null, null);
}
+ ///
+ /// Copies a row into an .
+ ///
+ /// The row to copy.
+ /// A containing the copied elements.
+ /// If is negative,
+ /// or greater than or equal to the number of rows.
+ public virtual Vector GetRow(int index)
+ {
+ Vector ret = CreateVector(ColumnCount);
+ GetRow(index, 0, ColumnCount, ret);
+ return ret;
+ }
+
+ ///
+ /// Copies a row into to the given .
+ ///
+ /// The row to copy.
+ /// The to copy the row into.
+ /// If the result vector is .
+ /// If is negative,
+ /// or greater than or equal to the number of rows.
+ /// If this.Columns != result.Count.
+ public virtual void GetRow(int index, Vector result)
+ {
+ GetRow(index, 0, ColumnCount, result);
+ }
+
+ ///
+ /// Copies the requested row elements into a new .
+ ///
+ /// The row to copy elements from.
+ /// The column to start copying from.
+ /// The number of elements to copy.
+ /// A containing the requested elements.
+ /// If:
+ /// - is negative,
+ /// or greater than or equal to the number of rows.
+ /// - is negative,
+ /// or greater than or equal to the number of columns.
+ /// - (columnIndex + length) >= Columns.
+ /// If is not positive.
+ public virtual Vector GetRow(int rowIndex, int columnIndex, int length)
+ {
+ Vector ret = CreateVector(length);
+ GetRow(rowIndex, columnIndex, length, ret);
+ return ret;
+ }
+
+ ///
+ /// Copies the requested row elements into a new .
+ ///
+ /// The row to copy elements from.
+ /// The column to start copying from.
+ /// The number of elements to copy.
+ /// The to copy the column into.
+ /// If the result is .
+ /// If is negative,
+ /// or greater than or equal to the number of columns.
+ /// If is negative,
+ /// or greater than or equal to the number of rows.
+ /// If +
+ /// is greater than or equal to the number of rows.
+ /// If is not positive.
+ /// If result.Count < length.
+ public virtual void GetRow(int rowIndex, int columnIndex, int length, Vector result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (rowIndex >= RowCount || rowIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+ if (columnIndex >= ColumnCount || columnIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+
+ if (columnIndex + length > ColumnCount)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+
+ if (length < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
+ }
+
+ if (result.Count < length)
+ {
+ throw new ArgumentException("result", Resources.ArgumentVectorsSameLength);
+ }
+
+ for (int i = columnIndex, j = 0; i < columnIndex + length; i++, j++)
+ {
+ result[j] = At(rowIndex, i);
+ }
+ }
+
+ ///
+ /// Copies a column into a new .
+ ///
+ /// The column to copy.
+ /// A containing the copied elements.
+ /// If is negative,
+ /// or greater than or equal to the number of columns.
+ public virtual Vector GetColumn(int index)
+ {
+ Vector result = CreateVector(RowCount);
+ GetColumn(index, 0, RowCount, result);
+ return result;
+ }
+
+ ///
+ /// Copies a column into to the given .
+ ///
+ /// The column to copy.
+ /// The to copy the column into.
+ /// If the result is .
+ /// If is negative,
+ /// or greater than or equal to the number of columns.
+ /// If this.Rows != result.Count.
+ public virtual void GetColumn(int index, Vector result)
+ {
+ GetColumn(index, 0, RowCount, result);
+ }
+
+ ///
+ /// Copies the requested column elements into a new .
+ ///
+ /// The column to copy elements from.
+ /// The row to start copying from.
+ /// The number of elements to copy.
+ /// A containing the requested elements.
+ /// If:
+ /// - is negative,
+ /// or greater than or equal to the number of columns.
+ /// - is negative,
+ /// or greater than or equal to the number of rows.
+ /// - (rowIndex + length) >= Rows.
+ ///
+ /// If is not positive.
+ public virtual Vector GetColumn(int columnIndex, int rowIndex, int length)
+ {
+ Vector result = CreateVector(length);
+ GetColumn(columnIndex, rowIndex, length, result);
+ return result;
+ }
+
+ ///
+ /// Copies the requested column elements into the given vector.
+ ///
+ /// The column to copy elements from.
+ /// The row to start copying from.
+ /// The number of elements to copy.
+ /// The to copy the column into.
+ /// If the result is .
+ /// If is negative,
+ /// or greater than or equal to the number of columns.
+ /// If is negative,
+ /// or greater than or equal to the number of rows.
+ /// If +
+ /// is greater than or equal to the number of rows.
+ /// If is not positive.
+ /// If result.Count < length.
+ public virtual void GetColumn(int columnIndex, int rowIndex, int length, Vector result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (columnIndex >= ColumnCount || columnIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("columnIndex");
+ }
+ if (rowIndex >= RowCount || rowIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("rowIndex");
+ }
+
+ if (rowIndex + length > RowCount)
+ {
+ throw new ArgumentOutOfRangeException("length");
+ }
+
+ if (length < 1)
+ {
+ throw new ArgumentException(Resources.ArgumentMustBePositive, "length");
+ }
+
+ if (result.Count < length)
+ {
+ throw new ArgumentException("result", Resources.ArgumentVectorsSameLength);
+ }
+
+ for (int i = rowIndex, j = 0; i < rowIndex + length; i++, j++)
+ {
+ result[j] = At(i, columnIndex);
+ }
+ }
+
#region Implemented Interfaces
#if !SILVERLIGHT
diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
index ff88a696..e9b4562f 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/DenseMatrixTests.cs
@@ -17,6 +17,16 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
return new DenseMatrix(data);
}
+ protected override Vector CreateVector(int size)
+ {
+ return new DenseVector(size);
+ }
+
+ protected override Vector CreateVector(double[] data)
+ {
+ return new DenseVector(data);
+ }
+
[Test]
public void CanCreateMatrixFrom1DArray()
{
diff --git a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
index 94224489..22a2476d 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/MatrixTests.cs
@@ -14,6 +14,8 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
protected abstract Matrix CreateMatrix(int rows, int columns);
protected abstract Matrix CreateMatrix(double[,] data);
+ protected abstract Vector CreateVector(int size);
+ protected abstract Vector CreateVector(double[] data);
[SetUp]
public void SetupMatrices()
@@ -115,7 +117,10 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
[Test]
[Row(0, 2)]
+ [Row(2, 0)]
+ [Row(0, 0)]
[Row(-1, 1)]
+ [Row(1, -1)]
[ExpectedArgumentOutOfRangeException]
public void ThrowsArgumentExceptionIfSizeIsNotPositive(int rows, int columns)
{
@@ -177,6 +182,230 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
}
+ [Test]
+ [Row(0, "Singular3x3")]
+ [Row(1, "Singular3x3")]
+ [Row(2, "Singular3x3")]
+ [Row(2, "Square3x3")]
+ public void CanGetRow(int rowIndex, string name)
+ {
+ var matrix = testMatrices[name];
+ var row = matrix.GetRow(rowIndex);
+
+ Assert.AreEqual(matrix.ColumnCount, row.Count);
+ for (int j = 0; j < matrix.ColumnCount; j++)
+ {
+ Assert.AreEqual(matrix[rowIndex, j], row[j]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetRowThrowsArgumentOutOfRangeWithNegativeIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetRow(-1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetRowThrowsArgumentOutOfRangeWithOverflowingRowIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetRow(matrix.RowCount);
+ }
+
+ [Test]
+ [Row(0, "Singular3x3")]
+ [Row(1, "Singular3x3")]
+ [Row(2, "Singular3x3")]
+ [Row(2, "Square3x3")]
+ public void CanGetRowWithResult(int rowIndex, string name)
+ {
+ var matrix = testMatrices[name];
+ var row = CreateVector(matrix.ColumnCount);
+ matrix.GetRow(rowIndex, row);
+
+ Assert.AreEqual(matrix.ColumnCount, row.Count);
+ for (int j = 0; j < matrix.ColumnCount; j++)
+ {
+ Assert.AreEqual(matrix[rowIndex, j], row[j]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void GetRowWithResultFailsWhenResultIsNull()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetRow(0, null);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetRowWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var row = CreateVector(matrix.ColumnCount);
+ matrix.GetRow(-1, row);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetRowWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var row = CreateVector(matrix.ColumnCount);
+ matrix.GetRow(matrix.RowCount, row);
+ }
+
+ [Test]
+ [Row(0, 0, 1, "Singular3x3")]
+ [Row(1, 1, 2, "Singular3x3")]
+ [Row(2, 0, 3, "Singular3x3")]
+ [Row(2, 0, 3, "Square3x3")]
+ public void CanGetRowWithRange(int rowIndex, int start, int length, string name)
+ {
+ var matrix = testMatrices[name];
+ var row = matrix.GetRow(rowIndex, start, length);
+
+ Assert.AreEqual(length, row.Count);
+ for (int j = start; j < start + length; j++)
+ {
+ Assert.AreEqual(matrix[rowIndex, j], row[j - start]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException))]
+ public void GetRowWithRangeResultArgumentExeptionWhenLengthIsZero()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var result = CreateVector(matrix.ColumnCount);
+ matrix.GetRow(0, 0, 0, result);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException))]
+ public void GetRowWithRangeFailsWithTooSmallResultVector()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var result = CreateVector(matrix.ColumnCount - 1);
+ matrix.GetRow(0, 0, 0, result);
+ }
+
+ [Test]
+ [Row(0, "Singular3x3")]
+ [Row(1, "Singular3x3")]
+ [Row(2, "Singular3x3")]
+ [Row(2, "Square3x3")]
+ public void CanGetColumn(int colIndex, string name)
+ {
+ var matrix = testMatrices[name];
+ var col = matrix.GetColumn(colIndex);
+
+ Assert.AreEqual(matrix.RowCount, col.Count);
+ for (int j = 0; j < matrix.RowCount; j++)
+ {
+ Assert.AreEqual(matrix[j, colIndex], col[j]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetColumnThrowsArgumentOutOfRangeWithNegativeIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetColumn(-1);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetColumnThrowsArgumentOutOfRangeWithOverflowingRowIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetColumn(matrix.ColumnCount);
+ }
+
+ [Test]
+ [Row(0, "Singular3x3")]
+ [Row(1, "Singular3x3")]
+ [Row(2, "Singular3x3")]
+ [Row(2, "Square3x3")]
+ public void CanGetColumnWithResult(int colIndex, string name)
+ {
+ var matrix = testMatrices[name];
+ var col = CreateVector(matrix.RowCount);
+ matrix.GetColumn(colIndex, col);
+
+ Assert.AreEqual(matrix.RowCount, col.Count);
+ for (int j = 0; j < matrix.RowCount; j++)
+ {
+ Assert.AreEqual(matrix[j, colIndex], col[j]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentNullException))]
+ public void GetColumnFailsWhenResultIsNull()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ matrix.GetColumn(0, null);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetColumnWithResultThrowsArgumentOutOfRangeWithNegativeIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var column = CreateVector(matrix.ColumnCount);
+ matrix.GetColumn(-1, column);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentOutOfRangeException))]
+ public void GetColumnWithResultThrowsArgumentOutOfRangeWithOverflowingRowIndex()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var column = CreateVector(matrix.RowCount);
+ matrix.GetRow(matrix.ColumnCount, column);
+ }
+
+ [Test]
+ [Row(0, 0, 1, "Singular3x3")]
+ [Row(1, 1, 2, "Singular3x3")]
+ [Row(2, 0, 3, "Singular3x3")]
+ [Row(2, 0, 3, "Square3x3")]
+ public void CanGetColumnWithRange(int colIndex, int start, int length, string name)
+ {
+ var matrix = testMatrices[name];
+ var col = matrix.GetColumn(colIndex, start, length);
+
+ Assert.AreEqual(length, col.Count);
+ for (int j = start; j < start+length; j++)
+ {
+ Assert.AreEqual(matrix[j, colIndex], col[j - start]);
+ }
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException))]
+ public void GetColumnWithRangeResultArgumentExeptionWhenLengthIsZero()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ var col = CreateVector(matrix.RowCount);
+ matrix.GetColumn(0, 0, 0, col);
+ }
+
+ [Test]
+ [ExpectedException(typeof(ArgumentException))]
+ public void GetColumnWithRangeFailsWithTooSmallResultVector()
+ {
+ var matrix = testMatrices["Singular3x3"];
+ Vector result = CreateVector(matrix.RowCount - 1);
+ matrix.GetColumn(0, 0, matrix.RowCount, result);
+ }
+
#region Elementary operations
[Test]
[Row("Singular3x3", "Square3x3")]
diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs
index a9893e0c..37a5f925 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedMatrixTests.cs
@@ -30,6 +30,11 @@
{
return new UserDefinedMatrix(numberOfRows, numberOfColumns);
}
+
+ public override Vector CreateVector(int size)
+ {
+ return new UserDefinedVector(size);
+ }
}
public class UserDefinedMatrixTests : MatrixTests
@@ -43,5 +48,15 @@
{
return new UserDefinedMatrix(data);
}
+
+ protected override Vector CreateVector(int size)
+ {
+ return new UserDefinedVector(size);
+ }
+
+ protected override Vector CreateVector(double[] data)
+ {
+ return new UserDefinedVector(data);
+ }
}
}