From 7cd5f92098323eb08ca7c5298bfbe4c04cf6a2a0 Mon Sep 17 00:00:00 2001 From: Jurgen Van Gael Date: Wed, 21 Jul 2010 05:26:03 +0800 Subject: [PATCH] Changed the Vector API to make methods more functional programming friendly. --- .../LinearAlgebra/Double/DenseVector.cs | 30 +++++--- .../LinearAlgebra/Double/SparseVector.cs | 26 ++++--- src/Numerics/LinearAlgebra/Double/Vector.cs | 74 ++++++++++++------- 3 files changed, 82 insertions(+), 48 deletions(-) diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 4a8d7cb9..0fe2ee50 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -298,17 +298,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Adds a scalar to each element of the vector. /// /// The scalar to add. - public override void Add(double scalar) + /// A copy of the vector with the scalar added. + public override Vector Add(double scalar) { if (scalar == 0.0) { - return; + return this.Clone(); } + var copy = (DenseVector) this.Clone(); CommonParallel.For( 0, - Data.Length, - index => Data[index] += scalar); + Data.Length, + index => copy.Data[index] += scalar); + return copy; } /// @@ -340,7 +343,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to add to this one. /// If the other vector is . /// If this vector and are not the same size. - public override void Add(Vector other) + public override Vector Add(Vector other) { if (other == null) { @@ -454,7 +457,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Subtracts a scalar from each element of the vector. /// /// The scalar to subtract. - public override void Subtract(double scalar) + public override Vector Subtract(double scalar) { if (scalar == 0.0) { @@ -496,7 +499,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to subtract from this one. /// If the other vector is . /// If this vector and are not the same size. - public override void Subtract(Vector other) + public override Vector Subtract(Vector other) { if (other == null) { @@ -625,7 +628,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Multiplies a scalar to each element of the vector. /// /// The scalar to multiply. - public override void Multiply(double scalar) + public override Vector Multiply(double scalar) { if (scalar == 1.0) { @@ -944,9 +947,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Pointwise multiplies this vector with another vector. /// /// The vector to pointwise multiply with this one. + /// A new vector which is the pointwise multiplication of the two vectors. /// If the other vector is . /// If this vector and are not the same size. - public override void PointwiseMultiply(Vector other) + public override Vector PointwiseMultiply(Vector other) { if (other == null) { @@ -966,10 +970,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double } else { + var copy = (DenseVector)this.Clone(); CommonParallel.For( 0, - Count, - index => this[index] *= other[index]); + Count, + index => copy[index] *= other[index]); + return copy; } } @@ -1023,7 +1029,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to pointwise divide this one by. /// If the other vector is . /// If this vector and are not the same size. - public override void PointwiseDivide(Vector other) + public override Vector PointwiseDivide(Vector other) { if (other == null) { diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index 8a386359..e50a416f 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -346,17 +346,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Adds a scalar to each element of the vector. /// /// The scalar to add. - public override void Add(double scalar) + /// A copy of the vector with the scalar added. + public override Vector Add(double scalar) { if (scalar == 0.0) { - return; + return this.Clone(); } + var copy = (SparseVector)this.Clone(); for (var i = 0; i < Count; i++) { - this[i] += scalar; + copy[i] += scalar; } + return copy; } /// @@ -388,7 +391,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to add to this one. /// If the other vector is . /// If this vector and are not the same size. - public override void Add(Vector other) + public override Vector Add(Vector other) { if (other == null) { @@ -571,7 +574,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Subtracts a scalar from each element of the vector. /// /// The scalar to subtract. - public override void Subtract(double scalar) + public override Vector Subtract(double scalar) { if (scalar == 0.0) { @@ -613,7 +616,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to subtract from this one. /// If the other vector is . /// If this vector and are not the same size. - public override void Subtract(Vector other) + public override Vector Subtract(Vector other) { if (other == null) { @@ -750,7 +753,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Multiplies a scalar to each element of the vector. /// /// The scalar to multiply. - public override void Multiply(double scalar) + public override Vector Multiply(double scalar) { if (scalar == 1.0) { @@ -1053,9 +1056,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Pointwise multiplies this vector with another vector. /// /// The vector to pointwise multiply with this one. + /// A new vector which is the pointwise multiplication of the two vectors. /// If the other vector is . /// If this vector and are not the same size. - public override void PointwiseMultiply(Vector other) + public override Vector PointwiseMultiply(Vector other) { if (other == null) { @@ -1068,10 +1072,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double } // We cannot iterate using NonZeroCount because the value may be changed (if multiply by 0) + var copy = (SparseVector)this.Clone(); for (var i = 0; i < Count; i++) { - this[i] *= other[i]; + copy[i] *= other[i]; } + return copy; } /// @@ -1124,7 +1130,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The vector to pointwise divide this one by. /// If the other vector is . /// If this vector and are not the same size. - public override void PointwiseDivide(Vector other) + public override Vector PointwiseDivide(Vector other) { if (other == null) { diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 60831009..e5341d1e 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -120,17 +120,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The scalar to add. /// - public virtual void Add(double scalar) + /// A copy of the vector with the scalar added. + public virtual Vector Add(double scalar) { if (scalar == 0.0) { - return; + return this.Clone(); } + var copy = this.Clone(); CommonParallel.For( 0, - Count, - index => this[index] += scalar); + Count, + index => copy[index] += scalar); + return copy; } /// @@ -169,7 +172,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Returns this vector. + /// Returns a copy of this vector. /// /// /// This vector. @@ -179,7 +182,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public virtual Vector Plus() { - return this; + return this * 1.0; } /// @@ -188,13 +191,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The vector to add to this one. /// + /// A new vector containing the sum of both vectors. /// /// If the other vector is . /// /// /// If this vector and are not the same size. /// - public virtual void Add(Vector other) + public virtual Vector Add(Vector other) { if (other == null) { @@ -206,10 +210,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } + var copy = this.Clone(); CommonParallel.For( 0, - Count, - index => this[index] += other[index]); + Count, + index => copy[index] += other[index]); + return copy; } /// @@ -264,17 +270,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The scalar to subtract. /// - public virtual void Subtract(double scalar) + /// A new vector containing the subtraction of this vector and the scalar. + public virtual Vector Subtract(double scalar) { if (scalar == 0.0) { - return; + return this.Clone(); } + var copy = this.Clone(); CommonParallel.For( 0, Count, - index => this[index] -= scalar); + index => copy[index] -= scalar); + return copy; } /// @@ -332,13 +341,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The vector to subtract from this one. /// + /// A new vector containing the subtraction of the the two vectors. /// /// If the other vector is . /// /// /// If this vector and are not the same size. /// - public virtual void Subtract(Vector other) + public virtual Vector Subtract(Vector other) { if (other == null) { @@ -350,10 +360,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } + var copy = this.Clone(); CommonParallel.For( 0, Count, - index => this[index] -= other[index]); + index => copy[index] -= other[index]); + return copy; } /// @@ -408,17 +420,20 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The scalar to multiply. /// - public virtual void Multiply(double scalar) + /// A new vector that is the multiplication of the vector and the scalar. + public virtual Vector Multiply(double scalar) { if (scalar == 1.0) { - return; + return this.Clone(); } + var copy = this.Clone(); CommonParallel.For( 0, - Count, - index => this[index] *= scalar); + Count, + index => copy[index] *= scalar); + return copy; } /// @@ -498,14 +513,15 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// The scalar to divide with. /// - public virtual void Divide(double scalar) + /// A new vector that is the division of the vector and the scalar. + public virtual Vector Divide(double scalar) { if (scalar == 1.0) { - return; + return this.Clone(); } - Multiply(1.0 / scalar); + return Multiply(1.0 / scalar); } /// @@ -547,9 +563,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Pointwise multiplies this vector with another vector. /// /// The vector to pointwise multiply with this one. + /// A new vector which is the pointwise multiplication of the two vectors. /// If the other vector is . /// If this vector and are not the same size. - public virtual void PointwiseMultiply(Vector other) + public virtual Vector PointwiseMultiply(Vector other) { if (other == null) { @@ -561,10 +578,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } + var copy = this.Clone(); CommonParallel.For( 0, - Count, - index => this[index] *= other[index]); + Count, + index => copy[index] *= other[index]); + return copy; } /// @@ -615,9 +634,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Pointwise divide this vector with another vector. /// /// The vector to pointwise divide this one by. + /// A new vector which is the pointwise division of the two vectors. /// If the other vector is . /// If this vector and are not the same size. - public virtual void PointwiseDivide(Vector other) + public virtual Vector PointwiseDivide(Vector other) { if (other == null) { @@ -629,10 +649,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); } + var copy = this.Clone(); CommonParallel.For( 0, Count, - index => this[index] /= other[index]); + index => copy[index] /= other[index]); + return copy; } ///