diff --git a/build/build.proj b/build/build.proj index 5367046e..5fdac875 100644 --- a/build/build.proj +++ b/build/build.proj @@ -58,7 +58,7 @@ - + diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index b820241f..daf377e2 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -82,7 +82,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// copying the values from another. /// /// - /// The matrix to create the new matrix from. + /// The vector to create the new vector from. /// public DenseVector(Vector other) : this(other.Count) @@ -98,6 +98,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } + /// + /// Initializes a new instance of the class by + /// copying the values from another. + /// + /// + /// The vector to create the new vector from. + /// + public DenseVector(DenseVector other) + : this(other.Count) + { + Buffer.BlockCopy(other.Data, 0, Data, 0, Data.Length * Constants.SizeOfDouble); + } + /// /// Initializes a new instance of the class for an array. /// @@ -603,10 +616,66 @@ namespace MathNet.Numerics.LinearAlgebra.Double { return; } - Control.LinearAlgebraProvider.ScaleArray(scalar, Data); } + /// + /// Multiplies a vector with a scalar. + /// + /// The vector to scale. + /// The scalar value. + /// The result of the multiplication. + /// If is . + public static DenseVector operator *(DenseVector leftSide, double rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + var ret = (DenseVector)leftSide.Clone(); + ret.Multiply(rightSide); + return ret; + } + + /// + /// Multiplies a vector with a scalar. + /// + /// The scalar value. + /// The vector to scale. + /// The result of the multiplication. + /// If is . + public static DenseVector operator *(double leftSide, DenseVector rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + var ret = (DenseVector)rightSide.Clone(); + ret.Multiply(leftSide); + return ret; + } + + /// + /// Divides a vector with a scalar. + /// + /// The vector to divide. + /// The scalar value. + /// The result of the division. + /// If is . + public static DenseVector operator /(DenseVector leftSide, double rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + var ret = (DenseVector)leftSide.Clone(); + ret.Multiply(1.0 / rightSide); + return ret; + } + #region Vector Norms /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs index e1d88f5d..d90a1242 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs @@ -25,19 +25,67 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [Test] [MultipleAsserts] - public void CanCreateVectorFromArray() + public void CanCreateDenseVectorFromArray() { - var data = new[] { 1.0, 2.0, 3.0, 4.0 }; - var vector = new DenseVector(data); - Assert.AreSame(data, vector.Data); - for( var i = 0; i < data.Length; i++) + var vector = new DenseVector(_data); + Assert.AreSame(_data, vector.Data); + for (var i = 0; i < _data.Length; i++) { - Assert.AreEqual(data[i], vector[i]); + Assert.AreEqual(_data[i], vector[i]); } vector[0] = 100.0; - Assert.AreEqual(100.0, data[0]); + Assert.AreEqual(100.0, _data[0]); } + [Test] + [MultipleAsserts] + public void CanCreateDenseVectorFromAnotherDenseVector() + { + var vector = new DenseVector(_data); + var other = new DenseVector(vector); + + + Assert.AreNotSame(vector, other); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(vector[i], other[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanCreateDenseVectorFromAnotherVector() + { + var vector = (Vector)new DenseVector(_data); + var other = new DenseVector(vector); + + Assert.AreNotSame(vector, other); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(vector[i], other[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanCreateDenseVectorFromUserDefinedVector() + { + var vector = new UserDefinedVector(_data); + var other = new DenseVector(vector); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(vector[i], other[i]); + } + } + + [Test] + public void CanCreateDenseVectorWithConstantValues() + { + var vector = new DenseVector(5, 5); + Assert.ForAll(vector, value => value == 5); + } + [Test] [MultipleAsserts] public void CanCreateDenseMatrix() @@ -53,8 +101,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double [MultipleAsserts] public void CanConvertDenseVectorToArray() { - var data = new[] { 0.0, 1.0, 2.0, 3.0, 4.0 }; - var vector = new DenseVector(data); + var vector = new DenseVector(_data); var array = (double[])vector; Assert.IsInstanceOfType(typeof(double[]), array); Assert.AreSame(vector.Data, array); @@ -70,5 +117,108 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.IsInstanceOfType(typeof(DenseVector), vector); Assert.AreElementsEqual(array, array); } + + [Test] + public void CanCallUnaryPlusOperatorOnDenseVector() + { + var vector = new DenseVector(_data); + var other = +vector; + Assert.AreSame(vector, other, "Should be the same vector"); + } + + [Test] + [MultipleAsserts] + public void CanAddTwoDenseVectorsUsingOperator() + { + var vector = new DenseVector(_data); + var other = new DenseVector(_data); + var result = vector + other; + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(_data[i] * 2.0, result[i]); + } + } + + [Test] + public void CanCallUnaryNegationOperatorOnDenseVector() + { + var vector = new DenseVector(_data); + var other = -vector; + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(-_data[i], other[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractTwoDenseVectorsUsingOperator() + { + var vector = new DenseVector(_data); + var other = new DenseVector(_data); + var result = vector - other; + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(0.0, result[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanMultiplyDenseVectorByScalarUsingOperators() + { + var vector = new DenseVector(_data); + vector = vector * 2.0; + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + + vector = vector * 1.0; + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + + vector = new DenseVector(_data); + vector = 2.0 * vector; + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + + vector = 1.0 * vector; + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanDivideDenseVectorByScalarUsingOperators() + { + var vector = new DenseVector(_data); + vector = vector / 2.0; + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] / 2.0, vector[i]); + } + + vector = vector / 1.0; + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] / 2.0, vector[i]); + } + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs index 19926be7..46a0f88f 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs @@ -13,6 +13,12 @@ _data = new double[size]; } + public UserDefinedVector(double[] data) + : base(data.Length) + { + _data = data; + } + public override double this[int index] { get diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 3662ab0f..f1877d40 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -10,7 +10,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double public abstract partial class VectorTests { - private readonly double[] _data = {1, 2, 3, 4, 5}; + protected readonly double[] _data = {1, 2, 3, 4, 5}; [Test] [MultipleAsserts] @@ -111,31 +111,22 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } [Test] - [MultipleAsserts] public void CanEnumerateOverVector() { var vector = CreateVector(_data); - var index = 0; + Assert.AreElementsEqual(_data, vector); - foreach (var element in vector) - { - Assert.AreEqual(index + 1, element); - index++; - } } [Test] [MultipleAsserts] public void CanEnumerateOverVectorUsingIEnumerable() { - var vector = CreateVector(_data); + var enumerable = (IEnumerable)CreateVector(_data); var index = 0; - - var enumerable = (IEnumerable)vector; foreach (var element in enumerable) { - Assert.AreEqual(index + 1, (double)element); - index++; + Assert.AreEqual(_data[index++], (double)element); } }