Browse Source

added LA to siliverlight

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

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

@ -31,9 +31,8 @@
namespace MathNet.Numerics.LinearAlgebra.Double namespace MathNet.Numerics.LinearAlgebra.Double
{ {
using System; using System;
using System.Collections.Concurrent;
using System.Threading.Tasks;
using Properties; using Properties;
using Threading;
/// <summary> /// <summary>
/// Defines the base class for <c>Matrix</c> classes. /// Defines the base class for <c>Matrix</c> classes.
@ -58,16 +57,14 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions); throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.RowCount), 0,
(range, loopState) => 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); throw new ArgumentOutOfRangeException(Resources.ArgumentMatrixDimensions);
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.RowCount), 0,
(range, loopState) => 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; return;
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.RowCount), 0,
(range, loopState) => 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 else
{ {
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.RowCount), 0,
(range, loopState) => 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; s += this.At(i, j) * rightSide[j];
for (var j = 0; j != this.ColumnCount; j++)
{
s += this.At(i, j) * rightSide[j];
}
result[i] = s;
} }
});
result[i] = s;
});
} }
} }
@ -281,21 +272,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.ColumnCount), 0,
(range, loopState) => 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; s += leftSide[i] * this.At(i, j);
for (var i = 0; i != leftSide.Count; i++)
{
s += leftSide[i] * this.At(i, j);
}
result[j] = s;
} }
});
result[j] = s;
});
} }
} }
@ -338,24 +327,22 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
else else
{ {
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.RowCount), 0,
(range, loopState) => 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; s += this.At(j, l) * other.At(l, i);
for (var l = 0; l < this.ColumnCount; l++)
{
s += this.At(j, l) * other.At(l, i);
}
result.At(j, i, s);
} }
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;
using System.Collections; using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic; using System.Collections.Generic;
using System.Text; using System.Text;
using System.Threading.Tasks;
using Properties; using Properties;
using Threading;
/// <summary> /// <summary>
/// Defines the base class for <c>Vector</c> classes. /// Defines the base class for <c>Vector</c> classes.
@ -133,15 +132,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return; return;
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => this[index] += scalar);
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] += scalar;
}
});
} }
/// <summary> /// <summary>
@ -217,15 +211,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => this[index] += other[index]);
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] += other[i];
}
});
} }
/// <summary> /// <summary>
@ -287,15 +276,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return; return;
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => this[index] -= scalar);
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] -= scalar;
}
});
} }
/// <summary> /// <summary>
@ -371,15 +355,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other");
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => this[index] -= other[index]);
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] -= other[i];
}
});
} }
/// <summary> /// <summary>
@ -441,15 +420,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return; return;
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => this[index] *= scalar);
for (var i = range.Item1; i < range.Item2; i++)
{
this[i] *= scalar;
}
});
} }
/// <summary> /// <summary>
@ -810,29 +784,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentOutOfRangeException("p"); throw new ArgumentOutOfRangeException("p");
} }
var sum = 0.0; var sum = CommonParallel.Aggregate(
var syncLock = new object(); 0,
this.Count,
Parallel.ForEach( index => Math.Pow(Math.Abs(this[index]), p));
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;
}
});
return Math.Pow(sum, 1.0 / p); return Math.Pow(sum, 1.0 / p);
} }
@ -844,6 +800,13 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </returns> /// </returns>
public virtual double NormInfinity() 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 max = 0.0;
var syncLock = new object(); var syncLock = new object();
@ -867,7 +830,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
} }
}); });
return max; return max;*/
} }
/// <summary> /// <summary>
@ -935,15 +898,10 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return; return;
} }
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, this.Count), 0,
(range, loopState) => this.Count,
{ index => target[index] = this[index]);
for (var index = range.Item1; index < range.Item2; index++)
{
target[index] = this[index];
}
});
} }
/// <summary> /// <summary>
@ -993,27 +951,17 @@ namespace MathNet.Numerics.LinearAlgebra.Double
var tmpVector = destination.CreateVector(destination.Count); var tmpVector = destination.CreateVector(destination.Count);
this.CopyTo(tmpVector); this.CopyTo(tmpVector);
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, count), 0,
(range, loopState) => count,
{ index => destination[destinationOffset + index] = tmpVector[offset + index]);
for (var index = range.Item1; index < range.Item2; index++)
{
destination[destinationOffset + index] = tmpVector[offset + index];
}
});
} }
else else
{ {
Parallel.ForEach( CommonParallel.For(
Partitioner.Create(0, count), 0,
(range, loopState) => count,
{ index => destination[destinationOffset + index] = this[offset + index]);
for (var index = range.Item1; index < range.Item2; index++)
{
destination[destinationOffset + index] = this[offset + index];
}
});
} }
} }

52
src/Numerics/Threading/CommonParallel.cs

@ -149,5 +149,57 @@ namespace MathNet.Numerics.Threading
{ {
Parallel.Invoke(actions); 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"> <Compile Include="..\Numerics\IPrecisionSupport.cs">
<Link>IPrecisionSupport.cs</Link> <Link>IPrecisionSupport.cs</Link>
</Compile> </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"> <Compile Include="..\Numerics\NumberTheory\IntegerTheory.cs">
<Link>NumberTheory\IntegerTheory.cs</Link> <Link>NumberTheory\IntegerTheory.cs</Link>
</Compile> </Compile>

Loading…
Cancel
Save