From 4abb536ea0628aec76fb75f9c677adf2b92f1dc1 Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Wed, 12 Aug 2009 21:03:37 +0800 Subject: [PATCH] Linear Algebra: Started implement DenseVector Signed-off-by: Marcus Cuda --- src/Numerics/Constants.cs | 5 + .../LinearAlgebra/Double/DenseVector.cs | 196 ++++++++++++++++++ src/Numerics/LinearAlgebra/Double/Matrix.cs | 2 +- src/Numerics/LinearAlgebra/Double/Vector.cs | 38 ++-- src/Numerics/Numerics.csproj | 4 + src/Numerics/Properties/Resources.Designer.cs | 11 +- src/Numerics/Properties/Resources.resx | 3 + .../Double/DenseVectorTests.cs | 25 +++ .../LinearAlgebraTests/Double/VectorTests.cs | 194 +++++++++++++++++ src/UnitTests/UnitTests.csproj | 2 + 10 files changed, 459 insertions(+), 21 deletions(-) create mode 100644 src/Numerics/LinearAlgebra/Double/DenseVector.cs create mode 100644 src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs create mode 100644 src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs diff --git a/src/Numerics/Constants.cs b/src/Numerics/Constants.cs index 8677e005..62df8c6a 100644 --- a/src/Numerics/Constants.cs +++ b/src/Numerics/Constants.cs @@ -159,5 +159,10 @@ namespace MathNet.Numerics /// The Khinchin constant /// prod(k=1 -> inf){1+1/(k*(k+2))^log(k,2)} public const double Khinchin = 2.6854520010653064453097148354817956938203822939944629530511523455572188595371520028011d; + + /// + /// The size of a double in bytes. + /// + public const int SizeOfDouble = sizeof(double); } } \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs new file mode 100644 index 00000000..bb440838 --- /dev/null +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -0,0 +1,196 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// Copyright (c) 2009 Math.NET +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// +namespace MathNet.Numerics.LinearAlgebra.Double +{ + using System; + + using Properties; + + /// + /// A vector using dense storage. + /// + public class DenseVector : Vector + { + /// + /// Initializes a new instance of the class with a given size. + /// + /// + /// the size of the vector. + /// + /// + /// If is less than one. + /// + public DenseVector(int size) + : base(size) + { + Data = new double[size]; + } + + /// + /// Initializes a new instance of the class with a given size + /// and each element set to the given value; + /// + /// + /// the size of the vector. + /// + /// + /// the value to set each element to. + /// + /// + /// If is less than one. + /// + public DenseVector(int size, double value) + : this(size) + { + for (var index = 0; index < Data.Length; index++) + { + Data[index] = value; + } + } + + /// + /// Initializes a new instance of the class by + /// copying the values from another. + /// + /// + /// The matrix to create the new matrix from. + /// + public DenseVector(Vector other) + : this(other.Count) + { + var vector = other as DenseVector; + if (vector == null) + { + // using enumerators since they will be more efficient for copying sparse matrices + foreach (var item in other.GetIndexedEnumerator()) + { + Data[item.Key] = item.Value; + } + } + else + { + Buffer.BlockCopy(vector.Data, 0, Data, 0, Data.Length * Constants.SizeOfDouble); + } + } + + /// + /// Gets the vector's data. + /// + /// The vector's data. + internal double[] Data + { + get; + private set; + } + + /// Gets or sets the value at the given . + /// The index of the value to get or set. + /// The value of the vector at the given . + /// If is negative or + /// greater than the size of the vector. + public override double this[int index] + { + get + { + return Data[index]; + } + + set + { + Data[index] = value; + } + } + + /// + /// Creates a matrix with the given dimensions using the same storage type + /// as this vector. + /// + /// + /// The number of rows. + /// + /// + /// The number of columns. + /// + /// + /// A matrix with the given dimensions. + /// + public override Matrix CreateMatrix(int rows, int columns) + { + throw new NotImplementedException(); + } + + /// + /// Creates a Vector of the given size using the same storage type + /// as this vector. + /// + /// + /// The size of the Vector to create. + /// + /// + /// The new Vector. + /// + public override Vector CreateVector(int size) + { + return new DenseVector(size); + } + + /// + /// 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 override void CopyTo(Vector target) + { + if (target == null) + { + throw new ArgumentNullException("target"); + } + + if (Count != target.Count) + { + throw new ArgumentException("target", Resources.ArgumentVectorsSameLengths); + } + + var otherVector = target as DenseVector; + if (otherVector == null) + { + for (var index = 0; index < Data.Length; index++) + { + target[index] = Data[index]; + } + } + else + { + Buffer.BlockCopy(Data, 0, otherVector.Data, 0, Data.Length * Constants.SizeOfDouble); + } + } + } +} \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index 02f2ba62..2a4a80b6 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -29,7 +29,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double using MathNet.Numerics.Properties; /// - /// A matrix class. + /// Defines the base class for Matrix classes. /// [Serializable] public abstract class Matrix : IFormattable, ICloneable, IEquatable diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 58d99359..8e473f70 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -198,10 +198,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double public abstract Matrix CreateMatrix(int rows, int columns); /// - /// Returns an that contains the position and value of the element. + /// Creates a Vector of the given size using the same storage type + /// as this vector. + /// + /// + /// The size of the Vector to create. + /// + /// + /// The new Vector. + /// + public abstract Vector CreateVector(int size); + + /// + /// Returns an that contains the position and value of the element. /// /// - /// An over this vector that contains the position and value of each + /// An over this vector that contains the position and value of each /// non-zero element. /// /// @@ -222,7 +234,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double } /// - /// Returns an over the specified elements. + /// Returns an over the specified elements. /// /// /// The element to start copying from. @@ -231,7 +243,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// The number of elements to enumerate over. /// /// - /// An over a range of this vector. + /// An over a range of this vector. /// /// /// If or + @@ -244,10 +256,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// being the value of the element at that index. /// /// - /// + /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Needed to support sparse vectors.")] - public virtual IEnumerator> GetIndexEnumerator(int startIndex, int length) + public virtual IEnumerable> GetIndexedEnumerator(int startIndex, int length) { if (startIndex > Count) { @@ -317,7 +329,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// A that can be used to iterate through the collection. /// /// - /// For sparse vectors, will perform better. + /// For sparse vectors, will perform better. /// [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "Needed to support sparse vectors.")] @@ -407,17 +419,5 @@ namespace MathNet.Numerics.LinearAlgebra.Double #endregion #endregion - - /// - /// Creates a Vector of the given size using the same storage type - /// as this vector. - /// - /// - /// The size of the Vector to create. - /// - /// - /// The new Vector. - /// - protected internal abstract Vector CreateVector(int size); } } \ No newline at end of file diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 053c9833..6d6bfb1a 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -82,6 +82,9 @@ + + + @@ -117,6 +120,7 @@ +