From ce54b3eba4e98d89095a35c7ef6b2ad2ad1dfa60 Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Tue, 18 Aug 2009 15:46:08 +0800 Subject: [PATCH] Vector: added norm methods and broke up unit tests Signed-off-by: Marcus Cuda --- .../LinearAlgebra/Double/DenseVector.cs | 80 +++ src/Numerics/LinearAlgebra/Double/Vector.cs | 548 +++++++++------ .../Double/VectorTests.Arithmetic.cs | 634 ++++++++++++++++++ .../Double/VectorTests.Norm.cs | 59 ++ .../LinearAlgebraTests/Double/VectorTests.cs | 625 +---------------- src/UnitTests/UnitTests.csproj | 2 + 6 files changed, 1101 insertions(+), 847 deletions(-) create mode 100644 src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs create mode 100644 src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 7985ecfa..1ec221b0 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -543,5 +543,85 @@ namespace MathNet.Numerics.LinearAlgebra.Double _linearAlgebra.ScaleArray(scalar, Data); } + + #region Vector Norms + + /// + /// Euclidean Norm also known as 2-Norm. + /// + /// Scalar ret = sqrt(sum(this[i]^2)) + public override double Norm() + { + var sum = 0.0; + for (var i = 0; i < Data.Length; i++) + { + sum = SpecialFunctions.Hypotenuse(sum, Data[i]); + } + + return sum; + } + + /// + /// 1-Norm also known as Manhattan Norm or Taxicab Norm. + /// + /// Scalar ret = sum(abs(this[i])) + public override double Norm1() + { + double sum = 0; + for (var i = 0; i < Data.Length; i++) + { + sum += Math.Abs(Data[i]); + } + + return sum; + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public override double NormP(int p) + { + if (1 > p) + { + throw new ArgumentOutOfRangeException("p"); + } + + if (1 == p) + { + return Norm1(); + } + + if (2 == p) + { + return Norm(); + } + + var sum = 0.0; + for (var i = 0; i < Data.Length; i++) + { + sum += Math.Pow(Math.Abs(Data[i]), p); + } + + return Math.Pow(sum, 1.0 / p); + } + + /// + /// Infinity Norm. + /// + /// Scalar ret = max(abs(this[i])) + public override double NormInfinity() + { + double max = 0; + for (int i = 0; i < Data.Length; i++) + { + max = Math.Max(max, Math.Abs(Data[i])); + } + + return max; + } + + #endregion } } \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index e8c97ae0..2da8679f 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -80,111 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double set; } - /// - /// Returns a deep-copy clone of the vector. - /// - /// - /// A deep-copy clone of the vector. - /// - public Vector Clone() - { - var retrunVector = CreateVector(Count); - CopyTo(retrunVector); - return retrunVector; - } - - /// - /// Copies the values of this vector into the target vector. - /// - /// - /// The vector to copy elements into. - /// - /// - /// If is . - /// - /// - /// If is not the same size as this vector. - /// - public virtual void CopyTo(Vector target) - { - if (target == null) - { - throw new ArgumentNullException("target"); - } - - if (Count != target.Count) - { - throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); - } - - if (ReferenceEquals(this, target)) - { - return; - } - - for (var index = 0; index < Count; index++) - { - target[index] = this[index]; - } - } - - /// - /// Copies the requested elements from this vector to another. - /// - /// - /// The vector to copy the elements to. - /// - /// - /// The element to start copying from. - /// - /// - /// The element to start copying to. - /// - /// - /// The number of elements to copy. - /// - public virtual void CopyTo(Vector destination, int offset, int destinationOffset, int count) - { - if (destination == null) - { - throw new ArgumentNullException("destination"); - } - - if (offset >= Count) - { - throw new ArgumentOutOfRangeException("offset"); - } - - if (offset + count > Count) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (destinationOffset >= destination.Count) - { - throw new ArgumentOutOfRangeException("destinationOffset"); - } - - if (destinationOffset + count > destination.Count) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (ReferenceEquals(this, destination)) - { - var tmpVector = destination.CreateVector(destination.Count); - CopyTo(tmpVector, offset, destinationOffset, count); - tmpVector.CopyTo(destination); - } - else - { - for (var index = 0; index < count; index++) - { - destination[destinationOffset + index] = this[offset + index]; - } - } - } - /// /// Creates a matrix with the given dimensions using the same storage type /// as this vector. @@ -280,17 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - /// - /// Returns a that represents this instance. - /// - /// - /// A that represents this instance. - /// - public override string ToString() - { - return ToString(null, null); - } - + #region Elementary operations /// /// Adds a scalar to each element of the vector. /// @@ -397,53 +282,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double } } - /// - /// Returns a Vector containing the same values of rightSide. - /// - /// This method is included for completeness. - /// The vector to get the values from. - /// A vector containing the same values as . - /// If is . - public static Vector operator +(Vector rightSide) - { - if (rightSide == null) - { - throw new ArgumentNullException("rightSide"); - } - - return rightSide.Plus(); - } - - /// - /// Adds two Vectors together and returns the results. - /// - /// One of the vectors to add. - /// The other vector to add. - /// The result of the addition. - /// If and are not the same size. - /// If or is . - public static Vector operator +(Vector leftSide, Vector rightSide) - { - if (rightSide == null) - { - throw new ArgumentNullException("rightSide"); - } - - if (leftSide == null) - { - throw new ArgumentNullException("leftSide"); - } - - if (leftSide.Count != rightSide.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide"); - } - - var ret = leftSide.Clone(); - ret.Add(rightSide); - return ret; - } - /// /// Subtracts a scalar from each element of the vector. /// @@ -553,30 +391,115 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Returns a Vector containing the negated values of rightSide. + /// Multiplies a scalar to each element of the vector. + /// + /// The scalar to multiply. + public virtual void Multiply(double scalar) + { + if (scalar.AlmostEqual(1.0)) + { + return; + } + + Parallel.For(0, Count, i => this[i] *= scalar); + } + + /// + /// Multiplies a scalar to each element of the vector and stores the result in the result vector. + /// + /// The scalar to multiply. + /// The vector to store the result of the multiplication. + /// If the result vector is . + /// If this vector and are not the same size. + public virtual void Multiply(double scalar, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + if (!ReferenceEquals(this, result)) + { + CopyTo(result); + } + + result.Multiply(scalar); + } + + /// + /// Divides each element of the vector by a scalar. /// + /// The scalar to divide with. + public virtual void Divide(double scalar) + { + if (scalar.AlmostEqual(1.0)) + { + return; + } + + Multiply(1.0 / scalar); + } + + /// + /// Divides each element of the vector by a scalar and stores the result in the result vector. + /// + /// The scalar to divide with. + /// The vector to store the result of the division. + /// If the result vector is . + /// If this vector and are not the same size. + public virtual void Divide(double scalar, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + if (!ReferenceEquals(this, result)) + { + CopyTo(result); + } + + result.Multiply(1.0 / scalar); + } + #endregion + + #region Arithmetic Operator Overloading + /// + /// Returns a Vector containing the same values of rightSide. + /// + /// This method is included for completeness. /// The vector to get the values from. - /// A vector containing the negated values as . + /// A vector containing the same values as . /// If is . - public static Vector operator -(Vector rightSide) + public static Vector operator +(Vector rightSide) { if (rightSide == null) { throw new ArgumentNullException("rightSide"); } - return rightSide.Negate(); + return rightSide.Plus(); } /// - /// Subtracts two Vectors and returns the results. + /// Adds two Vectors together and returns the results. /// - /// The vector to subtract from. - /// The vector to subtract. - /// The result of the subtraction. + /// One of the vectors to add. + /// The other vector to add. + /// The result of the addition. /// If and are not the same size. /// If or is . - public static Vector operator -(Vector leftSide, Vector rightSide) + public static Vector operator +(Vector leftSide, Vector rightSide) { if (rightSide == null) { @@ -594,49 +517,54 @@ namespace MathNet.Numerics.LinearAlgebra.Double } var ret = leftSide.Clone(); - ret.Subtract(rightSide); + ret.Add(rightSide); return ret; } /// - /// Multiplies a scalar to each element of the vector. + /// Returns a Vector containing the negated values of rightSide. /// - /// The scalar to multiply. - public virtual void Multiply(double scalar) + /// The vector to get the values from. + /// A vector containing the negated values as . + /// If is . + public static Vector operator -(Vector rightSide) { - if (scalar.AlmostEqual(1.0)) + if (rightSide == null) { - return; + throw new ArgumentNullException("rightSide"); } - Parallel.For(0, Count, i => this[i] *= scalar); + return rightSide.Negate(); } /// - /// Multiplies a scalar to each element of the vector and stores the result in the result vector. + /// Subtracts two Vectors and returns the results. /// - /// The scalar to multiply. - /// The vector to store the result of the multiplication. - /// If the result vector is . - /// If this vector and are not the same size. - public virtual void Multiply(double scalar, Vector result) + /// The vector to subtract from. + /// The vector to subtract. + /// The result of the subtraction. + /// If and are not the same size. + /// If or is . + public static Vector operator -(Vector leftSide, Vector rightSide) { - if (result == null) + if (rightSide == null) { - throw new ArgumentNullException("result"); + throw new ArgumentNullException("rightSide"); } - if (Count != result.Count) + if (leftSide == null) { - throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + throw new ArgumentNullException("leftSide"); } - - if (!ReferenceEquals(this, result)) + + if (leftSide.Count != rightSide.Count) { - CopyTo(result); + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide"); } - result.Multiply(scalar); + var ret = leftSide.Clone(); + ret.Subtract(rightSide); + return ret; } /// @@ -678,65 +606,239 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Divides each element of the vector by a scalar. + /// Divides a vector with a scalar. /// - /// The scalar to divide with. - public virtual void Divide(double scalar) + /// The vector to divide. + /// The scalar value. + /// The result of the division. + /// If is . + public static Vector operator /(Vector leftSide, double rightSide) { - if (scalar.AlmostEqual(1.0)) + if (leftSide == null) { - return; + throw new ArgumentNullException("leftSide"); } - Multiply(1.0 / scalar); + var ret = leftSide.Clone(); + ret.Multiply(1.0 / rightSide); + return ret; + } + + #endregion + + #region Vector Norms + + /// + /// Euclidean Norm also known as 2-Norm. + /// + /// + /// Scalar ret = sqrt(sum(this[i]^2)) + /// + public virtual double Norm() + { + return NormP(2); } /// - /// Divides each element of the vector by a scalar and stores the result in the result vector. + /// Squared Euclidean 2-Norm. /// - /// The scalar to divide with. - /// The vector to store the result of the division. - /// If the result vector is . - /// If this vector and are not the same size. - public virtual void Divide(double scalar, Vector result) + /// + /// Scalar ret = sum(this[i]^2) + /// + public virtual double SquaredNorm() { - if (result == null) + var norm = Norm(); + return norm * norm; + } + + /// + /// 1-Norm also known as Manhattan Norm or Taxicab Norm. + /// + /// + /// Scalar ret = sum(abs(this[i])) + /// + public virtual double Norm1() + { + return NormP(1); + } + + /// + /// Computes the p-Norm. + /// + /// The p value. + /// Scalar ret = (sum(abs(this[i])^p))^(1/p) + public virtual double NormP(int p) + { + if (1 > p) { - throw new ArgumentNullException("result"); + throw new ArgumentOutOfRangeException("p"); } - if (Count != result.Count) + var sum = 0.0; + + foreach (var pair in GetIndexedEnumerator()) { - throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + sum += Math.Pow(Math.Abs(pair.Value), p); } - if (!ReferenceEquals(this, result)) + return Math.Pow(sum, 1.0 / p); + } + + /// + /// Infinity Norm. + /// + /// + /// Scalar ret = max(abs(this[i])) + /// + public virtual double NormInfinity() + { + var max = 0.0; + foreach (var pair in GetIndexedEnumerator()) { - CopyTo(result); + max = Math.Max(max, Math.Abs(pair.Value)); } - result.Multiply(1.0 / scalar); + return max; } /// - /// Divides a vector with a scalar. + /// Normalizes this vector to a unit vector with respect to the Eucliden 2-Norm. /// - /// The vector to divide. - /// The scalar value. - /// The result of the division. - /// If is . - public static Vector operator /(Vector leftSide, double rightSide) + /// This vector normalized to a unit vector with respect to the Eucliden 2-Norm. + public virtual Vector Normalize() { - if (leftSide == null) + var norm = Norm(); + var clone = Clone(); + if (norm.AlmostZero()) { - throw new ArgumentNullException("leftSide"); + return clone; } - var ret = leftSide.Clone(); - ret.Multiply(1.0 / rightSide); - return ret; + clone.Multiply(1.0 / norm); + return clone; + } + + #endregion + + #region Coping and Conversion + /// + /// Returns a deep-copy clone of the vector. + /// + /// + /// A deep-copy clone of the vector. + /// + public Vector Clone() + { + var retrunVector = CreateVector(Count); + CopyTo(retrunVector); + return retrunVector; + } + + /// + /// Copies the values of this vector into the target vector. + /// + /// + /// The vector to copy elements into. + /// + /// + /// If is . + /// + /// + /// If is not the same size as this vector. + /// + public virtual void CopyTo(Vector target) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (Count != target.Count) + { + throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); + } + + if (ReferenceEquals(this, target)) + { + return; + } + + for (var index = 0; index < Count; index++) + { + target[index] = this[index]; + } + } + + /// + /// Copies the requested elements from this vector to another. + /// + /// + /// The vector to copy the elements to. + /// + /// + /// The element to start copying from. + /// + /// + /// The element to start copying to. + /// + /// + /// The number of elements to copy. + /// + public virtual void CopyTo(Vector destination, int offset, int destinationOffset, int count) + { + if (destination == null) + { + throw new ArgumentNullException("destination"); + } + + if (offset >= Count) + { + throw new ArgumentOutOfRangeException("offset"); + } + + if (offset + count > Count) + { + throw new ArgumentOutOfRangeException("count"); + } + + if (destinationOffset >= destination.Count) + { + throw new ArgumentOutOfRangeException("destinationOffset"); + } + + if (destinationOffset + count > destination.Count) + { + throw new ArgumentOutOfRangeException("count"); + } + + if (ReferenceEquals(this, destination)) + { + var tmpVector = destination.CreateVector(destination.Count); + CopyTo(tmpVector, offset, destinationOffset, count); + tmpVector.CopyTo(destination); + } + else + { + for (var index = 0; index < count; index++) + { + destination[destinationOffset + index] = this[offset + index]; + } + } } + /// + /// Returns a that represents this instance. + /// + /// + /// A that represents this instance. + /// + public override string ToString() + { + return ToString(null, null); + } + + #endregion + #region Implemented Interfaces #region ICloneable diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs new file mode 100644 index 00000000..bc4be17d --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs @@ -0,0 +1,634 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using MathNet.Numerics.LinearAlgebra.Double; +using MbUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + public abstract partial class VectorTests + { + [Test] + public void CanCallPlus() + { + var vector = CreateVector(_data); + var other = vector.Plus(); + Assert.AreSame(vector, other, "Should be the same vector"); + } + + [Test] + public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector() + { + Vector vector = null; + Vector other = null; + Assert.Throws(() => other = +vector); + } + + [Test] + public void CanCallUnaryPlusOperator() + { + var vector = CreateVector(_data); + var other = +vector; + Assert.AreSame(vector, other, "Should be the same vector"); + } + + [Test] + [MultipleAsserts] + public void CanAddScalarToVector() + { + var vector = CreateVector(_data); + vector.Add(2.0); + + for( var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i]+2.0, vector[i]); + } + + vector.Add(0.0); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] + 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanAddScalarToVectorUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Add(2.0, result); + + 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] + 2.0, result[i]); + } + + vector.Add(0.0, result); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], result[i]); + } + } + + [Test] + public void ThrowsArgumentNullExceptionWhenAddingScalarWithNullResultVector() + { + var vector = CreateVector(_data.Length); + Assert.Throws(() => vector.Add(0.0, null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenAddingScalarWithWrongSizeResultVector() + { + var vector = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Add(0.0, result)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndOneIsNull() + { + var vector = CreateVector(_data); + Assert.Throws(() => vector.Add(null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenAddingTwoVectorsOfDifferingSize() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length +1); + Assert.Throws(() => vector.Add(other)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndResultIsNull() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length+1); + Assert.Throws(() => vector.Add(other,null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenAddingTwoVectorsAndResultIsDifferentSize() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Add(other, result)); + } + + [Test] + public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() + { + Vector a = null; + var b = CreateVector(_data.Length); + Assert.Throws(()=> a += b); + + a = b; + b = null; + Assert.Throws(() => a += b); + } + + [Test] + public void AdditionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize() + { + var a = CreateVector(_data.Length); + var b = CreateVector(_data.Length + 1); + Assert.Throws(() => a += b); + } + + [Test] + public void CanAddTwoVectors() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + vector.Add(other); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanAddTwoVectorsUsingResultVector() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Add(other, result); + + 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] + [MultipleAsserts] + public void CanAddTwoVectorsUsingOperator() + { + var vector = CreateVector(_data); + var other = CreateVector(_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 CanAddVectorToItself() + { + var vector = CreateVector(_data); + vector.Add(vector); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanAddVectorToItselfUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Add(vector, result); + + 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] * 2.0, result[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanAddTwoVectorsUsingItselfAsResultVector() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + vector.Add(other, vector); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + } + + [Test] + public void CanCallNegate() + { + var vector = CreateVector(_data); + var other = vector.Negate(); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(-_data[i], other[i]); + } + } + + [Test] + public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector() + { + Vector vector = null; + Vector other = null; + Assert.Throws(() => other = -vector); + } + + [Test] + public void CanCallUnaryNegationOperator() + { + var vector = CreateVector(_data); + var other = -vector; + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(-_data[i], other[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractScalarFromVector() + { + var vector = CreateVector(_data); + vector.Subtract(2.0); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] - 2.0, vector[i]); + } + + vector.Subtract(0.0); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] - 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractScalarFromVectorUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Subtract(2.0, result); + + 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] - 2.0, result[i]); + } + + vector.Subtract(0.0, result); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], result[i]); + } + } + + [Test] + public void ThrowsArgumentNullExceptionWhenSubtractingScalarWithNullResultVector() + { + var vector = CreateVector(_data.Length); + Assert.Throws(() => vector.Subtract(0.0, null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenSubtractingScalarWithWrongSizeResultVector() + { + var vector = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Subtract(0.0, result)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndOneIsNull() + { + var vector = CreateVector(_data); + Assert.Throws(() => vector.Subtract(null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsOfDifferingSize() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Subtract(other)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndResultIsNull() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Subtract(other, null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsAndResultIsDifferentSize() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Subtract(other, result)); + } + + [Test] + public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() + { + Vector a = null; + var b = CreateVector(_data.Length); + Assert.Throws(() => a -= b); + + a = b; + b = null; + Assert.Throws(() => a -= b); + } + + [Test] + public void SubtractionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize() + { + var a = CreateVector(_data.Length); + var b = CreateVector(_data.Length + 1); + Assert.Throws(() => a -= b); + } + + [Test] + public void CanSubtractTwoVectors() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + vector.Subtract(other); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(0.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractTwoVectorsUsingResultVector() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Subtract(other, result); + + 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 CanSubtractTwoVectorsUsingOperator() + { + var vector = CreateVector(_data); + var other = CreateVector(_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] + public void CanSubtractVectorFromItself() + { + var vector = CreateVector(_data); + vector.Subtract(vector); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(0.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractVectorFromItselfUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Subtract(vector, result); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(0.0, result[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanSubtractTwoVectorsUsingItselfAsResultVector() + { + var vector = CreateVector(_data); + var other = CreateVector(_data); + vector.Subtract(other, vector); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); + Assert.AreEqual(0.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanDivideVectorByScalar() + { + var vector = CreateVector(_data); + vector.Divide(2.0); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] / 2.0, vector[i]); + } + + vector.Divide(1.0); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] / 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanDivideVectorByScalarUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Divide(2.0, result); + + 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] / 2.0, result[i]); + } + + vector.Divide(1.0, result); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], result[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanMultiplyVectorByScalar() + { + var vector = CreateVector(_data); + vector.Multiply(2.0); + + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + + vector.Multiply(1.0); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i] * 2.0, vector[i]); + } + } + + [Test] + [MultipleAsserts] + public void CanMultiplyVectorByScalarUsingResultVector() + { + var vector = CreateVector(_data); + var result = CreateVector(_data.Length); + vector.Multiply(2.0, result); + + 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] * 2.0, result[i]); + } + + vector.Multiply(1.0, result); + for (var i = 0; i < _data.Length; i++) + { + Assert.AreEqual(_data[i], result[i]); + } + } + + [Test] + public void ThrowsArgumentNullExceptionWhenMultiplyingScalarWithNullResultVector() + { + var vector = CreateVector(_data.Length); + Assert.Throws(() => vector.Multiply(1.0, null)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenDividingScalarWithNullResultVector() + { + var vector = CreateVector(_data.Length); + Assert.Throws(() => vector.Divide(1.0, null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenMultiplyingScalarWithWrongSizeResultVector() + { + var vector = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Multiply(0.0, result)); + } + + [Test] + public void ThrowsArgumentExceptionWhenDividingScalarWithWrongSizeResultVector() + { + var vector = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Divide(0.0, result)); + } + + [Test] + [MultipleAsserts] + public void CanMultiplyVectorByScalarUsingOperators() + { + var vector = CreateVector(_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 = CreateVector(_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 CanDivideVectorByScalarUsingOperators() + { + var vector = CreateVector(_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]); + } + } + + [Test] + [MultipleAsserts] + public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull() + { + Vector vector = null; + Vector result = null; + Assert.Throws(() => result = vector * 2.0); + Assert.Throws(() => result = 2.0 * vector); + } + + [Test] + public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull() + { + Vector vector = null; + Assert.Throws(() => vector = vector / 2.0); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs new file mode 100644 index 00000000..5c41b4e1 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs @@ -0,0 +1,59 @@ +using MbUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + public abstract partial class VectorTests + { + [Test] + public void CanComputeNorm() + { + var vector = CreateVector(_data); + AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(), 15); + } + + [Test] + public void CanComputeNorm1() + { + var vector = CreateVector(_data); + AssertHelpers.AlmostEqual(15.0, vector.Norm1(), 15); + } + + [Test] + public void CanComputeSquareNorm() + { + var vector = CreateVector(_data); + AssertHelpers.AlmostEqual(55.0, vector.SquaredNorm(), 15); + } + + [Test] + [Row(1, 15.0)] + [Row(2, 7.416198487095663)] + [Row(3, 6.0822019955734001)] + [Row(10, 5.0540557845353753)] + public void CanComputeNormP(int p, double expected) + { + var vector = CreateVector(_data); + AssertHelpers.AlmostEqual(expected, vector.NormP(p), 15); + } + + [Test] + public void CanComputeNormInfinity() + { + var vector = CreateVector(_data); + AssertHelpers.AlmostEqual(5.0, vector.NormInfinity(), 15); + } + + [Test] + [MultipleAsserts] + public void CanNormalizeVector() + { + var vector = CreateVector(_data); + var result = vector.Normalize(); + AssertHelpers.AlmostEqual(0.134839972492648, result[0], 14); + AssertHelpers.AlmostEqual(0.269679944985297, result[1], 14); + AssertHelpers.AlmostEqual(0.404519917477945, result[2], 14); + AssertHelpers.AlmostEqual(0.539359889970594, result[3], 14); + AssertHelpers.AlmostEqual(0.674199862463242, result[4], 14); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index fe719268..1a95836c 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -6,7 +6,7 @@ using MbUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { - public abstract class VectorTests + public abstract partial class VectorTests { private readonly double[] _data = {1, 2, 3, 4, 5}; @@ -157,629 +157,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.Throws(() => CreateVector(0)); } - [Test] - public void CanCallPlus() - { - var vector = CreateVector(_data); - var other = vector.Plus(); - Assert.AreSame(vector, other, "Should be the same vector"); - } - - [Test] - public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector() - { - Vector vector = null; - Vector other = null; - Assert.Throws(() => other = +vector); - } - - [Test] - public void CanCallUnaryPlusOperator() - { - var vector = CreateVector(_data); - var other = +vector; - Assert.AreSame(vector, other, "Should be the same vector"); - } - - [Test] - [MultipleAsserts] - public void CanAddScalarToVector() - { - var vector = CreateVector(_data); - vector.Add(2.0); - - for( var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i]+2.0, vector[i]); - } - - vector.Add(0.0); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] + 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanAddScalarToVectorUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Add(2.0, result); - - 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] + 2.0, result[i]); - } - - vector.Add(0.0, result); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], result[i]); - } - } - - [Test] - public void ThrowsArgumentNullExceptionWhenAddingScalarWithNullResultVector() - { - var vector = CreateVector(_data.Length); - Assert.Throws(() => vector.Add(0.0, null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenAddingScalarWithWrongSizeResultVector() - { - var vector = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Add(0.0, result)); - } - - [Test] - public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndOneIsNull() - { - var vector = CreateVector(_data); - Assert.Throws(() => vector.Add(null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenAddingTwoVectorsOfDifferingSize() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length +1); - Assert.Throws(() => vector.Add(other)); - } - - [Test] - public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndResultIsNull() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length+1); - Assert.Throws(() => vector.Add(other,null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenAddingTwoVectorsAndResultIsDifferentSize() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Add(other, result)); - } - - [Test] - public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() - { - Vector a = null; - var b = CreateVector(_data.Length); - Assert.Throws(()=> a += b); - - a = b; - b = null; - Assert.Throws(() => a += b); - } - - [Test] - public void AdditionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize() - { - var a = CreateVector(_data.Length); - var b = CreateVector(_data.Length + 1); - Assert.Throws(() => a += b); - } - - [Test] - public void CanAddTwoVectors() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - vector.Add(other); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] * 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanAddTwoVectorsUsingResultVector() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Add(other, result); - - 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] - [MultipleAsserts] - public void CanAddTwoVectorsUsingOperator() - { - var vector = CreateVector(_data); - var other = CreateVector(_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 CanAddVectorToItself() - { - var vector = CreateVector(_data); - vector.Add(vector); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] * 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanAddVectorToItselfUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Add(vector, result); - - 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] * 2.0, result[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanAddTwoVectorsUsingItselfAsResultVector() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - vector.Add(other, vector); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); - Assert.AreEqual(_data[i] * 2.0, vector[i]); - } - } - - [Test] - public void CanCallNegate() - { - var vector = CreateVector(_data); - var other = vector.Negate(); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(-_data[i], other[i]); - } - } - - [Test] - public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector() - { - Vector vector = null; - Vector other = null; - Assert.Throws(() => other = -vector); - } - - [Test] - public void CanCallUnaryNegationOperator() - { - var vector = CreateVector(_data); - var other = -vector; - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(-_data[i], other[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanSubtractScalarFromVector() - { - var vector = CreateVector(_data); - vector.Subtract(2.0); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] - 2.0, vector[i]); - } - - vector.Subtract(0.0); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] - 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanSubtractScalarFromVectorUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Subtract(2.0, result); - - 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] - 2.0, result[i]); - } - - vector.Subtract(0.0, result); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], result[i]); - } - } - - [Test] - public void ThrowsArgumentNullExceptionWhenSubtractingScalarWithNullResultVector() - { - var vector = CreateVector(_data.Length); - Assert.Throws(() => vector.Subtract(0.0, null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenSubtractingScalarWithWrongSizeResultVector() - { - var vector = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Subtract(0.0, result)); - } - - [Test] - public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndOneIsNull() - { - var vector = CreateVector(_data); - Assert.Throws(() => vector.Subtract(null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsOfDifferingSize() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Subtract(other)); - } - - [Test] - public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndResultIsNull() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Subtract(other, null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsAndResultIsDifferentSize() - { - var vector = CreateVector(_data.Length); - var other = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Subtract(other, result)); - } - - [Test] - public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() - { - Vector a = null; - var b = CreateVector(_data.Length); - Assert.Throws(() => a -= b); - - a = b; - b = null; - Assert.Throws(() => a -= b); - } - - [Test] - public void SubtractionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize() - { - var a = CreateVector(_data.Length); - var b = CreateVector(_data.Length + 1); - Assert.Throws(() => a -= b); - } - - [Test] - public void CanSubtractTwoVectors() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - vector.Subtract(other); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(0.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanSubtractTwoVectorsUsingResultVector() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Subtract(other, result); - - 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 CanSubtractTwoVectorsUsingOperator() - { - var vector = CreateVector(_data); - var other = CreateVector(_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] - public void CanSubtractVectorFromItself() - { - var vector = CreateVector(_data); - vector.Subtract(vector); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(0.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanSubtractVectorFromItselfUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Subtract(vector, result); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified."); - Assert.AreEqual(0.0, result[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanSubtractTwoVectorsUsingItselfAsResultVector() - { - var vector = CreateVector(_data); - var other = CreateVector(_data); - vector.Subtract(other, vector); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified."); - Assert.AreEqual(0.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanDivideVectorByScalar() - { - var vector = CreateVector(_data); - vector.Divide(2.0); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] / 2.0, vector[i]); - } - - vector.Divide(1.0); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] / 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanDivideVectorByScalarUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Divide(2.0, result); - - 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] / 2.0, result[i]); - } - - vector.Divide(1.0, result); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], result[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanMultiplyVectorByScalar() - { - var vector = CreateVector(_data); - vector.Multiply(2.0); - - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] * 2.0, vector[i]); - } - - vector.Multiply(1.0); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i] * 2.0, vector[i]); - } - } - - [Test] - [MultipleAsserts] - public void CanMultiplyVectorByScalarUsingResultVector() - { - var vector = CreateVector(_data); - var result = CreateVector(_data.Length); - vector.Multiply(2.0, result); - - 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] * 2.0, result[i]); - } - - vector.Multiply(1.0, result); - for (var i = 0; i < _data.Length; i++) - { - Assert.AreEqual(_data[i], result[i]); - } - } - - [Test] - public void ThrowsArgumentNullExceptionWhenMultiplyingScalarWithNullResultVector() - { - var vector = CreateVector(_data.Length); - Assert.Throws(() => vector.Multiply(1.0, null)); - } - - [Test] - public void ThrowsArgumentNullExceptionWhenDividingScalarWithNullResultVector() - { - var vector = CreateVector(_data.Length); - Assert.Throws(() => vector.Divide(1.0, null)); - } - - [Test] - public void ThrowsArgumentExceptionWhenMultiplyingScalarWithWrongSizeResultVector() - { - var vector = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Multiply(0.0, result)); - } - - [Test] - public void ThrowsArgumentExceptionWhenDividingScalarWithWrongSizeResultVector() - { - var vector = CreateVector(_data.Length); - var result = CreateVector(_data.Length + 1); - Assert.Throws(() => vector.Divide(0.0, result)); - } - - [Test] - [MultipleAsserts] - public void CanMultiplyVectorByScalarUsingOperators() - { - var vector = CreateVector(_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 = CreateVector(_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 CanDivideVectorByScalarUsingOperators() - { - var vector = CreateVector(_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]); - } - } - - [Test] - [MultipleAsserts] - public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull() - { - Vector vector = null; - Vector result = null; - Assert.Throws(() => result = vector * 2.0); - Assert.Throws(() => result = 2.0 * vector); - } - - [Test] - public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull() - { - Vector vector = null; - Assert.Throws(() => vector = vector / 2.0); - } - protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(IList data); diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index d32db935..79126209 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -80,6 +80,8 @@ + +