diff --git a/src/FSharpExamples/Apply.fs b/src/FSharpExamples/Apply.fs
index dc2c675b..b99e8a2a 100644
--- a/src/FSharpExamples/Apply.fs
+++ b/src/FSharpExamples/Apply.fs
@@ -27,6 +27,7 @@
//
module MathNet.Numerics.FSharp.Examples.Apply
+open System.Numerics
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra.Double
diff --git a/src/FSharpExamples/FSharpExamples.fsproj b/src/FSharpExamples/FSharpExamples.fsproj
index f91e2310..6b257ead 100644
--- a/src/FSharpExamples/FSharpExamples.fsproj
+++ b/src/FSharpExamples/FSharpExamples.fsproj
@@ -37,6 +37,7 @@
3.5
+
diff --git a/src/MathNet.Numerics.sln b/src/MathNet.Numerics.sln
index f14a0f50..42db81f8 100644
--- a/src/MathNet.Numerics.sln
+++ b/src/MathNet.Numerics.sln
@@ -13,7 +13,7 @@ Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpExamples", "FSharpExa
EndProject
Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "FSharpUnitTests", "FSharpUnitTests\FSharpUnitTests.fsproj", "{F2F8032B-A31D-4E33-A05E-F2CDCBFAA75D}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silverlight", "Silverlight\Silverlight.csproj", "{0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Silverlight", "Silverlight\Silverlight.csproj", "{793E332F-E2B1-4D1D-9B2E-27E90B99BF93}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -45,10 +45,10 @@ Global
{F2F8032B-A31D-4E33-A05E-F2CDCBFAA75D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2F8032B-A31D-4E33-A05E-F2CDCBFAA75D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2F8032B-A31D-4E33-A05E-F2CDCBFAA75D}.Release|Any CPU.Build.0 = Release|Any CPU
- {0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}.Release|Any CPU.Build.0 = Release|Any CPU
+ {793E332F-E2B1-4D1D-9B2E-27E90B99BF93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {793E332F-E2B1-4D1D-9B2E-27E90B99BF93}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {793E332F-E2B1-4D1D-9B2E-27E90B99BF93}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {793E332F-E2B1-4D1D-9B2E-27E90B99BF93}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
index f29344f3..7c8e7212 100644
--- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
+++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebraProvider.cs
@@ -24,10 +24,9 @@
namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
using System;
- using System.Collections.Concurrent;
using System.Numerics;
- using System.Threading.Tasks;
using Properties;
+ using Threading;
///
/// The managed linear algebra provider.
@@ -67,27 +66,13 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
if (alpha == 1.0)
{
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- y[i] += x[i];
- }
- });
+ CommonParallel.For(0, y.Length,
+ index => { y[index] += x[index]; });
}
else
{
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- y[i] += alpha * x[i];
- }
- });
+ CommonParallel.For(0, y.Length,
+ index => { y[index] += alpha * x[index]; });
}
}
@@ -109,15 +94,8 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
return;
}
- Parallel.ForEach(
- Partitioner.Create(0, x.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- x[i] = alpha * x[i];
- }
- });
+ CommonParallel.For(0, x.Length,
+ index => { x[index] = alpha * x[index]; });
}
///
@@ -144,30 +122,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- var sync = new object();
- var d = 0.0;
-
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- () => 0.0,
- (range, loopState, localData) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- localData += y[i] * x[i];
- }
-
- return localData;
- },
- localResult =>
- {
- lock (sync)
- {
- d += localResult;
- }
- });
-
- return d;
+ return CommonParallel.Aggregate(0, y.Length, index => y[index] * x[index]);
}
///
@@ -202,15 +157,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- result[i] = x[i] + y[i];
- }
- });
+ CommonParallel.For(0, y.Length, index => { result[index] = x[index] + y[index]; });
}
///
@@ -245,15 +192,8 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- result[i] = x[i] - y[i];
- }
- });
+ CommonParallel.For(0, y.Length,
+ index => { result[index] = x[index] - y[index]; });
}
///
@@ -287,16 +227,9 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
-
- Parallel.ForEach(
- Partitioner.Create(0, y.Length),
- (range, loopState) =>
- {
- for (var i = range.Item1; i < range.Item2; i++)
- {
- result[i] = x[i] * y[i];
- }
- });
+
+ CommonParallel.For(0, y.Length,
+ index => { result[index] = x[index] * y[index]; });
}
public double MatrixNorm(Norm norm, double[] matrix)
@@ -513,190 +446,158 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, aColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != bRows; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != bColumns; l++)
- {
- s += adata[iIndex + l] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = s;
- }
- }
- });
+ CommonParallel.For(0, aColumns,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != bRows; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != bColumns; l++)
+ {
+ s += adata[iIndex + l] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = s;
+ }
+ });
}
else if ((int)transposeA > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aColumns; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != aRows; l++)
- {
- s += adata[iIndex + l] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = s;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aColumns; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != aRows; l++)
+ {
+ s += adata[iIndex + l] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = s;
+ }
+ });
}
else if ((int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bRows),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = s;
- }
- }
- });
+ CommonParallel.For(0, bRows,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = s;
+ }
+ });
}
else
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = s;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = s;
+ }
+ });
}
}
else
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, aColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != bRows; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != bColumns; l++)
- {
- s += adata[iIndex + l] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = c[jIndex + i] * beta + s;
- }
- }
- });
+ CommonParallel.For(0, aColumns,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != bRows; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != bColumns; l++)
+ {
+ s += adata[iIndex + l] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = c[jIndex + i] * beta + s;
+ }
+ });
}
else if ((int)transposeA > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aColumns; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != aRows; l++)
- {
- s += adata[iIndex + l] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = s + c[jcIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aColumns; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != aRows; l++)
+ {
+ s += adata[iIndex + l] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = s + c[jcIndex + i] * beta;
+ }
+ });
}
else if ((int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bRows),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = s + c[jIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bRows,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = s + c[jIndex + i] * beta;
+ }
+ });
}
else
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = s + c[jcIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = s + c[jcIndex + i] * beta;
+ }
+ });
}
}
}
@@ -704,95 +605,79 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, aColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != bRows; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != bColumns; l++)
- {
- s += adata[iIndex + l] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = c[jIndex + i] * beta + alpha * s;
- }
- }
- });
+ CommonParallel.For(0, aColumns,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != bRows; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != bColumns; l++)
+ {
+ s += adata[iIndex + l] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = c[jIndex + i] * beta + alpha * s;
+ }
+ });
}
else if ((int)transposeA > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aColumns; i++)
- {
- var iIndex = i * aRows;
- double s = 0;
- for (var l = 0; l != aRows; l++)
- {
- s += adata[iIndex + l] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = alpha * s + c[jcIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aColumns; i++)
+ {
+ var iIndex = i * aRows;
+ double s = 0;
+ for (var l = 0; l != aRows; l++)
+ {
+ s += adata[iIndex + l] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = alpha * s + c[jcIndex + i] * beta;
+ }
+ });
}
else if ((int)transposeB > 111)
{
- Parallel.ForEach(
- Partitioner.Create(0, bRows),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jIndex = j * cRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[l * bRows + j];
- }
-
- c[jIndex + i] = alpha * s + c[jIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bRows,
+ j =>
+ {
+ var jIndex = j * cRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[l * bRows + j];
+ }
+
+ c[jIndex + i] = alpha * s + c[jIndex + i] * beta;
+ }
+ });
}
else
{
- Parallel.ForEach(
- Partitioner.Create(0, bColumns),
- (range, loopState) =>
- {
- for (var j = range.Item1; j < range.Item2; j++)
- {
- var jcIndex = j * cRows;
- var jbIndex = j * bRows;
- for (var i = 0; i != aRows; i++)
- {
- double s = 0;
- for (var l = 0; l != aColumns; l++)
- {
- s += adata[l * aRows + i] * bdata[jbIndex + l];
- }
-
- c[jcIndex + i] = alpha * s + c[jcIndex + i] * beta;
- }
- }
- });
+ CommonParallel.For(0, bColumns,
+ j =>
+ {
+ var jcIndex = j * cRows;
+ var jbIndex = j * bRows;
+ for (var i = 0; i != aRows; i++)
+ {
+ double s = 0;
+ for (var l = 0; l != aColumns; l++)
+ {
+ s += adata[l * aRows + i] * bdata[jbIndex + l];
+ }
+
+ c[jcIndex + i] = alpha * s + c[jcIndex + i] * beta;
+ }
+ });
}
}
}
@@ -980,11 +865,11 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
if (alpha == 1.0)
{
- Parallel.For(0, y.Length, i => y[i] += x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += x[i]);
}
else
{
- Parallel.For(0, y.Length, i => y[i] += alpha * x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += alpha * x[i]);
}
}
@@ -1006,7 +891,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
return;
}
- Parallel.For(0, x.Length, i => x[i] = alpha * x[i]);
+ CommonParallel.For(0, x.Length, i => x[i] = alpha * x[i]);
}
///
@@ -1075,7 +960,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
}
///
@@ -1110,7 +995,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
}
///
@@ -1145,7 +1030,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
public float MatrixNorm(Norm norm, float[] matrix)
@@ -1368,7 +1253,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -1386,7 +1271,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1405,7 +1290,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -1422,7 +1307,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1443,7 +1328,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -1461,7 +1346,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1480,7 +1365,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -1497,7 +1382,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1519,7 +1404,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -1537,7 +1422,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1556,7 +1441,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -1573,7 +1458,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -1779,11 +1664,11 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
if (alpha == 1.0)
{
- Parallel.For(0, y.Length, i => y[i] += x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += x[i]);
}
else
{
- Parallel.For(0, y.Length, i => y[i] += alpha * x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += alpha * x[i]);
}
}
@@ -1805,7 +1690,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
return;
}
- Parallel.For(0, x.Length, i => x[i] = alpha * x[i]);
+ CommonParallel.For(0, x.Length, i => x[i] = alpha * x[i]);
}
///
@@ -1874,7 +1759,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
}
///
@@ -1909,7 +1794,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
}
///
@@ -1944,7 +1829,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
public Complex MatrixNorm(Norm norm, Complex[] matrix)
@@ -2167,7 +2052,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -2185,7 +2070,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2204,7 +2089,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -2221,7 +2106,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2242,7 +2127,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -2260,7 +2145,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2279,7 +2164,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -2296,7 +2181,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2318,7 +2203,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -2336,7 +2221,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2355,7 +2240,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -2372,7 +2257,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2543,11 +2428,11 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
if (alpha == 1.0F)
{
- Parallel.For(0, y.Length, i => y[i] += x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += x[i]);
}
else
{
- Parallel.For(0, y.Length, i => y[i] += alpha * x[i]);
+ CommonParallel.For(0, y.Length, i => y[i] += alpha * x[i]);
}
}
@@ -2569,7 +2454,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
return;
}
- Parallel.For(0, x.Length, i => x[i] = alpha * x[i]);
+ CommonParallel.For(0, x.Length, i => x[i] = alpha * x[i]);
}
///
@@ -2638,7 +2523,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] + y[i]);
}
///
@@ -2673,7 +2558,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] - y[i]);
}
///
@@ -2708,7 +2593,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
throw new ArgumentException(Resources.ArgumentVectorsSameLength);
}
- Parallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
+ CommonParallel.For(0, y.Length, i => result[i] = x[i] * y[i]);
}
public Complex32 MatrixNorm(Norm norm, Complex32[] matrix)
@@ -2931,7 +2816,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -2949,7 +2834,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -2968,7 +2853,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -2985,7 +2870,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -3006,7 +2891,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -3024,7 +2909,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -3043,7 +2928,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -3060,7 +2945,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -3082,7 +2967,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
{
if ((int)transposeA > 111 && (int)transposeB > 111)
{
- Parallel.For(0, aColumns, j =>
+ CommonParallel.For(0, aColumns, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != bRows; i++)
@@ -3100,7 +2985,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeA > 111)
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
@@ -3119,7 +3004,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else if ((int)transposeB > 111)
{
- Parallel.For(0, bRows, j =>
+ CommonParallel.For(0, bRows, j =>
{
var jIndex = j * cRows;
for (var i = 0; i != aRows; i++)
@@ -3136,7 +3021,7 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra
}
else
{
- Parallel.For(0, bColumns, j =>
+ CommonParallel.For(0, bColumns, j =>
{
var jcIndex = j * cRows;
var jbIndex = j * bRows;
diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs
index 15381230..4d3ee43d 100644
--- a/src/Numerics/Control.cs
+++ b/src/Numerics/Control.cs
@@ -28,6 +28,7 @@
namespace MathNet.Numerics
{
+ using System;
using Algorithms.LinearAlgebra;
///
@@ -35,6 +36,13 @@ namespace MathNet.Numerics
///
public static class Control
{
+#if !SILVERLIGHT
+ ///
+ /// Initial number of threads to use;
+ ///
+ private static int _numberOfThreads = Environment.ProcessorCount;
+#endif
+
///
/// Initializes static members of the Control class.
///
@@ -75,5 +83,28 @@ namespace MathNet.Numerics
{
get; set;
}
+
+ ///
+ /// Gets or sets a value indicating how many parallel worker threads shall be used
+ /// when parallelization is applicable.
+ ///
+ /// The Silverlight version of the library defaults to one thread.
+ public static int NumberOfParallelWorkerThreads
+ {
+#if SILVERLIGHT
+ get { return ThreadQueue.ThreadCount; }
+ set { ThreadQueue.Start(value); }
+#else
+ get
+ {
+ return _numberOfThreads;
+ }
+
+ set
+ { // instead of throwing an out of range exception, simply normalize
+ _numberOfThreads = Math.Max(1, Math.Min(1024, value));
+ }
+#endif
+ }
}
}
diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
index 825ba0eb..45fda59d 100644
--- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
+++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Bluestein.cs
@@ -30,9 +30,9 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
using System.Numerics;
- using System.Threading.Tasks;
using NumberTheory;
-
+ using Threading;
+
///
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
///
@@ -71,7 +71,7 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
Complex[] b = new Complex[m];
Complex[] a = new Complex[m];
- Parallel.Invoke(
+ CommonParallel.Invoke(
() =>
{
// Build and transform padded sequence b_k = exp(I*Pi*k^2/N)
diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
index cf9aadf9..dd8466c8 100644
--- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
+++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.Naive.cs
@@ -25,9 +25,8 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
- using System.Collections.Concurrent;
using System.Numerics;
- using System.Threading.Tasks;
+ using Threading;
///
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
@@ -45,23 +44,21 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
var w0 = exponentSign * Constants.Pi2 / samples.Length;
var spectrum = new Complex[samples.Length];
- Parallel.ForEach(
- Partitioner.Create(0, samples.Length),
- (range, loopState) =>
- {
- for (var k = range.Item1; k < range.Item2; k++)
- {
- var wk = w0 * k;
- var sum = Complex.Zero;
- for (var n = 0; n < samples.Length; n++)
- {
- var w = n * wk;
- sum += samples[n] * new Complex(Math.Cos(w), Math.Sin(w));
- }
+ CommonParallel.For(
+ 0,
+ samples.Length,
+ index =>
+ {
+ var wk = w0 * index;
+ var sum = Complex.Zero;
+ for (var n = 0; n < samples.Length; n++)
+ {
+ var w = n * wk;
+ sum += samples[n] * new Complex(Math.Cos(w), Math.Sin(w));
+ }
- spectrum[k] = sum;
- }
- });
+ spectrum[index] = sum;
+ });
return spectrum;
}
diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
index 76107de1..7644a27c 100644
--- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
+++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteFourierTransform.RadixN.cs
@@ -25,11 +25,10 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
- using System.Collections.Concurrent;
using System.Numerics;
- using System.Threading.Tasks;
using NumberTheory;
using Properties;
+ using Threading;
///
/// Complex Fast (FFT) Implementation of the Discrete Fourier Transform (DFT).
@@ -127,15 +126,11 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
for (var levelSize = 1; levelSize < samples.Length; levelSize *= 2)
{
var size = levelSize;
- Parallel.ForEach(
- Partitioner.Create(0, size),
- (range, loopState) =>
- {
- for (var k = range.Item1; k < range.Item2; k++)
- {
- Radix2Step(samples, exponentSign, size, k);
- }
- });
+
+ CommonParallel.For(
+ 0,
+ size,
+ index => Radix2Step(samples, exponentSign, size, index));
}
}
diff --git a/src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Naive.cs b/src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Naive.cs
index 2b079062..d48c29d0 100644
--- a/src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Naive.cs
+++ b/src/Numerics/IntegralTransforms/Algorithms/DiscreteHartleyTransform.Naive.cs
@@ -25,8 +25,7 @@
namespace MathNet.Numerics.IntegralTransforms.Algorithms
{
using System;
- using System.Collections.Concurrent;
- using System.Threading.Tasks;
+ using Threading;
///
/// Fast (FHT) Implementation of the Discrete Hartley Transform (DHT).
@@ -43,22 +42,20 @@ namespace MathNet.Numerics.IntegralTransforms.Algorithms
var w0 = Constants.Pi2 / samples.Length;
var spectrum = new double[samples.Length];
- Parallel.ForEach(
- Partitioner.Create(0, samples.Length),
- (range, loopState) =>
+ CommonParallel.For(
+ 0,
+ samples.Length,
+ index =>
{
- for (var k = range.Item1; k < range.Item2; k++)
+ var wk = w0 * index;
+ var sum = 0.0;
+ for (var n = 0; n < samples.Length; n++)
{
- var wk = w0 * k;
- var sum = 0.0;
- for (var n = 0; n < samples.Length; n++)
- {
- var w = n * wk;
- sum += samples[n] * Constants.Sqrt2 * Math.Cos(w - Constants.PiOver4);
- }
-
- spectrum[k] = sum;
+ var w = n * wk;
+ sum += samples[n] * Constants.Sqrt2 * Math.Cos(w - Constants.PiOver4);
}
+
+ spectrum[index] = sum;
});
return spectrum;
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index 4e20e60e..9d335228 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -180,6 +180,7 @@
+
diff --git a/src/Numerics/Threading/CommonParallel.cs b/src/Numerics/Threading/CommonParallel.cs
new file mode 100644
index 00000000..dba3eae9
--- /dev/null
+++ b/src/Numerics/Threading/CommonParallel.cs
@@ -0,0 +1,147 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://mathnet.opensourcedotnet.info
+// Copyright (c) 2009-2010 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.Threading
+{
+ using System;
+
+#if !SILVERLIGHT
+ using System.Collections.Concurrent;
+ using System.Threading.Tasks;
+#endif
+
+ ///
+ /// Used to simplify parallel code, particularly between the .NET 4.0 and Silverlight Code.
+ ///
+ internal static class CommonParallel
+ {
+ ///
+ /// Executes a for loop in which iterations may run in parallel.
+ ///
+ /// The start index, inclusive.
+ /// The end index, exclusive.
+ /// The body to be invoked for each iteration.
+ /// The argument is null.
+ /// At least one invocation of the body threw an exception.
+ public static void For(int fromInclusive, int toExclusive, Action body)
+ {
+#if SILVERLIGHT
+ Parallel.For(fromInclusive, toExclusive, body);
+#else
+ if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2)
+ {
+ for (var index = fromInclusive; index < toExclusive; index++)
+ {
+ body(index);
+ }
+ }
+ else
+ {
+ Parallel.ForEach(
+ Partitioner.Create(fromInclusive, toExclusive),
+ new ParallelOptions { MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads },
+ (range, loopState) =>
+ {
+ for (var i = range.Item1; i < range.Item2; i++)
+ {
+ body(i);
+ }
+ });
+ }
+#endif
+ }
+
+ ///
+ /// Aggregates a function over a loop.
+ ///
+ /// Starting index of the loop.
+ /// Ending index of the loop
+ /// The function to aggregate.
+ /// The sum of the function over the loop.
+ public static double Aggregate(int fromInclusive, int toExclusive, Func body)
+ {
+ var sync = new object();
+ var sum = 0.0;
+
+#if SILVERLIGHT
+ Parallel.For(
+ fromInclusive,
+ toExclusive,
+ () => 0.0,
+ (i, localData) => localData += body(i),
+ localResult =>
+ {
+ lock (sync)
+ {
+ sum += localResult;
+ }
+ });
+#else
+
+ if (Control.DisableParallelization || Control.NumberOfParallelWorkerThreads < 2)
+ {
+ for (var index = fromInclusive; index < toExclusive; index++)
+ {
+ sum += body(index);
+ }
+ }
+ else
+ {
+ Parallel.ForEach(
+ Partitioner.Create(fromInclusive, toExclusive),
+ new ParallelOptions { MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads },
+ () => 0.0,
+ (range, loopState, localData) =>
+ {
+ for (var i = range.Item1; i < range.Item2; i++)
+ {
+ localData += body(i);
+ }
+
+ return localData;
+ },
+ localResult =>
+ {
+ lock (sync)
+ {
+ sum += localResult;
+ }
+ });
+ }
+#endif
+ return sum;
+ }
+
+ ///
+ /// Executes each of the provided actions inside a discrete, asynchronous task.
+ ///
+ /// An array of actions to execute.
+ /// The actions array contains a null element.
+ /// An action threw an exception.
+ public static void Invoke(params Action[] actions)
+ {
+ Parallel.Invoke(actions);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Silverlight/Properties/AssemblyInfo.cs b/src/Silverlight/Properties/AssemblyInfo.cs
index d9214ba6..e01c184a 100644
--- a/src/Silverlight/Properties/AssemblyInfo.cs
+++ b/src/Silverlight/Properties/AssemblyInfo.cs
@@ -44,4 +44,4 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("7b66646f-f0ee-425d-9065-910d1937a2df")]
[assembly: NeutralResourcesLanguage("en")]
-[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed2314a577643d859571b8b9307c6ff2670525c4598fbb307e57ea65ebf5d4417284cb3da9181636480b623f4db8cc3c1947244ba069df0df86e2431621f51a488f9929519a1c5d0ae595f6e2d0e4094685f0c1229ff658360acbb9f63f1a0258e984dda00dc7ad4fd16dbb550ec1ef8a11df138402b7c1998ee224e652c839b")]
+//[assembly: InternalsVisibleTo("MathNet.Numerics.UnitTests, PublicKey=0024000004800000940000000602000000240000525341310004000001000100ed2314a577643d859571b8b9307c6ff2670525c4598fbb307e57ea65ebf5d4417284cb3da9181636480b623f4db8cc3c1947244ba069df0df86e2431621f51a488f9929519a1c5d0ae595f6e2d0e4094685f0c1229ff658360acbb9f63f1a0258e984dda00dc7ad4fd16dbb550ec1ef8a11df138402b7c1998ee224e652c839b")]
diff --git a/src/Silverlight/Silverlight.csproj b/src/Silverlight/Silverlight.csproj
index e5b3abf5..5c86bdbd 100644
--- a/src/Silverlight/Silverlight.csproj
+++ b/src/Silverlight/Silverlight.csproj
@@ -1,47 +1,28 @@
-
- v3.5
-
Debug
AnyCPU
- 9.0.30729
+ 8.0.50727
2.0
- {0CCA2BA4-9DF2-4E9B-8A77-0A1F61A96A77}
+ {793E332F-E2B1-4D1D-9B2E-27E90B99BF93}
{A1591282-1198-4647-A2B1-27E5FF5F6F3B};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}
Library
Properties
MathNet.Numerics
MathNet.Numerics.Silverlight
+ Silverlight
v4.0
+ $(TargetFrameworkVersion)
false
true
true
- true
- ..\MathNet.Numerics.snk
- Silverlight
- $(TargetFrameworkVersion)
-
-
- 3.5
-
- publish\
- true
- Disk
- false
- Foreground
- 7
- Days
- false
- false
- true
- 0
- 1.0.0.%2a
- false
- false
- true
-
+
+
+
+ v3.5
true
@@ -53,7 +34,6 @@
true
prompt
4
- AllRules.ruleset
pdbonly
@@ -64,12 +44,11 @@
true
prompt
4
- AllRules.ruleset
+
-
@@ -78,13 +57,13 @@
- Algorithms\ILinearAlgebraProvider.cs
+ Algorithms\LinearAlgebra\ILinearAlgebraProvider.cs
- Algorithms\ILinearAlgebraProviderOfT.cs
+ Algorithms\LinearAlgebra\ILinearAlgebraProviderOfT.cs
- Algorithms\ManagedLinearAlgebraProvider.cs
+ Algorithms\LinearAlgebra\ManagedLinearAlgebraProvider.cs
Combinatorics.cs
@@ -230,21 +209,6 @@
IPrecisionSupport.cs
-
- LinearAlgebra\Double\DenseMatrix.cs
-
-
- LinearAlgebra\Double\DenseVector.cs
-
-
- LinearAlgebra\Double\Matrix.Arithmetic.cs
-
-
- LinearAlgebra\Double\Matrix.cs
-
-
- LinearAlgebra\Double\Vector.cs
-
NumberTheory\IntegerTheory.cs
@@ -255,7 +219,7 @@
Precision.cs
- Properties\Resources.Designer.cs
+ Resources.Designer.cs
Random\AbstractRandomNumberGenerator.cs
@@ -338,49 +302,35 @@
Statistics\Statistics.cs
+
+ Threading\CommonParallel.cs
+
Trigonometry.cs
-
- Version.cs
-
+
+
+
+
+
- Properties\Resources.resx
+ Resources.resx
-
- MathNet.Numerics.snk
+
+ Version.tt
+ TextTemplatingFileGenerator
+ Version1.cs
-
- False
- .NET Framework 3.5 SP1 Client Profile
- false
-
-
- False
- .NET Framework 3.5 SP1
- true
-
-
- False
- Windows Installer 3.1
- true
-
+
-
@@ -388,4 +338,11 @@
+
\ No newline at end of file
diff --git a/src/Silverlight/Threading/AggregateException.cs b/src/Silverlight/Threading/AggregateException.cs
new file mode 100644
index 00000000..b1d6d042
--- /dev/null
+++ b/src/Silverlight/Threading/AggregateException.cs
@@ -0,0 +1,65 @@
+//
+// 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.Threading
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Collections.ObjectModel;
+
+ ///
+ /// Represents multiple errors that occur during application execution.
+ ///
+ public class AggregateException : Exception
+ {
+ ///
+ /// List of the aggregated exceptions.
+ ///
+ private readonly IList _exceptions = new List();
+
+ ///
+ /// Initializes a new instance of the AggregateException class with a specified error message and references to the inner exceptions that are the cause of this exception.
+ ///
+ /// The exceptions that are the cause of the current exception.
+ public AggregateException(IEnumerable exceptions)
+ {
+ foreach (var exception in exceptions)
+ {
+ this._exceptions.Add(exception);
+ }
+ }
+
+ ///
+ /// Gets a read-only collection of the Exception instances that caused the current exception.
+ ///
+ /// A read-only collection of the Exception instances that caused the current exception
+ public ReadOnlyCollection InnerExceptions
+ {
+ get
+ {
+ return new ReadOnlyCollection(this._exceptions);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Silverlight/Threading/Parallel.cs b/src/Silverlight/Threading/Parallel.cs
new file mode 100644
index 00000000..9c266a29
--- /dev/null
+++ b/src/Silverlight/Threading/Parallel.cs
@@ -0,0 +1,485 @@
+//
+// 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.Threading
+{
+ using System;
+ using System.Collections.Generic;
+ using Properties;
+
+ ///
+ /// Provides support for parallel loops.
+ ///
+ internal static class Parallel
+ {
+ ///
+ /// The amount to scale the foreach buffer after each iteration.
+ ///
+ private const int ScalingFactor = 2;
+
+ ///
+ /// The maximum size of the foreach buffer.
+ ///
+ private const int MaxBlockSize = 65536;
+
+ ///
+ /// The initial size of the for each buffer.
+ ///
+ private const int IntialBlockSize = 1024;
+
+ ///
+ /// Executes a for loop in which iterations may run in parallel.
+ ///
+ /// The start index, inclusive.
+ /// The end index, exclusive.
+ /// The body to be invoked for each iteration.
+ /// The argument is null.
+ /// At least one invocation of the body threw an exception.
+ public static void For(int fromInclusive, int toExclusive, Action body)
+ {
+ if (body == null)
+ {
+ throw new ArgumentNullException("body");
+ }
+
+ // fast forward execution if it's only one or none items
+ var count = toExclusive - fromInclusive;
+ if (count <= 1)
+ {
+ if (count == 1)
+ {
+ body(fromInclusive);
+ }
+
+ return;
+ }
+
+ // fast forward execution in case parallelization is disabled
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
+ {
+ for (int i = fromInclusive; i < toExclusive; i++)
+ {
+ body(i);
+ }
+
+ return;
+ }
+
+ var actions = new Action[ThreadQueue.ThreadCount];
+ var size = count / actions.Length;
+
+ // partition the jobs into separate sets for each but the last worked thread
+ for (var i = 0; i < actions.Length - 1; i++)
+ {
+ var start = fromInclusive + (i * size);
+ var stop = fromInclusive + ((i + 1) * size);
+
+ actions[i] =
+ () =>
+ {
+ for (int j = start; j < stop; j++)
+ {
+ body(j);
+ }
+ };
+ }
+
+ // add another set for last worker thread
+ actions[actions.Length - 1] =
+ () =>
+ {
+ for (int i = fromInclusive + ((actions.Length - 1) * size); i < toExclusive; i++)
+ {
+ body(i);
+ }
+ };
+
+ Invoke(actions);
+ }
+
+ ///
+ /// Executes a for loop in which iterations may run in parallel.
+ ///
+ /// The type of the thread-local data.
+ /// The start index, inclusive.
+ /// The end index, exclusive.
+ /// The function delegate that returns the initial state of the local data for each thread.
+ /// The delegate that is invoked once per iteration.
+ /// The delegate that performs a final action on the local state of each thread.
+ public static void For(int fromInclusive, int toExclusive, Func localInit, Func body, Action localFinally)
+ {
+ var count = toExclusive - fromInclusive;
+ var tasks = new Task[ThreadQueue.ThreadCount];
+ var size = count / tasks.Length;
+
+ // fast forward execution if it's only one or none items
+ if (count <= 1)
+ {
+ if (count == 1)
+ {
+ localFinally(body(fromInclusive, localInit()));
+ }
+
+ return;
+ }
+
+ // fast forward execution in case parallelization is disabled
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
+ {
+ var localresult = localInit();
+ for (var i = fromInclusive; i < toExclusive; i++)
+ {
+ localresult = body(i, localresult);
+ }
+
+ localFinally(localresult);
+ return;
+ }
+
+ // partition the jobs into separate sets for each but the last worked thread
+ for (var i = 0; i < tasks.Length - 1; i++)
+ {
+ var start = fromInclusive + (i * size);
+ var stop = fromInclusive + ((i + 1) * size);
+ tasks[i] = new Task(
+ localData =>
+ {
+ var localresult = (T)localData;
+ for (var j = start; j < stop; j++)
+ {
+ localresult = body(j, localresult);
+ }
+
+ return localresult;
+ },
+ localInit());
+ ThreadQueue.Enqueue(tasks[i]);
+ }
+
+ // add another set for last worker thread
+ tasks[tasks.Length - 1] = new Task(
+ localData =>
+ {
+ var localresult = (T)localData;
+ for (var i = fromInclusive + ((tasks.Length - 1) * size); i < toExclusive; i++)
+ {
+ localresult = body(i, localresult);
+ }
+
+ return localresult;
+ },
+ localInit());
+
+ ThreadQueue.Enqueue(tasks[tasks.Length - 1]);
+ if (tasks.Length <= 0)
+ {
+ return;
+ }
+
+ WaitForTasksToComplete(tasks);
+
+ foreach (var t in tasks)
+ {
+ localFinally(t.Result);
+ }
+
+ CollectExceptions(tasks);
+ }
+
+ ///
+ /// Executes a for each operation on an IEnumerable{T} in which iterations may run in parallel.
+ ///
+ /// The type of the data in the source.
+ /// An enumerable data source.
+ /// The delegate that is invoked once per iteration.
+ public static void ForEach(IEnumerable source, Action body)
+ {
+ if (body == null)
+ {
+ throw new ArgumentNullException("body");
+ }
+
+ // fast forward execution in case parallelization is disabled
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
+ {
+ foreach (var item in source)
+ {
+ body(item);
+ }
+
+ return;
+ }
+
+ // source is a IList, call For instead.
+ if (source is IList)
+ {
+ var list = (IList)source;
+ For(0, list.Count, i => body(list[i]));
+ return;
+ }
+
+ var maxBlockSize = IntialBlockSize;
+ var tasks = new List();
+
+ var enumerator = source.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ var pos = 0;
+ var list = new T[maxBlockSize];
+ list[pos++] = enumerator.Current;
+
+ var count = 1;
+ while (count < maxBlockSize && enumerator.MoveNext())
+ {
+ list[pos++] = enumerator.Current;
+ count++;
+ }
+
+ var task = new Task(
+ () =>
+ {
+ for (var i = 0; i < pos; i++)
+ {
+ body(list[i]);
+ }
+ });
+
+ ThreadQueue.Enqueue(task);
+ tasks.Add(task);
+ maxBlockSize = Math.Min(MaxBlockSize, maxBlockSize * ScalingFactor);
+ }
+
+ if (tasks.Count > 0)
+ {
+ WaitForTasksToComplete(tasks.ToArray());
+ CollectExceptions(tasks);
+ }
+ }
+
+ ///
+ /// Executes a for each operation on an IEnumerable{TSource in which iterations may run in parallel.
+ ///
+ /// The type of the data in the source.
+ /// The type of the thread-local data.
+ /// An enumerable data source.
+ /// The function delegate that returns the initial state of the local data for each thread.
+ /// The delegate that is invoked once per iteration.
+ /// The delegate that performs a final action on the local state of each thread.
+ public static void ForEach(IEnumerable source, Func localInit, Func body, Action localFinally)
+ {
+ if (body == null)
+ {
+ throw new ArgumentNullException("body");
+ }
+
+ // fast forward execution in case parallelization is disabled
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
+ {
+ var localResult = localInit();
+ foreach (var item in source)
+ {
+ localResult = body(item, localResult);
+ }
+
+ localFinally(localResult);
+ return;
+ }
+
+ // source is a IList, call For instead.
+ if (source is IList)
+ {
+ var list = (IList)source;
+ For(0, list.Count, localInit, (i, local) => body(list[i], local), localFinally);
+ return;
+ }
+
+ var maxBlockSize = IntialBlockSize;
+ var tasks = new List>();
+
+ var enumerator = source.GetEnumerator();
+ while (enumerator.MoveNext())
+ {
+ var pos = 0;
+ var list = new TSource[maxBlockSize];
+ list[pos++] = enumerator.Current;
+
+ var count = 1;
+ while (count < maxBlockSize && enumerator.MoveNext())
+ {
+ list[pos++] = enumerator.Current;
+ count++;
+ }
+
+ var task = new Task(
+ localData =>
+ {
+ var localresult = localData;
+ for (var i = 0; i < pos; i++)
+ {
+ localresult = body(list[i], (TLocal)localresult);
+ }
+
+ return (TLocal)localresult;
+ },
+ localInit());
+
+ ThreadQueue.Enqueue(task);
+ tasks.Add(task);
+ maxBlockSize = Math.Min(MaxBlockSize, maxBlockSize * ScalingFactor);
+ }
+
+ if (tasks.Count <= 0)
+ {
+ return;
+ }
+
+ var taskArray = tasks.ToArray();
+ WaitForTasksToComplete(taskArray);
+
+ for (var i = 0; i < taskArray.Length; i++)
+ {
+ localFinally(tasks[i].Result);
+ }
+
+ CollectExceptions(taskArray);
+ }
+
+ ///
+ /// Executes each of the provided actions inside a discrete, asynchronous task.
+ ///
+ /// An array of actions to execute.
+ /// The argument is null.
+ /// The actions array contains a null element.
+ /// An action threw an exception.
+ public static void Run(params Action[] actions)
+ {
+ if (actions == null)
+ {
+ throw new ArgumentNullException("actions");
+ }
+
+ // fast forward execution if it's only one or none items
+ if (actions.Length <= 1)
+ {
+ if (actions.Length == 1)
+ {
+ actions[0]();
+ }
+
+ return;
+ }
+
+ // fast forward execution in case parallelization is disabled
+ if (Control.DisableParallelization
+ || ThreadQueue.ThreadCount <= 1
+ || ThreadQueue.IsInWorkerThread)
+ {
+ for (var i = 0; i < actions.Length; i++)
+ {
+ actions[i]();
+ }
+
+ return;
+ }
+
+ Invoke(actions);
+ }
+
+ ///
+ /// Executes each of the provided actions inside a discrete, asynchronous task.
+ ///
+ /// An array of actions to execute.
+ /// The actions array contains a null element.
+ /// An action threw an exception.
+ internal static void Invoke(params Action[] actions)
+ {
+ // create a job for each action
+ var tasks = new Task[actions.Length];
+ for (var i = 0; i < tasks.Length; i++)
+ {
+ Action action = actions[i];
+ if (action == null)
+ {
+ throw new ArgumentException(String.Format(Resources.ArgumentItemNull, "actions"), "actions");
+ }
+
+ tasks[i] = new Task(action);
+ }
+
+ // run the jobs
+ ThreadQueue.Enqueue(tasks);
+
+ WaitForTasksToComplete(tasks);
+
+ CollectExceptions(tasks);
+ }
+
+ ///
+ /// Waits for tasks to complete.
+ ///
+ /// The tasks.
+ private static void WaitForTasksToComplete(Task[] tasks)
+ {
+ foreach (var task in tasks)
+ {
+ task.Wait();
+ }
+ }
+
+ ///
+ /// Collects the exceptions and dispose tasks.
+ ///
+ /// The tasks.
+ private static void CollectExceptions(IEnumerable tasks)
+ {
+ // collect all thrown exceptions and dispose the jobs
+ var exceptions = new List();
+ foreach (var task in tasks)
+ {
+ if (task.IsFaulted)
+ {
+ exceptions.Add(task.Exception);
+ }
+ }
+
+ // throw the aggregated exceptions, if any
+ if (exceptions.Count > 0)
+ {
+ throw new AggregateException(exceptions);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Silverlight/Threading/Task.cs b/src/Silverlight/Threading/Task.cs
new file mode 100644
index 00000000..2f330837
--- /dev/null
+++ b/src/Silverlight/Threading/Task.cs
@@ -0,0 +1,128 @@
+//
+// 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.Threading
+{
+ using System;
+ using System.Threading;
+
+ ///
+ /// Internal Parallel Task Handle.
+ ///
+ internal class Task
+ {
+ ///
+ /// Delegate to the task's action.
+ ///
+ private readonly System.Action _body;
+
+ ///
+ /// Initializes a new instance of the Task class.
+ ///
+ /// Delegate to the task's action.
+ public Task(Action body)
+ {
+ if (body == null)
+ {
+ throw new ArgumentNullException("body");
+ }
+
+ _body = body;
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected Task()
+ {
+ }
+
+ ///
+ /// Gets a value indicating whether the task completed due to an unhandled exception.
+ ///
+ ///
+ /// true if this task completed due to an unhandled exception; otherwise, false.
+ ///
+ public bool IsFaulted
+ {
+ get { return Exception != null; }
+ }
+
+ ///
+ /// Gets a value indicating whether this task has completed.
+ ///
+ ///
+ /// true if this task has completed; otherwise, false.
+ ///
+ public bool IsCompleted
+ {
+ get;
+ private set;
+ }
+
+ ///
+ /// Gets or sets the exception thrown by the task, if any.
+ ///
+ public Exception Exception { get; set; }
+
+ ///
+ /// Run the task.
+ ///
+ public void Compute()
+ {
+ try
+ {
+ DoCompute();
+ IsCompleted = true;
+ }
+ catch (Exception e)
+ {
+ Exception = e;
+ }
+ }
+
+ ///
+ /// Runs the actual task.
+ ///
+ protected virtual void DoCompute()
+ {
+ _body();
+ }
+
+ ///
+ /// Waits for the task to complete execution.
+ ///
+ public void Wait()
+ {
+ while (!IsCompleted && !IsFaulted)
+ {
+ Thread.Sleep(0);
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Silverlight/Threading/TaskOfT.cs b/src/Silverlight/Threading/TaskOfT.cs
new file mode 100644
index 00000000..2cef39c2
--- /dev/null
+++ b/src/Silverlight/Threading/TaskOfT.cs
@@ -0,0 +1,79 @@
+//
+// 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.Threading
+{
+ using System;
+
+ ///
+ /// Internal Generic Parallel Task Handle.
+ ///
+ /// The type of the result.
+ internal class Task : Task
+ {
+ ///
+ /// Delegate to the task's action.
+ ///
+ private readonly Func