diff --git a/src/.gitignore b/src/.gitignore index becc3258..939ed403 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -3,3 +3,4 @@ bin obj *.user *.suo +*.vsdoc diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 8c8cb872..e28f45f7 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -90,11 +90,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double var vector = other as DenseVector; if (vector == null) { - // using enumerators since they will be more efficient for copying sparse matrices - // foreach (var item in other.GetIndexedEnumerator()) - // { - // Data[item.Key] = item.Value; - // } Parallel.For(0, Count, index => this[index] = other[index]); } else @@ -115,15 +110,81 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Gets the vector's data. + /// Gets the vector's internal data. /// - /// The vector's data. + /// The vector's internal data. + /// Changing values in the array also changes the corresponding value in vector. Use with care. internal double[] Data { get; private set; } + /// + /// Returns a reference to the internal data structure. + /// + /// The DenseVector whose internal data we are + /// returning. + /// + /// A reference to the internal date of the given vector. + /// + public static implicit operator double[](DenseVector vector) + { + if (vector == null) + { + throw new ArgumentNullException(); + } + + return vector.Data; + } + + /// + /// Returns a vector bound directly to a reference of the provided array. + /// + /// The array to bind to the DenseVector object. + /// + /// A DenseVector whose values are bound to the given array. + /// + public static implicit operator DenseVector(double[] array) + { + if (array == null) + { + throw new ArgumentNullException(); + } + + return new DenseVector(array); + } + + /// + /// Create a matrix based on this vector in column form (one single column). + /// + /// This vector as a column matrix. + public override Matrix ToColumnMatrix() + { + var matrix = new DenseMatrix(Count, 1); + for (var i = 0; i < Data.Length; i++) + { + matrix[i, 0] = Data[i]; + } + + return matrix; + } + + /// + /// Create a matrix based on this vector in row form (one single row). + /// + /// This vector as a row matrix. + public override Matrix ToRowMatrix() + { + var matrix = new DenseMatrix(1, Count); + for (var i = 0; i < Data.Length; i++) + { + matrix[0, i] = Data[i]; + } + + return matrix; + } + /// Gets or sets the value at the given . /// The index of the value to get or set. /// The value of the vector at the given . @@ -196,7 +257,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != target.Count) { - throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target"); } var otherVector = target as DenseVector; @@ -243,7 +304,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != result.Count) { - throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); } CopyTo(result); @@ -265,7 +326,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != other.Count) { - throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } var denseVector = other as DenseVector; @@ -298,12 +359,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != other.Count) { - throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } if (Count != result.Count) { - throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); } if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) @@ -358,7 +419,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (leftSide.Count != rightSide.Count) { - throw new ArgumentException("rightSide", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide"); } var ret = leftSide.Clone(); @@ -396,7 +457,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != result.Count) { - throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); } CopyTo(result); @@ -418,7 +479,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != other.Count) { - throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } var denseVector = other as DenseVector; @@ -451,12 +512,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != other.Count) { - throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } if (Count != result.Count) { - throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); } if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) @@ -510,7 +571,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (leftSide.Count != rightSide.Count) { - throw new ArgumentException("rightSide", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide"); } var ret = leftSide.Clone(); diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 82de26ca..412bd298 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -719,7 +719,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != target.Count) { - throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "target"); } if (ReferenceEquals(this, target)) @@ -784,6 +784,51 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } + /// + /// Returns the data contained in the vector as an array. + /// + /// The vector's data as an array. + public virtual double[] ToArray() + { + var ret = new double[Count]; + for (var i = 0; i < ret.Length; i++) + { + ret[i] = this[i]; + } + + return ret; + } + + /// + /// Create a matrix based on this vector in column form (one single column). + /// + /// This vector as a column matrix. + public virtual Matrix ToColumnMatrix() + { + var matrix = CreateMatrix(Count, 1); + for (var i = 0; i < Count; i++) + { + matrix[i, 0] = this[i]; + } + + return matrix; + } + + /// + /// Create a matrix based on this vector in row form (one single row). + /// + /// This vector as a row matrix. + public virtual Matrix ToRowMatrix() + { + var matrix = CreateMatrix(1, Count); + for (var i = 0; i < Count; i++) + { + matrix[0, i] = this[i]; + } + + return matrix; + } + #endregion #region Implemented Interfaces diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs index 2fed73ab..e1d88f5d 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs @@ -40,12 +40,35 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] [MultipleAsserts] - public void CanCreateMatrix() + public void CanCreateDenseMatrix() { var vector = new DenseVector(3); var matrix = vector.CreateMatrix(2, 3); Assert.AreEqual(2, matrix.RowCount); Assert.AreEqual(3, matrix.ColumnCount); } + + + [Test] + [MultipleAsserts] + public void CanConvertDenseVectorToArray() + { + var data = new[] { 0.0, 1.0, 2.0, 3.0, 4.0 }; + var vector = new DenseVector(data); + var array = (double[])vector; + Assert.IsInstanceOfType(typeof(double[]), array); + Assert.AreSame(vector.Data, array); + Assert.AreElementsEqual(vector, array); + } + + [Test] + [MultipleAsserts] + public void CanConvertArrayToDenseVector() + { + var array = new[] { 0.0, 1.0, 2.0, 3.0, 4.0 }; + var vector = (DenseVector)array; + Assert.IsInstanceOfType(typeof(DenseVector), vector); + Assert.AreElementsEqual(array, array); + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 8cb09f38..f8390ec0 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -161,6 +161,48 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } + [Test] + [MultipleAsserts] + public void CanConvertVectorToArray() + { + var vector = new DenseVector(_data); + var array = vector.ToArray(); + Assert.AreNotSame(array, vector.Data); + Assert.AreElementsEqual(vector, array); + } + + [Test] + [MultipleAsserts] + public void CanConvertVectorToColumnMatrix() + { + var vector = new DenseVector(_data); + var matrix = vector.ToColumnMatrix(); + + Assert.AreEqual(vector.Count, matrix.RowCount); + Assert.AreEqual(1, matrix.ColumnCount); + + for(var i = 0; i < vector.Count; i++) + { + Assert.AreEqual(vector[i], matrix[i, 0]); + } + } + + [Test] + [MultipleAsserts] + public void CanConvertVectorToRowMatrix() + { + var vector = new DenseVector(_data); + var matrix = vector.ToRowMatrix(); + + Assert.AreEqual(vector.Count, matrix.ColumnCount); + Assert.AreEqual(1, matrix.RowCount); + + for (var i = 0; i < vector.Count; i++) + { + Assert.AreEqual(vector[i], matrix[0, i]); + } + } + protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(IList data);