From 33051dcc0caaeef3ff76877745c94abb1c1f8241 Mon Sep 17 00:00:00 2001 From: Christoph Ruegg Date: Fri, 16 Aug 2013 13:09:22 +0200 Subject: [PATCH] Vector: Added ConjugateDotProduct --- .../LinearAlgebra/Complex/DenseVector.cs | 27 ++++++++++-- .../LinearAlgebra/Complex/SparseVector.cs | 33 +++++++++++--- src/Numerics/LinearAlgebra/Complex/Vector.cs | 23 +++++++--- .../LinearAlgebra/Complex32/DenseVector.cs | 27 ++++++++++-- .../LinearAlgebra/Complex32/SparseVector.cs | 33 +++++++++++--- .../LinearAlgebra/Complex32/Vector.cs | 23 +++++++--- .../LinearAlgebra/Double/DenseVector.cs | 10 ++--- .../LinearAlgebra/Double/SparseVector.cs | 12 ++--- src/Numerics/LinearAlgebra/Double/Vector.cs | 10 +---- .../Generic/Vector.Arithmetic.cs | 44 +++++++++++++------ .../LinearAlgebra/Single/DenseVector.cs | 10 ++--- .../LinearAlgebra/Single/SparseVector.cs | 12 ++--- src/Numerics/LinearAlgebra/Single/Vector.cs | 10 +---- 13 files changed, 181 insertions(+), 93 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs index 2bfd369b..4c827b26 100644 --- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs @@ -434,14 +434,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// s - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex DoDotProduct(Vector other) { var denseVector = other as DenseVector; + return denseVector == null + ? base.DoDotProduct(other) + : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + } + + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex DoConjugateDotProduct(Vector other) + { + var denseVector = other as DenseVector; + if (denseVector == null) return base.DoConjugateDotProduct(other); - return denseVector == null ? base.DoDotProduct(other) : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + // TODO: provide native zdotc routine + var dot = Complex.Zero; + for (var i = 0; i < _values.Length; i++) + { + dot += _values[i].Conjugate()*denseVector._values[i]; + } + return dot; } /// diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs index 9f90530e..89960c70 100644 --- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs @@ -540,16 +540,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex DoDotProduct(Vector other) { var result = Complex.Zero; - if (ReferenceEquals(this, other)) { for (var i = 0; i < _storage.ValueCount; i++) @@ -564,7 +559,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex result += _storage.Values[i] * other.At(_storage.Indices[i]); } } + return result; + } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex DoConjugateDotProduct(Vector other) + { + var result = Complex.Zero; + if (ReferenceEquals(this, other)) + { + for (var i = 0; i < _storage.ValueCount; i++) + { + result += _storage.Values[i].Conjugate() * _storage.Values[i]; + } + } + else + { + for (var i = 0; i < _storage.ValueCount; i++) + { + result += _storage.Values[i].Conjugate() * other.At(_storage.Indices[i]); + } + } return result; } diff --git a/src/Numerics/LinearAlgebra/Complex/Vector.cs b/src/Numerics/LinearAlgebra/Complex/Vector.cs index 40320362..065a15ec 100644 --- a/src/Numerics/LinearAlgebra/Complex/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex/Vector.cs @@ -203,21 +203,30 @@ namespace MathNet.Numerics.LinearAlgebra.Complex /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex DoDotProduct(Vector other) { var dot = Complex.Zero; - for (var i = 0; i < Count; i++) { dot += At(i) * other.At(i); } + return dot; + } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex DoConjugateDotProduct(Vector other) + { + var dot = Complex.Zero; + for (var i = 0; i < Count; i++) + { + dot += At(i).Conjugate() * other.At(i); + } return dot; } diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs index bfe21643..ca651380 100644 --- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs @@ -429,14 +429,33 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// s - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex32 DoDotProduct(Vector other) { var denseVector = other as DenseVector; + return denseVector == null + ? base.DoDotProduct(other) + : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + } + + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex32 DoConjugateDotProduct(Vector other) + { + var denseVector = other as DenseVector; + if (denseVector == null) return base.DoConjugateDotProduct(other); - return denseVector == null ? base.DoDotProduct(other) : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + // TODO: provide native cdotc routine + var dot = Complex32.Zero; + for (var i = 0; i < _values.Length; i++) + { + dot += _values[i].Conjugate() * denseVector._values[i]; + } + return dot; } /// diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs index dc84be28..4e200f62 100644 --- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs @@ -535,16 +535,11 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex32 DoDotProduct(Vector other) { var result = Complex32.Zero; - if (ReferenceEquals(this, other)) { for (var i = 0; i < _storage.ValueCount; i++) @@ -559,7 +554,31 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 result += _storage.Values[i] * other.At(_storage.Indices[i]); } } + return result; + } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex32 DoConjugateDotProduct(Vector other) + { + var result = Complex32.Zero; + if (ReferenceEquals(this, other)) + { + for (var i = 0; i < _storage.ValueCount; i++) + { + result += _storage.Values[i].Conjugate() * _storage.Values[i]; + } + } + else + { + for (var i = 0; i < _storage.ValueCount; i++) + { + result += _storage.Values[i].Conjugate() * other.At(_storage.Indices[i]); + } + } return result; } diff --git a/src/Numerics/LinearAlgebra/Complex32/Vector.cs b/src/Numerics/LinearAlgebra/Complex32/Vector.cs index b39d6c3c..a50fb1d2 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Vector.cs @@ -198,21 +198,30 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override Complex32 DoDotProduct(Vector other) { var dot = Complex32.Zero; - for (var i = 0; i < Count; i++) { dot += At(i) * other.At(i); } + return dot; + } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected override Complex32 DoConjugateDotProduct(Vector other) + { + var dot = Complex32.Zero; + for (var i = 0; i < Count; i++) + { + dot += At(i).Conjugate() * other.At(i); + } return dot; } diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 283fc212..0afd2d49 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -440,14 +440,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// s - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override double DoDotProduct(Vector other) { var denseVector = other as DenseVector; - - return denseVector == null ? base.DoDotProduct(other) : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + return denseVector == null + ? base.DoDotProduct(other) + : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index 715f2f87..ea8a6e3c 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -497,16 +497,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override double DoDotProduct(Vector other) { - var result = 0.0; - + var result = 0d; if (ReferenceEquals(this, other)) { for (var i = 0; i < _storage.ValueCount; i++) @@ -521,7 +516,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double result += _storage.Values[i] * other.At(_storage.Indices[i]); } } - return result; } diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 4de80d00..2b78436a 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -200,21 +200,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override double DoDotProduct(Vector other) { var dot = 0.0; - for (var i = 0; i < Count; i++) { dot += At(i) * other.At(i); } - return dot; } diff --git a/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs b/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs index d4033f30..6054a8c0 100644 --- a/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Generic/Vector.Arithmetic.cs @@ -96,10 +96,20 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected abstract T DoDotProduct(Vector other); + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + protected virtual T DoConjugateDotProduct(Vector other) + { + return DoDotProduct(other); + } + /// /// Divides each element of the vector by a scalar and stores the result in the result vector. /// @@ -502,25 +512,33 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. /// If is not of the same size. /// If is . public T DotProduct(Vector other) { - if (other == null) - { - throw new ArgumentNullException("other"); - } - - if (Count != other.Count) - { - throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); - } + if (other == null) throw new ArgumentNullException("other"); + if (Count != other.Count) throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); return DoDotProduct(other); } + /// + /// Computes the dot product between the conjugate of this vector and another vector. + /// + /// The other vector. + /// The sum of conj(a[i])*b[i] for all i. + /// If is not of the same size. + /// If is . + public T ConjugateDotProduct(Vector other) + { + if (other == null) throw new ArgumentNullException("other"); + if (Count != other.Count) throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + + return DoConjugateDotProduct(other); + } + /// /// Divides each element of the vector by a scalar. /// diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index 7186ace8..fc9a2969 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -429,14 +429,14 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Computes the dot product between this vector and another vector. /// - /// The other vector to add. - /// s - /// The result of the addition. + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override float DoDotProduct(Vector other) { var denseVector = other as DenseVector; - - return denseVector == null ? base.DoDotProduct(other) : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); + return denseVector == null + ? base.DoDotProduct(other) + : Control.LinearAlgebraProvider.DotProduct(_values, denseVector.Values); } /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index 33b10c2e..9c1db4b9 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -498,16 +498,11 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override float DoDotProduct(Vector other) { - var result = 0.0f; - + var result = 0f; if (ReferenceEquals(this, other)) { for (var i = 0; i < _storage.ValueCount; i++) @@ -522,7 +517,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single result += _storage.Values[i] * other.At(_storage.Indices[i]); } } - return result; } diff --git a/src/Numerics/LinearAlgebra/Single/Vector.cs b/src/Numerics/LinearAlgebra/Single/Vector.cs index 1199d759..58012194 100644 --- a/src/Numerics/LinearAlgebra/Single/Vector.cs +++ b/src/Numerics/LinearAlgebra/Single/Vector.cs @@ -200,21 +200,15 @@ namespace MathNet.Numerics.LinearAlgebra.Single /// /// Computes the dot product between this vector and another vector. /// - /// - /// The other vector to add. - /// - /// s - /// The result of the addition. - /// + /// The other vector. + /// The sum of a[i]*b[i] for all i. protected override float DoDotProduct(Vector other) { var dot = 0.0f; - for (var i = 0; i < Count; i++) { dot += At(i) * other.At(i); } - return dot; }