diff --git a/src/Numerics/Control.cs b/src/Numerics/Control.cs
index e8538eb1..66db2b19 100644
--- a/src/Numerics/Control.cs
+++ b/src/Numerics/Control.cs
@@ -67,6 +67,8 @@ namespace MathNet.Numerics
// Linear Algebra Provider
LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Managed.ManagedExperimentalLinearAlgebraProvider();
+
#if !PORTABLE && NATIVEMKL
try
{
@@ -77,6 +79,7 @@ namespace MathNet.Numerics
#if NATIVEMKL
case "MKL":
LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Mkl.MklExperimentalLinearAlgebraProvider();
break;
#endif
}
@@ -85,11 +88,9 @@ namespace MathNet.Numerics
{
// We don't care about any failures here at all (because "auto")
LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Managed.ManagedExperimentalLinearAlgebraProvider();
}
#endif
-
- // Experimental Linear Algebra Provider
- ExperimentalLinearAlgebraProvider = new ReferenceExperimentalLinearAlgebraProvider();
}
public static void UseSingleThread()
@@ -111,12 +112,14 @@ namespace MathNet.Numerics
public static void UseManaged()
{
LinearAlgebraProvider = new ManagedLinearAlgebraProvider();
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Managed.ManagedExperimentalLinearAlgebraProvider();
}
#if NATIVEMKL
public static void UseNativeMKL()
{
LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider();
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Mkl.MklExperimentalLinearAlgebraProvider();
}
[CLSCompliant(false)]
@@ -126,6 +129,7 @@ namespace MathNet.Numerics
Providers.LinearAlgebra.Mkl.MklAccuracy accuracy = Providers.LinearAlgebra.Mkl.MklAccuracy.High)
{
LinearAlgebraProvider = new Providers.LinearAlgebra.Mkl.MklLinearAlgebraProvider(consistency, precision, accuracy);
+ ExperimentalLinearAlgebraProvider = new Providers.ExperimentalLinearAlgebra.Mkl.MklExperimentalLinearAlgebraProvider(consistency, precision, accuracy);
}
#endif
diff --git a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs
index a2a6eb1a..4d2eb819 100644
--- a/src/Numerics/LinearAlgebra/Complex/DenseVector.cs
+++ b/src/Numerics/LinearAlgebra/Complex/DenseVector.cs
@@ -231,26 +231,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- /// The vector to add to this one.
- /// The vector to store the result of the addition.
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherDense = other as DenseVector;
- var resultDense = result as DenseVector;
-
- if (otherDense == null || resultDense == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, otherDense._values, resultDense._values);
- }
- }
-
///
/// Adds two Vectors together and returns the results.
///
diff --git a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs
index d81325c3..45626d3e 100644
--- a/src/Numerics/LinearAlgebra/Complex/SparseVector.cs
+++ b/src/Numerics/LinearAlgebra/Complex/SparseVector.cs
@@ -189,89 +189,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- ///
- /// The vector to add to this one.
- ///
- ///
- /// The vector to store the result of the addition.
- ///
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherSparse = other as SparseVector;
- if (otherSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- var resultSparse = result as SparseVector;
- if (resultSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- // TODO (ruegg, 2011-10-11): Options to optimize?
-
- var otherStorage = otherSparse._storage;
- if (ReferenceEquals(this, resultSparse))
- {
- int i = 0, j = 0;
- while (j < otherStorage.ValueCount)
- {
- if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
- {
- var otherValue = otherStorage.Values[j];
- if (!Complex.Zero.Equals(otherValue))
- {
- _storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
- }
- j++;
- }
- else if (_storage.Indices[i] == otherStorage.Indices[j])
- {
- // TODO: result can be zero, remove?
- _storage.Values[i++] += otherStorage.Values[j++];
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- result.Clear();
- int i = 0, j = 0, last = -1;
- while (i < _storage.ValueCount || j < otherStorage.ValueCount)
- {
- if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
- {
- var next = _storage.Indices[i];
- if (next != last)
- {
- last = next;
- result.At(next, _storage.Values[i] + otherSparse.At(next));
- }
- i++;
- }
- else
- {
- var next = otherStorage.Indices[j];
- if (next != last)
- {
- last = next;
- result.At(next, At(next) + otherStorage.Values[j]);
- }
- j++;
- }
- }
- }
- }
-
///
/// Subtracts a scalar from each element of the vector and stores the result in the result vector.
///
diff --git a/src/Numerics/LinearAlgebra/Complex/Vector.cs b/src/Numerics/LinearAlgebra/Complex/Vector.cs
index 6cda7da6..ca9fe7c7 100644
--- a/src/Numerics/LinearAlgebra/Complex/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Complex/Vector.cs
@@ -89,12 +89,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex
///
/// The vector to store the result of the addition.
///
- protected override void DoAdd(Vector other, Vector result)
+ protected override sealed void DoAdd(Vector other, Vector result)
{
- for (var index = 0; index < Count; index++)
- {
- result.At(index, At(index) + other.At(index));
- }
+ Control.ExperimentalLinearAlgebraProvider.AddVectors(Storage, other.Storage, result.Storage);
}
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs
index 5bba0a10..a1fa9c8c 100644
--- a/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/DenseVector.cs
@@ -226,26 +226,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- /// The vector to add to this one.
- /// The vector to store the result of the addition.
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherDense = other as DenseVector;
- var resultDense = result as DenseVector;
-
- if (otherDense == null || resultDense == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, otherDense._values, resultDense._values);
- }
- }
-
///
/// Adds two Vectors together and returns the results.
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
index 48c2f13c..89ff871e 100644
--- a/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/SparseVector.cs
@@ -184,89 +184,6 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- ///
- /// The vector to add to this one.
- ///
- ///
- /// The vector to store the result of the addition.
- ///
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherSparse = other as SparseVector;
- if (otherSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- var resultSparse = result as SparseVector;
- if (resultSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- // TODO (ruegg, 2011-10-11): Options to optimize?
-
- var otherStorage = otherSparse._storage;
- if (ReferenceEquals(this, resultSparse))
- {
- int i = 0, j = 0;
- while (j < otherStorage.ValueCount)
- {
- if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
- {
- var otherValue = otherStorage.Values[j];
- if (!Complex32.Zero.Equals(otherValue))
- {
- _storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
- }
- j++;
- }
- else if (_storage.Indices[i] == otherStorage.Indices[j])
- {
- // TODO: result can be zero, remove?
- _storage.Values[i++] += otherStorage.Values[j++];
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- result.Clear();
- int i = 0, j = 0, last = -1;
- while (i < _storage.ValueCount || j < otherStorage.ValueCount)
- {
- if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
- {
- var next = _storage.Indices[i];
- if (next != last)
- {
- last = next;
- result.At(next, _storage.Values[i] + otherSparse.At(next));
- }
- i++;
- }
- else
- {
- var next = otherStorage.Indices[j];
- if (next != last)
- {
- last = next;
- result.At(next, At(next) + otherStorage.Values[j]);
- }
- j++;
- }
- }
- }
- }
-
///
/// Subtracts a scalar from each element of the vector and stores the result in the result vector.
///
diff --git a/src/Numerics/LinearAlgebra/Complex32/Vector.cs b/src/Numerics/LinearAlgebra/Complex32/Vector.cs
index 865296d5..d302151f 100644
--- a/src/Numerics/LinearAlgebra/Complex32/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Complex32/Vector.cs
@@ -84,12 +84,9 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32
///
/// The vector to store the result of the addition.
///
- protected override void DoAdd(Vector other, Vector result)
+ protected override sealed void DoAdd(Vector other, Vector result)
{
- for (var index = 0; index < Count; index++)
- {
- result.At(index, At(index) + other.At(index));
- }
+ Control.ExperimentalLinearAlgebraProvider.AddVectors(Storage, other.Storage, result.Storage);
}
///
diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs
index 12b96828..ed5125f1 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs
@@ -226,26 +226,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- /// The vector to add to this one.
- /// The vector to store the result of the addition.
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherDense = other as DenseVector;
- var resultDense = result as DenseVector;
-
- if (otherDense == null || resultDense == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, otherDense._values, resultDense._values);
- }
- }
-
///
/// Adds two Vectors together and returns the results.
///
diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs
index 9ec18d65..5e4df7bd 100644
--- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs
+++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs
@@ -184,89 +184,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- ///
- /// The vector to add to this one.
- ///
- ///
- /// The vector to store the result of the addition.
- ///
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherSparse = other as SparseVector;
- if (otherSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- var resultSparse = result as SparseVector;
- if (resultSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- // TODO (ruegg, 2011-10-11): Options to optimize?
-
- var otherStorage = otherSparse._storage;
- if (ReferenceEquals(this, resultSparse))
- {
- int i = 0, j = 0;
- while (j < otherStorage.ValueCount)
- {
- if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
- {
- var otherValue = otherStorage.Values[j];
- if (otherValue != 0.0)
- {
- _storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
- }
- j++;
- }
- else if (_storage.Indices[i] == otherStorage.Indices[j])
- {
- // TODO: result can be zero, remove?
- _storage.Values[i++] += otherStorage.Values[j++];
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- result.Clear();
- int i = 0, j = 0, last = -1;
- while (i < _storage.ValueCount || j < otherStorage.ValueCount)
- {
- if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
- {
- var next = _storage.Indices[i];
- if (next != last)
- {
- last = next;
- result.At(next, _storage.Values[i] + otherSparse.At(next));
- }
- i++;
- }
- else
- {
- var next = otherStorage.Indices[j];
- if (next != last)
- {
- last = next;
- result.At(next, At(next) + otherStorage.Values[j]);
- }
- j++;
- }
- }
- }
- }
-
///
/// Subtracts a scalar from each element of the vector and stores the result in the result vector.
///
diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs
index 01e80270..ebfa29c9 100644
--- a/src/Numerics/LinearAlgebra/Double/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Double/Vector.cs
@@ -82,12 +82,9 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
/// The vector to store the result of the addition.
///
- protected override void DoAdd(Vector other, Vector result)
+ protected override sealed void DoAdd(Vector other, Vector result)
{
- for (var index = 0; index < Count; index++)
- {
- result.At(index, At(index) + other.At(index));
- }
+ Control.ExperimentalLinearAlgebraProvider.AddVectors(Storage, other.Storage, result.Storage);
}
///
diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs
index 4b69bd9f..d7ca99ec 100644
--- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs
+++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs
@@ -225,26 +225,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- /// The vector to add to this one.
- /// The vector to store the result of the addition.
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherDense = other as DenseVector;
- var resultDense = result as DenseVector;
-
- if (otherDense == null || resultDense == null)
- {
- base.DoAdd(other, result);
- }
- else
- {
- Control.LinearAlgebraProvider.AddArrays(_values, otherDense._values, resultDense._values);
- }
- }
-
///
/// Adds two Vectors together and returns the results.
///
diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs
index 2bc0fc85..841ca3e5 100644
--- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs
+++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs
@@ -185,89 +185,6 @@ namespace MathNet.Numerics.LinearAlgebra.Single
}
}
- ///
- /// Adds another vector to this vector and stores the result into the result vector.
- ///
- ///
- /// The vector to add to this one.
- ///
- ///
- /// The vector to store the result of the addition.
- ///
- protected override void DoAdd(Vector other, Vector result)
- {
- var otherSparse = other as SparseVector;
- if (otherSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- var resultSparse = result as SparseVector;
- if (resultSparse == null)
- {
- base.DoAdd(other, result);
- return;
- }
-
- // TODO (ruegg, 2011-10-11): Options to optimize?
-
- var otherStorage = otherSparse._storage;
- if (ReferenceEquals(this, resultSparse))
- {
- int i = 0, j = 0;
- while (j < otherStorage.ValueCount)
- {
- if (i >= _storage.ValueCount || _storage.Indices[i] > otherStorage.Indices[j])
- {
- var otherValue = otherStorage.Values[j];
- if (otherValue != 0.0f)
- {
- _storage.InsertAtIndexUnchecked(i++, otherStorage.Indices[j], otherValue);
- }
- j++;
- }
- else if (_storage.Indices[i] == otherStorage.Indices[j])
- {
- // TODO: result can be zero, remove?
- _storage.Values[i++] += otherStorage.Values[j++];
- }
- else
- {
- i++;
- }
- }
- }
- else
- {
- result.Clear();
- int i = 0, j = 0, last = -1;
- while (i < _storage.ValueCount || j < otherStorage.ValueCount)
- {
- if (j >= otherStorage.ValueCount || i < _storage.ValueCount && _storage.Indices[i] <= otherStorage.Indices[j])
- {
- var next = _storage.Indices[i];
- if (next != last)
- {
- last = next;
- result.At(next, _storage.Values[i] + otherSparse.At(next));
- }
- i++;
- }
- else
- {
- var next = otherStorage.Indices[j];
- if (next != last)
- {
- last = next;
- result.At(next, At(next) + otherStorage.Values[j]);
- }
- j++;
- }
- }
- }
- }
-
///
/// Subtracts a scalar from each element of the vector and stores the result in the result vector.
///
diff --git a/src/Numerics/LinearAlgebra/Single/Vector.cs b/src/Numerics/LinearAlgebra/Single/Vector.cs
index 0ff911fa..ec79e7c4 100644
--- a/src/Numerics/LinearAlgebra/Single/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Single/Vector.cs
@@ -82,12 +82,9 @@ namespace MathNet.Numerics.LinearAlgebra.Single
///
/// The vector to store the result of the addition.
///
- protected override void DoAdd(Vector other, Vector result)
+ protected override sealed void DoAdd(Vector other, Vector result)
{
- for (var index = 0; index < Count; index++)
- {
- result.At(index, At(index) + other.At(index));
- }
+ Control.ExperimentalLinearAlgebraProvider.AddVectors(Storage, other.Storage, result.Storage);
}
///
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index b1417100..2cc47c17 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -149,6 +149,16 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex.cs
new file mode 100644
index 00000000..7251e60e
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex.cs
@@ -0,0 +1,127 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Threading;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed
+{
+
+#if !NOSYSNUMERICS
+ using Complex = System.Numerics.Complex;
+#endif
+
+ public partial class ManagedExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ CommonParallel.For(0, y.Length, 4096, (a, b) =>
+ {
+ for (int i = a; i < b; i++)
+ {
+ result[i] = x[i] + y[i];
+ }
+ });
+ return;
+ }
+
+ var xs = x as SparseVectorStorage;
+ var ys = y as SparseVectorStorage;
+ var rs = result as SparseVectorStorage;
+ if (xs != null && ys != null && rs != null)
+ {
+
+ // NOTE: this algorithm could be improved, just here for demonstration with same behavior as before
+
+ if (ReferenceEquals(xs, rs))
+ {
+ int i = 0, j = 0;
+ while (j < ys.ValueCount)
+ {
+ if (i >= xs.ValueCount || xs.Indices[i] > ys.Indices[j])
+ {
+ var yValues = ys.Values[j];
+ if (!Complex.Zero.Equals(yValues))
+ {
+ xs.InsertAtIndexUnchecked(i++, ys.Indices[j], yValues);
+ }
+ j++;
+ }
+ else if (xs.Indices[i] == ys.Indices[j])
+ {
+ // TODO: result can be zero, remove?
+ xs.Values[i++] += ys.Values[j++];
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+ else
+ {
+ rs.Clear();
+ int i = 0, j = 0, last = -1;
+ while (i < xs.ValueCount || j < ys.ValueCount)
+ {
+ if (j >= ys.ValueCount || i < xs.ValueCount && xs.Indices[i] <= ys.Indices[j])
+ {
+ var next = xs.Indices[i];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.Values[i] + ys.At(next));
+ }
+ i++;
+ }
+ else
+ {
+ var next = ys.Indices[j];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.At(next) + ys.Values[j]);
+ }
+ j++;
+ }
+ }
+ }
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex32.cs
new file mode 100644
index 00000000..bdbf7734
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Complex32.cs
@@ -0,0 +1,122 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Threading;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed
+{
+ public partial class ManagedExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ CommonParallel.For(0, y.Length, 4096, (a, b) =>
+ {
+ for (int i = a; i < b; i++)
+ {
+ result[i] = x[i] + y[i];
+ }
+ });
+ return;
+ }
+
+ var xs = x as SparseVectorStorage;
+ var ys = y as SparseVectorStorage;
+ var rs = result as SparseVectorStorage;
+ if (xs != null && ys != null && rs != null)
+ {
+
+ // NOTE: this algorithm could be improved, just here for demonstration with same behavior as before
+
+ if (ReferenceEquals(xs, rs))
+ {
+ int i = 0, j = 0;
+ while (j < ys.ValueCount)
+ {
+ if (i >= xs.ValueCount || xs.Indices[i] > ys.Indices[j])
+ {
+ var yValues = ys.Values[j];
+ if (!Complex32.Zero.Equals(yValues))
+ {
+ xs.InsertAtIndexUnchecked(i++, ys.Indices[j], yValues);
+ }
+ j++;
+ }
+ else if (xs.Indices[i] == ys.Indices[j])
+ {
+ // TODO: result can be zero, remove?
+ xs.Values[i++] += ys.Values[j++];
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+ else
+ {
+ rs.Clear();
+ int i = 0, j = 0, last = -1;
+ while (i < xs.ValueCount || j < ys.ValueCount)
+ {
+ if (j >= ys.ValueCount || i < xs.ValueCount && xs.Indices[i] <= ys.Indices[j])
+ {
+ var next = xs.Indices[i];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.Values[i] + ys.At(next));
+ }
+ i++;
+ }
+ else
+ {
+ var next = ys.Indices[j];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.At(next) + ys.Values[j]);
+ }
+ j++;
+ }
+ }
+ }
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Double.cs
new file mode 100644
index 00000000..cf8edcbf
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Double.cs
@@ -0,0 +1,122 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Threading;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed
+{
+ public partial class ManagedExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ CommonParallel.For(0, y.Length, 4096, (a, b) =>
+ {
+ for (int i = a; i < b; i++)
+ {
+ result[i] = x[i] + y[i];
+ }
+ });
+ return;
+ }
+
+ var xs = x as SparseVectorStorage;
+ var ys = y as SparseVectorStorage;
+ var rs = result as SparseVectorStorage;
+ if (xs != null && ys != null && rs != null)
+ {
+
+ // NOTE: this algorithm could be improved, just here for demonstration with same behavior as before
+
+ if (ReferenceEquals(xs, rs))
+ {
+ int i = 0, j = 0;
+ while (j < ys.ValueCount)
+ {
+ if (i >= xs.ValueCount || xs.Indices[i] > ys.Indices[j])
+ {
+ var yValues = ys.Values[j];
+ if (yValues != 0.0)
+ {
+ xs.InsertAtIndexUnchecked(i++, ys.Indices[j], yValues);
+ }
+ j++;
+ }
+ else if (xs.Indices[i] == ys.Indices[j])
+ {
+ // TODO: result can be zero, remove?
+ xs.Values[i++] += ys.Values[j++];
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+ else
+ {
+ rs.Clear();
+ int i = 0, j = 0, last = -1;
+ while (i < xs.ValueCount || j < ys.ValueCount)
+ {
+ if (j >= ys.ValueCount || i < xs.ValueCount && xs.Indices[i] <= ys.Indices[j])
+ {
+ var next = xs.Indices[i];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.Values[i] + ys.At(next));
+ }
+ i++;
+ }
+ else
+ {
+ var next = ys.Indices[j];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.At(next) + ys.Values[j]);
+ }
+ j++;
+ }
+ }
+ }
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Single.cs
new file mode 100644
index 00000000..e36b266d
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.Single.cs
@@ -0,0 +1,122 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Threading;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed
+{
+ public partial class ManagedExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ CommonParallel.For(0, y.Length, 4096, (a, b) =>
+ {
+ for (int i = a; i < b; i++)
+ {
+ result[i] = x[i] + y[i];
+ }
+ });
+ return;
+ }
+
+ var xs = x as SparseVectorStorage;
+ var ys = y as SparseVectorStorage;
+ var rs = result as SparseVectorStorage;
+ if (xs != null && ys != null && rs != null)
+ {
+
+ // NOTE: this algorithm could be improved, just here for demonstration with same behavior as before
+
+ if (ReferenceEquals(xs, rs))
+ {
+ int i = 0, j = 0;
+ while (j < ys.ValueCount)
+ {
+ if (i >= xs.ValueCount || xs.Indices[i] > ys.Indices[j])
+ {
+ var yValues = ys.Values[j];
+ if (yValues != 0.0f)
+ {
+ xs.InsertAtIndexUnchecked(i++, ys.Indices[j], yValues);
+ }
+ j++;
+ }
+ else if (xs.Indices[i] == ys.Indices[j])
+ {
+ // TODO: result can be zero, remove?
+ xs.Values[i++] += ys.Values[j++];
+ }
+ else
+ {
+ i++;
+ }
+ }
+ }
+ else
+ {
+ rs.Clear();
+ int i = 0, j = 0, last = -1;
+ while (i < xs.ValueCount || j < ys.ValueCount)
+ {
+ if (j >= ys.ValueCount || i < xs.ValueCount && xs.Indices[i] <= ys.Indices[j])
+ {
+ var next = xs.Indices[i];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.Values[i] + ys.At(next));
+ }
+ i++;
+ }
+ else
+ {
+ var next = ys.Indices[j];
+ if (next != last)
+ {
+ last = next;
+ rs.At(next, xs.At(next) + ys.Values[j]);
+ }
+ j++;
+ }
+ }
+ }
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.cs
new file mode 100644
index 00000000..ab7ee2fd
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Managed/ManagedExperimentalLinearAlgebraProvider.cs
@@ -0,0 +1,51 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed
+{
+ [Obsolete("Experimental with breaking changes expected between minor version. Do not use until properly released.")]
+ public partial class ManagedExperimentalLinearAlgebraProvider : ReferenceExperimentalLinearAlgebraProvider
+ {
+ ///
+ /// Initialize and verify that the provided is indeed available. If not, fall back to alternatives like the managed provider
+ ///
+ public override void InitializeVerify()
+ {
+ base.InitializeVerify();
+ }
+
+ public override string ToString()
+ {
+ return "Managed";
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex.cs
new file mode 100644
index 00000000..1c14c2cc
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex.cs
@@ -0,0 +1,69 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Properties;
+using MathNet.Numerics.Providers.LinearAlgebra.Mkl;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Mkl
+{
+
+#if !NOSYSNUMERICS
+ using Complex = System.Numerics.Complex;
+#endif
+
+ public partial class MklExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ if (xd.Length != yd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (xd.Length != rd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.z_vector_add(xd.Length, xd.Data, yd.Data, rd.Data);
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex32.cs
new file mode 100644
index 00000000..57c58533
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Complex32.cs
@@ -0,0 +1,64 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Properties;
+using MathNet.Numerics.Providers.LinearAlgebra.Mkl;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Mkl
+{
+ public partial class MklExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ if (xd.Length != yd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (xd.Length != rd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.c_vector_add(xd.Length, xd.Data, yd.Data, rd.Data);
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Double.cs
new file mode 100644
index 00000000..e758c455
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Double.cs
@@ -0,0 +1,64 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Properties;
+using MathNet.Numerics.Providers.LinearAlgebra.Mkl;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Mkl
+{
+ public partial class MklExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ if (xd.Length != yd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (xd.Length != rd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.d_vector_add(xd.Length, xd.Data, yd.Data, rd.Data);
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Single.cs
new file mode 100644
index 00000000..928dc891
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.Single.cs
@@ -0,0 +1,64 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+using MathNet.Numerics.LinearAlgebra.Storage;
+using MathNet.Numerics.Properties;
+using MathNet.Numerics.Providers.LinearAlgebra.Mkl;
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Mkl
+{
+ public partial class MklExperimentalLinearAlgebraProvider
+ {
+ public override void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ {
+ var xd = x as DenseVectorStorage;
+ var yd = y as DenseVectorStorage;
+ var rd = result as DenseVectorStorage;
+ if (xd != null && yd != null && rd != null)
+ {
+ if (xd.Length != yd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ if (xd.Length != rd.Length)
+ {
+ throw new ArgumentException(Resources.ArgumentArraysSameLength);
+ }
+
+ SafeNativeMethods.s_vector_add(xd.Length, xd.Data, yd.Data, rd.Data);
+ return;
+ }
+
+ base.AddVectors(x, y, result);
+ }
+ }
+}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.cs
new file mode 100644
index 00000000..269b8e52
--- /dev/null
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/Mkl/MklExperimentalLinearAlgebraProvider.cs
@@ -0,0 +1,144 @@
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+using System;
+using MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Managed;
+using MathNet.Numerics.Providers.LinearAlgebra.Mkl;
+
+#if NATIVEMKL
+
+namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra.Mkl
+{
+ // TODO: Consider composition instead of inheritance
+
+ ///
+ /// Intel's Math Kernel Library (MKL) linear algebra provider.
+ ///
+ public partial class MklExperimentalLinearAlgebraProvider : ManagedExperimentalLinearAlgebraProvider
+ {
+ int _nativeRevision;
+ bool _nativeIX86;
+ bool _nativeX64;
+ bool _nativeIA64;
+
+ readonly MklConsistency _consistency;
+ readonly MklPrecision _precision;
+ readonly MklAccuracy _accuracy;
+
+ ///
+ /// Sets the desired bit consistency on repeated identical computations on varying CPU architectures,
+ /// as a trade-off with performance.
+ ///
+ /// VML optimal precision and rounding.
+ /// VML accuracy mode.
+ [CLSCompliant(false)]
+ public MklExperimentalLinearAlgebraProvider(
+ MklConsistency consistency = MklConsistency.Auto,
+ MklPrecision precision = MklPrecision.Double,
+ MklAccuracy accuracy = MklAccuracy.High)
+ {
+ _consistency = consistency;
+ _precision = precision;
+ _accuracy = accuracy;
+ }
+
+ public MklExperimentalLinearAlgebraProvider()
+ {
+ _consistency = MklConsistency.Auto;
+ _precision = MklPrecision.Double;
+ _accuracy = MklAccuracy.High;
+ }
+
+ ///
+ /// Initialize and verify that the provided is indeed available.
+ /// If calling this method fails, consider to fall back to alternatives like the managed provider.
+ ///
+ public override void InitializeVerify()
+ {
+ // TODO: Choose x86 or x64 based on Environment.Is64BitProcess
+
+ int a, b, linearAlgebra;
+ try
+ {
+ a = SafeNativeMethods.query_capability(0);
+ b = SafeNativeMethods.query_capability(1);
+
+ _nativeIX86 = SafeNativeMethods.query_capability(8) > 0;
+ _nativeX64 = SafeNativeMethods.query_capability(9) > 0;
+ _nativeIA64 = SafeNativeMethods.query_capability(10) > 0;
+
+ _nativeRevision = SafeNativeMethods.query_capability(64);
+ linearAlgebra = SafeNativeMethods.query_capability(128);
+ }
+ catch (DllNotFoundException e)
+ {
+ throw new NotSupportedException("MKL Native Provider not found.", e);
+ }
+ catch (BadImageFormatException e)
+ {
+ throw new NotSupportedException("MKL Native Provider found but failed to load. Please verify that the platform matches (x64 vs x32, Windows vs Linux).", e);
+ }
+ catch (EntryPointNotFoundException e)
+ {
+ // we currently accept this to continue to support the old version for a while.
+ // however, this is planned to be dropped for the final v3 release at latest.
+ // TODO: drop return statement and instead fail with the exception below
+ return;
+
+ throw new NotSupportedException("MKL Native Provider found but does not support capability querying and is therefore not compatible. Try to upgrade to a newer version.", e);
+ }
+
+ if (a != 0 || b != -1 || linearAlgebra <=0 || _nativeRevision < 4)
+ {
+ throw new NotSupportedException("MKL Native Provider found but too old or not compatible.");
+ }
+
+ // set numerical consistency, precision and accuracy modes, if supported
+ if (SafeNativeMethods.query_capability(65) > 0)
+ {
+ SafeNativeMethods.set_consistency_mode((int)_consistency);
+ SafeNativeMethods.set_vml_mode((uint)_precision | (uint)_accuracy);
+ }
+
+ // set threading settings, if supported
+ if (SafeNativeMethods.query_capability(66) > 0)
+ {
+ SafeNativeMethods.set_max_threads(Control.MaxDegreeOfParallelism);
+ }
+ }
+
+ public override string ToString()
+ {
+ return string.Format("Intel MKL ({1}; revision {0})", _nativeRevision, _nativeIX86 ? "x86" : _nativeX64 ? "x64" : _nativeIA64 ? "IA64" : "unknown");
+ }
+ }
+}
+
+#endif
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex.cs
index 344798a5..099d127d 100644
--- a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex.cs
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex.cs
@@ -40,7 +40,7 @@ namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra
public partial class ReferenceExperimentalLinearAlgebraProvider
{
- public void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ public virtual void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
{
x.Map2To(result, y, (u, v) => u+v, Zeros.AllowSkip, ExistingData.Clear);
}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex32.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex32.cs
index 109b16db..a8f758b6 100644
--- a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex32.cs
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Complex32.cs
@@ -35,7 +35,7 @@ namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra
{
public partial class ReferenceExperimentalLinearAlgebraProvider
{
- public void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ public virtual void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
{
x.Map2To(result, y, (u, v) => u+v, Zeros.AllowSkip, ExistingData.Clear);
}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Double.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Double.cs
index ab8ab1b2..546368db 100644
--- a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Double.cs
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Double.cs
@@ -35,7 +35,7 @@ namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra
{
public partial class ReferenceExperimentalLinearAlgebraProvider
{
- public void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ public virtual void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
{
x.Map2To(result, y, (u,v) => u+v, Zeros.AllowSkip, ExistingData.Clear);
}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Single.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Single.cs
index 2ddbf2b5..dcecb4f0 100644
--- a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Single.cs
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.Single.cs
@@ -35,7 +35,7 @@ namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra
{
public partial class ReferenceExperimentalLinearAlgebraProvider
{
- public void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
+ public virtual void AddVectors(VectorStorage x, VectorStorage y, VectorStorage result)
{
x.Map2To(result, y, (u, v) => u+v, Zeros.AllowSkip, ExistingData.Clear);
}
diff --git a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.cs b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.cs
index 3a0f6f67..8db9fdb9 100644
--- a/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.cs
+++ b/src/Numerics/Providers/ExperimentalLinearAlgebra/ReferenceExperimentalLinearAlgebraProvider.cs
@@ -1,4 +1,35 @@
-using System;
+//
+// Math.NET Numerics, part of the Math.NET Project
+// http://numerics.mathdotnet.com
+// http://github.com/mathnet/mathnet-numerics
+// http://mathnetnumerics.codeplex.com
+//
+// Copyright (c) 2009-2014 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.
+//
+
+
+using System;
namespace MathNet.Numerics.Providers.ExperimentalLinearAlgebra
{