From a8b66050c04eaa18765148d0f93bb96b600de7c5 Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Mon, 25 Jan 2010 07:06:04 +0800 Subject: [PATCH] Added vector Dot product. --- .../LinearAlgebra/Double/DenseVector.cs | 60 ++++++++++++++++ src/Numerics/LinearAlgebra/Double/Vector.cs | 56 +++++++++++++++ .../Double/VectorTests.Arithmetic.cs | 68 +++++++++++++++++++ 3 files changed, 184 insertions(+) diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index deae7518..22b1c0df 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -620,6 +620,38 @@ namespace MathNet.Numerics.LinearAlgebra.Double Control.LinearAlgebraProvider.ScaleArray(scalar, Data); } + /// + /// Computes the dot product between this vector and another vector. + /// + /// The other vector to add. + /// The result of the addition. + /// If is not of the same size. + /// If is . + public override double DotProduct(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + + var denseVector = other as DenseVector; + + if (denseVector == null) + { + return base.DotProduct(other); + } + else + { + return Control.LinearAlgebraProvider.DotProduct(this.Data, denseVector.Data); + } + } + /// /// Multiplies a vector with a scalar. /// @@ -658,6 +690,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double return ret; } + /// + /// Computes the dot product between two Vectors. + /// + /// The left row vector. + /// The right column vector. + /// The dot product between the two vectors. + /// If and are not the same size. + /// If or is . + public static double operator *(DenseVector leftSide, DenseVector 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"); + } + + return Control.LinearAlgebraProvider.DotProduct(leftSide.Data, rightSide.Data); + } + /// /// Divides a vector with a scalar. /// diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 58e61b51..88dabe95 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -370,6 +370,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double result.Multiply(scalar); } + /// + /// Computes the dot product between this vector and another vector. + /// + /// The other vector to add. + /// The result of the addition. + /// If is not of the same size. + /// If is . + public virtual double DotProduct(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + double dot = 0.0; + for (int i = 0; i < Count; i++) + { + dot += this[i] * other[i]; + } + + return dot; + } + /// /// Divides each element of the vector by a scalar. /// @@ -544,6 +572,34 @@ namespace MathNet.Numerics.LinearAlgebra.Double return ret; } + /// + /// Computes the dot product between two Vectors. + /// + /// The left row vector. + /// The right column vector. + /// The dot product between the two vectors. + /// If and are not the same size. + /// If or is . + public static double 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"); + } + + return leftSide.DotProduct(rightSide); + } + /// /// Divides a vector with a scalar. /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs index a1bf8118..54c36b88 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs @@ -628,5 +628,73 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Vector vector = null; Assert.Throws(() => vector = vector / 2.0); } + + [Test] + public void CanDotProduct() + { + Vector dataA = CreateVector(_data); + Vector dataB = CreateVector(_data); + + Assert.AreEqual(55.0, dataA.DotProduct(dataB)); + } + + [Test] + [ExpectedArgumentNullException] + public void DotProductThrowsExceptionWhenArgumentIsNull() + { + Vector dataA = CreateVector(_data); + Vector dataB = null; + + dataA.DotProduct(dataB); + } + + [Test] + [ExpectedArgumentException] + public void DotProductThrowsExceptionWhenArgumentHasDifferentSize() + { + Vector dataA = CreateVector(_data); + Vector dataB = CreateVector(new double[] {1, 2, 3, 4, 5, 6}); + + dataA.DotProduct(dataB); + } + + [Test] + public void CanDotProductUsingOperator() + { + Vector dataA = CreateVector(_data); + Vector dataB = CreateVector(_data); + + Assert.AreEqual(55.0, dataA * dataB); + } + + [Test] + [ExpectedArgumentNullException] + public void OperatorDotProductThrowsExceptionWhenLeftArgumentIsNull() + { + Vector dataA = CreateVector(_data); + Vector dataB = null; + + double d = dataA * dataB; + } + + [Test] + [ExpectedArgumentNullException] + public void OperatorDotProductThrowsExceptionWhenRightArgumentIsNull() + { + Vector dataA = null; + Vector dataB = CreateVector(_data); + + double d = dataA * dataB; + } + + [Test] + [ExpectedArgumentException] + public void OperatorDotProductThrowsExceptionWhenArgumentHasDifferentSize() + { + Vector dataA = CreateVector(_data); + Vector dataB = CreateVector(new double[] { 1, 2, 3, 4, 5, 6 }); + + double d = dataA * dataB; + } } } \ No newline at end of file