Browse Source

added LA to siliverlight

switched LA parallel to CommonParallel class
pull/36/head
Marcus Cuda 16 years ago
parent
commit
44bded2c7b
  1. 132
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  2. 113
      src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs
  3. 144
      src/Numerics/LinearAlgebra/Double/Vector.cs
  4. 52
      src/Numerics/Threading/CommonParallel.cs
  5. 24
      src/Silverlight/Silverlight.csproj

132
src/Numerics/LinearAlgebra/Double/DenseVector.cs

@ -31,12 +31,11 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks;
using NumberTheory;
using Properties;
using Threading;
/// <summary>
/// A vector using dense storage.
@ -93,15 +92,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var vector = other as DenseVector;
if (vector == null)
{
Parallel.ForEach(
Partitioner.Create(0, this.Data.Length),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
this[index] = other[index];
}
});
CommonParallel.For(
0,
this.Data.Length,
index => this[index] = other[index]);
}
else
{
@ -292,15 +286,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var otherVector = target as DenseVector;
if (otherVector == null)
{
Parallel.ForEach(
Partitioner.Create(0, this.Data.Length),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
target[index] = this.Data[index];
}
});
CommonParallel.For(
0,
this.Data.Length,
index => this[index] = this.Data[index]);
}
else
{
@ -319,15 +308,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Data.Length),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
this.Data[index] += scalar;
}
});
CommonParallel.For(
0,
this.Data.Length,
index => this.Data[index] += scalar);
}
/// <summary>
@ -480,15 +464,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Data.Length),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
this.Data[index] -= scalar;
}
});
CommonParallel.For(
0,
this.Data.Length,
index => this.Data[index] -= scalar);
}
/// <summary>
@ -637,15 +616,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override Vector Negate()
{
var result = new DenseVector(this.Count);
Parallel.ForEach(
Partitioner.Create(0, this.Data.Length),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
result[index] = -this.Data[index];
}
});
CommonParallel.For(
0,
this.Data.Length,
index => result[index] = -this.Data[index]);
return result;
}
@ -787,6 +761,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
public override double Norm()
{
var sum = 0.0;
for (var i = 0; i < this.Data.Length; i++)
{
sum = SpecialFunctions.Hypotenuse(sum, this.Data[i]);
@ -801,30 +776,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>Scalar ret = sum(abs(this[i]))</returns>
public override double Norm1()
{
var sum = 0.0;
var syncLock = new object();
Parallel.ForEach(
Partitioner.Create(0, this.Count),
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData += Math.Abs(this.Data[i]);
}
return localData;
},
localResult =>
{
lock (syncLock)
{
sum += localResult;
}
});
return sum;
return CommonParallel.Aggregate(
0,
this.Count,
index => Math.Abs(this.Data[index]));
}
/// <summary>
@ -849,28 +804,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return this.Norm();
}
var sum = 0.0;
var syncLock = new object();
Parallel.ForEach(
Partitioner.Create(0, this.Count),
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData += Math.Pow(Math.Abs(this.Data[i]), p);
}
return localData;
},
localResult =>
{
lock (syncLock)
{
sum += localResult;
}
});
var sum = CommonParallel.Aggregate(
0,
this.Count,
index => Math.Pow(Math.Abs(this.Data[index]), p));
return Math.Pow(sum, 1.0 / p);
}
@ -881,7 +818,12 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// <returns>Scalar ret = max(abs(this[i]))</returns>
public override double NormInfinity()
{
double max = 0;
return CommonParallel.Select(
0,
this.Count,
(index, localData) => localData = Math.Max(localData, Math.Abs(this.Data[index])),
Math.Max);
/*double max = 0;
var syncLock = new object();
@ -905,7 +847,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
});
return max;
return max;*/
}
#endregion

113
src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs

@ -31,9 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Properties;
using Threading;
/// <summary>
/// Defines the base class for <c>Matrix</c> classes.
@ -58,16 +57,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Parallel.ForEach(
Partitioner.Create(0, this.RowCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
i =>
{
for (var i = range.Item1; i < range.Item2; i++)
for (var j = 0; j < this.ColumnCount; j++)
{
for (var j = 0; j < this.ColumnCount; j++)
{
this.At(i, j, this.At(i, j) + other.At(i, j));
}
this.At(i, j, this.At(i, j) + other.At(i, j));
}
});
}
@ -90,16 +87,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
}
Parallel.ForEach(
Partitioner.Create(0, this.RowCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
i =>
{
for (var i = range.Item1; i < range.Item2; i++)
for (var j = 0; j < this.ColumnCount; j++)
{
for (var j = 0; j < this.ColumnCount; j++)
{
this.At(i, j, this.At(i, j) - other.At(i, j));
}
this.At(i, j, this.At(i, j) - other.At(i, j));
}
});
}
@ -115,16 +110,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.RowCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
i =>
{
for (var i = range.Item1; i < range.Item2; i++)
for (var j = 0; j < this.ColumnCount; j++)
{
for (var j = 0; j < this.ColumnCount; j++)
{
this.At(i, j, this.At(i, j) * scalar);
}
this.At(i, j, this.At(i, j) * scalar);
}
});
}
@ -210,21 +203,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
Parallel.ForEach(
Partitioner.Create(0, this.RowCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
i =>
{
for (var i = range.Item1; i < range.Item2; i++)
double s = 0;
for (var j = 0; j != this.ColumnCount; j++)
{
double s = 0;
for (var j = 0; j != this.ColumnCount; j++)
{
s += this.At(i, j) * rightSide[j];
}
result[i] = s;
s += this.At(i, j) * rightSide[j];
}
});
result[i] = s;
});
}
}
@ -281,21 +272,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
Parallel.ForEach(
Partitioner.Create(0, this.ColumnCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
j =>
{
for (var j = range.Item1; j < range.Item2; j++)
double s = 0;
for (var i = 0; i != leftSide.Count; i++)
{
double s = 0;
for (var i = 0; i != leftSide.Count; i++)
{
s += leftSide[i] * this.At(i, j);
}
result[j] = s;
s += leftSide[i] * this.At(i, j);
}
});
result[j] = s;
});
}
}
@ -338,24 +327,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
else
{
Parallel.ForEach(
Partitioner.Create(0, this.RowCount),
(range, loopState) =>
CommonParallel.For(
0,
this.RowCount,
j =>
{
for (var j = range.Item1; j < range.Item2; j++)
for (var i = 0; i != other.ColumnCount; i++)
{
for (var i = 0; i != other.ColumnCount; i++)
double s = 0;
for (var l = 0; l < this.ColumnCount; l++)
{
double s = 0;
for (var l = 0; l < this.ColumnCount; l++)
{
s += this.At(j, l) * other.At(l, i);
}
result.At(j, i, s);
s += this.At(j, l) * other.At(l, i);
}
result.At(j, i, s);
}
});
});
}
}

144
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -32,11 +32,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
{
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Properties;
using Threading;
/// <summary>
/// Defines the base class for <c>Vector</c> classes.
@ -133,15 +132,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] += scalar;
}
});
CommonParallel.For(
0,
this.Count,
index => this[index] += scalar);
}
/// <summary>
@ -217,15 +211,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] += other[i];
}
});
CommonParallel.For(
0,
this.Count,
index => this[index] += other[index]);
}
/// <summary>
@ -287,15 +276,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] -= scalar;
}
});
CommonParallel.For(
0,
this.Count,
index => this[index] -= scalar);
}
/// <summary>
@ -371,15 +355,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] -= other[i];
}
});
CommonParallel.For(
0,
this.Count,
index => this[index] -= other[index]);
}
/// <summary>
@ -441,15 +420,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] *= scalar;
}
});
CommonParallel.For(
0,
this.Count,
index => this[index] *= scalar);
}
/// <summary>
@ -810,29 +784,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("p");
}
var sum = 0.0;
var syncLock = new object();
Parallel.ForEach(
Partitioner.Create(0, this.Count),
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData += Math.Pow(Math.Abs(this[i]), p);
}
return localData;
},
localResult =>
{
lock (syncLock)
{
sum += localResult;
}
});
var sum = CommonParallel.Aggregate(
0,
this.Count,
index => Math.Pow(Math.Abs(this[index]), p));
return Math.Pow(sum, 1.0 / p);
}
@ -844,6 +800,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns>
public virtual double NormInfinity()
{
return CommonParallel.Select(
0,
this.Count,
(index, localData) => localData = Math.Max(localData, Math.Abs(this[index])),
Math.Max);
/*
var max = 0.0;
var syncLock = new object();
@ -867,7 +830,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
});
return max;
return max;*/
}
/// <summary>
@ -935,15 +898,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return;
}
Parallel.ForEach(
Partitioner.Create(0, this.Count),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
target[index] = this[index];
}
});
CommonParallel.For(
0,
this.Count,
index => target[index] = this[index]);
}
/// <summary>
@ -993,27 +951,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var tmpVector = destination.CreateVector(destination.Count);
this.CopyTo(tmpVector);
Parallel.ForEach(
Partitioner.Create(0, count),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
destination[destinationOffset + index] = tmpVector[offset + index];
}
});
CommonParallel.For(
0,
count,
index => destination[destinationOffset + index] = tmpVector[offset + index]);
}
else
{
Parallel.ForEach(
Partitioner.Create(0, count),
(range, loopState) =>
{
for (var index = range.Item1; index < range.Item2; index++)
{
destination[destinationOffset + index] = this[offset + index];
}
});
CommonParallel.For(
0,
count,
index => destination[destinationOffset + index] = this[offset + index]);
}
}

52
src/Numerics/Threading/CommonParallel.cs

@ -149,5 +149,57 @@ namespace MathNet.Numerics.Threading
{
Parallel.Invoke(actions);
}
/// <summary>
/// Selects an item (such as Max or Min).
/// </summary>
/// <param name="fromInclusive">Starting index of the loop.</param>
/// <param name="toExclusive">Ending index of the loop</param>
/// <param name="body">The function to select items over a subset.</param>
/// <param name="localFinally">The function to select the item of selection from the subsets.</param>
/// <returns>The selected value.</returns>
public static double Select(int fromInclusive, int toExclusive, Func<int, double, double> body, Func<double, double, double> localFinally)
{
double ret = 0;
var syncLock = new object();
#if SILVERLIGHT
Parallel.For(
fromInclusive,
toExclusive,
() => 0.0,
(i, localData) => localData += body(i, localData),
localResult =>
{
lock (syncLock)
{
ret = localFinally(ret, localResult);
}
});
#else
Parallel.ForEach(
Partitioner.Create(fromInclusive, toExclusive),
new ParallelOptions { MaxDegreeOfParallelism = Control.NumberOfParallelWorkerThreads },
() => 0.0,
(range, loop, localData) =>
{
for (var i = range.Item1; i < range.Item2; i++)
{
localData = body(i, localData);
}
return localData;
},
localResult =>
{
lock (syncLock)
{
ret = localFinally(ret, localResult);
}
});
#endif
return ret;
}
}
}

24
src/Silverlight/Silverlight.csproj

@ -215,6 +215,30 @@
<Compile Include="..\Numerics\IPrecisionSupport.cs">
<Link>IPrecisionSupport.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\DenseMatrix.cs">
<Link>LinearAlgebra\Double\DenseMatrix.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\DenseVector.cs">
<Link>LinearAlgebra\Double\DenseVector.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\Cholesky.cs">
<Link>LinearAlgebra\Double\Factorization\Cholesky.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\DenseCholesky.cs">
<Link>LinearAlgebra\Double\Factorization\DenseCholesky.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Factorization\ExtensionMethods.cs">
<Link>LinearAlgebra\Double\Factorization\ExtensionMethods.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.Arithmetic.cs">
<Link>LinearAlgebra\Double\Matrix.Arithmetic.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Matrix.cs">
<Link>LinearAlgebra\Double\Matrix.cs</Link>
</Compile>
<Compile Include="..\Numerics\LinearAlgebra\Double\Vector.cs">
<Link>LinearAlgebra\Double\Vector.cs</Link>
</Compile>
<Compile Include="..\Numerics\NumberTheory\IntegerTheory.cs">
<Link>NumberTheory\IntegerTheory.cs</Link>
</Compile>

Loading…
Cancel
Save