From 914c31715722b7d39308282f7756caa4ff4c5ef9 Mon Sep 17 00:00:00 2001 From: Marcus Cuda Date: Mon, 31 Aug 2009 02:35:39 +0800 Subject: [PATCH] removed GetIndexedEnumerator from Vector - will add it back to the sparse Vector moved the scaling factor and max block size from control into the Parallel class and made them constant Signed-off-by: Marcus Cuda --- src/Numerics/Control.cs | 18 ---- .../LinearAlgebra/Double/DenseVector.cs | 9 +- src/Numerics/LinearAlgebra/Double/Vector.cs | 94 ++----------------- src/Numerics/Threading/Parallel.cs | 11 ++- src/Numerics/Threading/ThreadQueue.cs | 2 +- .../LinearAlgebraTests/Double/VectorTests.cs | 28 ------ 6 files changed, 22 insertions(+), 140 deletions(-) diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs index d217517c..aff59c25 100644 --- a/src/Numerics/Control.cs +++ b/src/Numerics/Control.cs @@ -44,8 +44,6 @@ namespace MathNet.Numerics ThreadSafeRandomNumberGenerators = true; DisableParallelization = false; InitialThreadBlockSize = 2; - BlockScalingFactor = 2; - MaximumBlockSize = 1024; } /// @@ -85,21 +83,5 @@ namespace MathNet.Numerics /// /// The initial size of the thread processing bloc. public static int InitialThreadBlockSize { get; set; } - - /// - /// Gets or sets the - /// processing block scaling factor. With each iteration through - /// the for each loop, the processing block increased by this factor - /// up to ; - /// - /// The processing block scaling factor. - public static int BlockScalingFactor { get; set; } - - /// - /// Gets or sets the maximum processing block size for - /// . - /// - /// The maximum processing block size. - public static int MaximumBlockSize { get; set; } } } diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index 08d0751a..58c9b59a 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -98,10 +98,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double 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; - } + // foreach (var item in other.GetIndexedEnumerator()) + // { + // Data[item.Key] = item.Value; + // } + Parallel.For(0, Count, index => this[index] = other[index]); } else { diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 73a397ed..3b0084f7 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -110,74 +110,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// 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 - /// non-zero element. - /// - /// - /// The enumerator returns a - /// - /// with the key being the element index and the value - /// being the value of the element at that index. For sparse vectors, the enumerator will exclude all elements - /// with a zero value. - /// - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "Needed to support sparse vectors.")] - public virtual IEnumerable> GetIndexedEnumerator() - { - for (var index = 0; index < Count; index++) - { - yield return new KeyValuePair(index, this[index]); - } - } - - /// - /// Returns an over the specified elements. - /// - /// - /// The element to start copying from. - /// - /// - /// The number of elements to enumerate over. - /// - /// - /// An over a range of this vector. - /// - /// - /// If or + - /// is greater than the vector's length. - /// - /// - /// The enumerator returns a - /// - /// with the key being the element index and the value - /// being the value of the element at that index. - /// - /// - /// - [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", - Justification = "Needed to support sparse vectors.")] - public virtual IEnumerable> GetIndexedEnumerator(int startIndex, int length) - { - if (startIndex > Count) - { - throw new ArgumentOutOfRangeException("startIndex"); - } - - if (startIndex + length > Count) - { - throw new ArgumentOutOfRangeException("length"); - } - - for (var index = startIndex; index < length; index++) - { - yield return new KeyValuePair(index, this[index]); - } - } - #region Elementary operations /// /// Adds a scalar to each element of the vector. @@ -333,11 +265,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// Added as an alternative to the unary negation operator. public virtual Vector Negate() { - var result = CreateVector(Count); - - Parallel.ForEach(GetIndexedEnumerator(), item => result[item.Key] = -item.Value); - - return result; + return this * -1; } /// @@ -406,7 +334,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double return; } - Parallel.ForEach(GetIndexedEnumerator(), item => this[item.Key] = scalar * item.Value); + Parallel.For(0, Count, index => this[index] *= scalar); } /// @@ -681,11 +609,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double var sum = 0.0; var syncLock = new object(); - Parallel.ForEach(GetIndexedEnumerator(), + Parallel.For(0, Count, ()=> 0.0, - (pair, localData) => + (index, localData) => { - localData += Math.Pow(Math.Abs(pair.Value), p); + localData += Math.Pow(Math.Abs(this[index]), p); return localData; }, localResult=> @@ -709,11 +637,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double { var max = 0.0; var syncLock = new object(); - Parallel.ForEach(GetIndexedEnumerator(), + Parallel.For(0, Count, () => 0.0, - (pair, localData) => + (index, localData) => { - localData = Math.Max(localData, Math.Abs(pair.Value)); + localData = Math.Max(localData, Math.Abs(this[index])); return localData; }, localResult => @@ -788,8 +716,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double { return; } - - Parallel.ForEach(GetIndexedEnumerator(), item => target[item.Key] = item.Value); + Parallel.For(0, Count, index => target[index] = this[index]); } /// @@ -890,9 +817,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// A that can be used to iterate through the collection. /// - /// - /// For sparse vectors, will perform better. - /// public virtual IEnumerator GetEnumerator() { for (var index = 0; index < Count; index++) diff --git a/src/Numerics/Threading/Parallel.cs b/src/Numerics/Threading/Parallel.cs index 813e7796..8a9eb72c 100644 --- a/src/Numerics/Threading/Parallel.cs +++ b/src/Numerics/Threading/Parallel.cs @@ -38,6 +38,9 @@ namespace MathNet.Numerics.Threading /// internal static class Parallel { + private const int ScalingFactor = 2; + private const int MaxBlockSize = 65536; + /// /// Executes a for loop in which iterations may run in parallel. /// @@ -220,7 +223,7 @@ namespace MathNet.Numerics.Threading var enumerator = source.GetEnumerator(); var maxBlockSize = Control.InitialThreadBlockSize; - var scalingFactor = Control.BlockScalingFactor; + var scalingFactor = ScalingFactor; var tasks = new List(); while (enumerator.MoveNext()) { @@ -246,7 +249,7 @@ namespace MathNet.Numerics.Threading ThreadQueue.Enqueue(task); tasks.Add(task); - maxBlockSize = Math.Min(Control.MaximumBlockSize, maxBlockSize * scalingFactor); + maxBlockSize = Math.Min(MaxBlockSize, maxBlockSize * scalingFactor); } if (tasks.Count > 0) @@ -275,7 +278,7 @@ namespace MathNet.Numerics.Threading var enumerator = source.GetEnumerator(); var maxBlockSize = Control.InitialThreadBlockSize; - var scalingFactor = Control.BlockScalingFactor; + var scalingFactor = ScalingFactor; var tasks = new List>(); var intial = localInit(); @@ -306,7 +309,7 @@ namespace MathNet.Numerics.Threading ThreadQueue.Enqueue(task); tasks.Add(task); - maxBlockSize = Math.Min(Control.MaximumBlockSize, maxBlockSize * scalingFactor); + maxBlockSize = Math.Min(MaxBlockSize, maxBlockSize * scalingFactor); } if (tasks.Count <= 0) diff --git a/src/Numerics/Threading/ThreadQueue.cs b/src/Numerics/Threading/ThreadQueue.cs index b83a9c1b..4469e915 100644 --- a/src/Numerics/Threading/ThreadQueue.cs +++ b/src/Numerics/Threading/ThreadQueue.cs @@ -55,7 +55,7 @@ namespace MathNet.Numerics.Threading /// /// Maximum number of jobs that can be in the queue at the same time. /// - private const int MaximumQueueLength = 1024; + private const int MaximumQueueLength = 4096; /// /// Counting Semaphore to make the worker thread wait for jobs diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 546ed2e5..46b99852 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -121,34 +121,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.IsFalse(vector1.Equals(null)); } - [Test] - [MultipleAsserts] - public void CanGetIndexedEnumerator() - { - var vector = CreateVector(_data); - var index = 0; - - foreach (var pair in vector.GetIndexedEnumerator()) - { - Assert.AreEqual(index, pair.Key); - Assert.AreEqual(++index, pair.Value); - } - } - - [Test] - [MultipleAsserts] - public void CanGetIndexedEnumeratorOverRange() - { - var vector = CreateVector(_data); - var index = 2; - - foreach (var pair in vector.GetIndexedEnumerator(2, 2)) - { - Assert.AreEqual(index, pair.Key); - Assert.AreEqual(++index, pair.Value); - } - } - [Test] [MultipleAsserts] public void ThrowsArgumentExceptionIfSizeIsNotPositive()