diff --git a/src/Numerics/LinearAlgebra/Generic/Common.cs b/src/Numerics/LinearAlgebra/Generic/Common.cs
index 124b1be6..544d4e38 100644
--- a/src/Numerics/LinearAlgebra/Generic/Common.cs
+++ b/src/Numerics/LinearAlgebra/Generic/Common.cs
@@ -33,17 +33,6 @@ namespace MathNet.Numerics.LinearAlgebra.Generic
///
internal static class Common
{
- ///
- /// Returns the maximum value.
- ///
- /// The first value.
- /// The second value.
- /// The maximum value.
- public static float Max(float a, float b)
- {
- return Math.Max(a, b);
- }
-
///
/// Sets the value of 1.0 for type T.
///
diff --git a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
index a8dcbba1..fbff9e9c 100644
--- a/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
+++ b/src/Numerics/LinearAlgebra/Storage/MatrixStorage.cs
@@ -89,7 +89,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
///
/// True if the specified field can be set to any value.
- /// Fall if the field is fixed, like an off-diagonal field on a diagonal matrix.
+ /// False if the field is fixed, like an off-diagonal field on a diagonal matrix.
///
public virtual bool IsMutable(int row, int column)
{
@@ -166,7 +166,7 @@ namespace MathNet.Numerics.LinearAlgebra.Storage
///
/// true if the specified is equal to the current ; otherwise, false.
///
- /// The to compare with the current . 2
+ /// The to compare with the current .
public override sealed bool Equals(object obj)
{
return Equals(obj as MatrixStorage);
diff --git a/src/Numerics/LinearAlgebra/Storage/VectorStorage.Validation.cs b/src/Numerics/LinearAlgebra/Storage/VectorStorage.Validation.cs
new file mode 100644
index 00000000..906fc729
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Storage/VectorStorage.Validation.cs
@@ -0,0 +1,55 @@
+using System;
+using MathNet.Numerics.Properties;
+
+namespace MathNet.Numerics.LinearAlgebra.Storage
+{
+ // ReSharper disable UnusedParameter.Global
+ public partial class VectorStorage
+ {
+ protected void ValidateRange(int index)
+ {
+ if (index < 0 || index >= Length)
+ {
+ throw new ArgumentOutOfRangeException("index");
+ }
+ }
+
+ protected void ValidateSubVectorRange(VectorStorage target,
+ int sourceIndex, int targetIndex, int count)
+ {
+ if (count < 1)
+ {
+ throw new ArgumentOutOfRangeException("count", Resources.ArgumentMustBePositive);
+ }
+
+ // Verify Source
+
+ if (sourceIndex >= Length || sourceIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("sourceIndex");
+ }
+
+ var sourceMax = sourceIndex + count;
+
+ if (sourceMax > Length)
+ {
+ throw new ArgumentOutOfRangeException("count");
+ }
+
+ // Verify Target
+
+ if (targetIndex >= target.Length || targetIndex < 0)
+ {
+ throw new ArgumentOutOfRangeException("targetIndex");
+ }
+
+ var targetMax = targetIndex + count;
+
+ if (targetMax > target.Length)
+ {
+ throw new ArgumentOutOfRangeException("count");
+ }
+ }
+ }
+ // ReSharper restore UnusedParameter.Global
+}
diff --git a/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs
new file mode 100644
index 00000000..72e02345
--- /dev/null
+++ b/src/Numerics/LinearAlgebra/Storage/VectorStorage.cs
@@ -0,0 +1,199 @@
+using System;
+using MathNet.Numerics.Properties;
+
+namespace MathNet.Numerics.LinearAlgebra.Storage
+{
+ public abstract partial class VectorStorage : IEquatable>
+ where T : struct, IEquatable, IFormattable
+ {
+ // [ruegg] public fields are OK here
+
+ public readonly int Length;
+
+ protected VectorStorage(int length)
+ {
+ if (length <= 0)
+ {
+ throw new ArgumentOutOfRangeException(Resources.ArgumentMustBePositive);
+ }
+
+ Length = length;
+ }
+
+ ///
+ /// Gets or sets the value at the given index, with range checking.
+ ///
+ ///
+ /// The index of the element.
+ ///
+ /// The value to get or set.
+ /// This method is ranged checked. and
+ /// to get and set values without range checking.
+ public T this[int index]
+ {
+ get
+ {
+ ValidateRange(index);
+ return At(index);
+ }
+
+ set
+ {
+ ValidateRange(index);
+ At(index, value);
+ }
+ }
+
+ ///
+ /// Retrieves the requested element without range checking.
+ ///
+ /// The index of the element.
+ /// The requested element.
+ /// Not range-checked.
+ public abstract T At(int index);
+
+ ///
+ /// Sets the element without range checking.
+ ///
+ /// The index of the element.
+ /// The value to set the element to.
+ /// WARNING: This method is not thread safe. Use "lock" with it and be sure to avoid deadlocks.
+ public abstract void At(int index, T value);
+
+ ///
+ /// True if all fields of this vector can be set to any value.
+ /// False if some fields are fixed.
+ ///
+ public virtual bool IsFullyMutable
+ {
+ get { return true; }
+ }
+
+ ///
+ /// True if the specified field can be set to any value.
+ /// False if the field is fixed.
+ ///
+ public virtual bool IsMutable(int index)
+ {
+ return true;
+ }
+
+ public virtual void Clear()
+ {
+ for (var i = 0; i < Length; i++)
+ {
+ At(i, default(T));
+ }
+ }
+
+ public virtual void Clear(int index, int count)
+ {
+ for (var i = index; i < index + count; i++)
+ {
+ At(i, default(T));
+ }
+ }
+
+ ///
+ /// Indicates whether the current object is equal to another object of the same type.
+ ///
+ ///
+ /// An object to compare with this object.
+ ///
+ ///
+ /// true if the current object is equal to the parameter; otherwise, false.
+ ///
+ public virtual bool Equals(VectorStorage other)
+ {
+ // Reject equality when the argument is null or has a different shape.
+ if (other == null)
+ {
+ return false;
+ }
+ if (Length != other.Length)
+ {
+ return false;
+ }
+
+ // Accept if the argument is the same object as this.
+ if (ReferenceEquals(this, other))
+ {
+ return true;
+ }
+
+ // If all else fails, perform element wise comparison.
+ for (var index = 0; index < Length; index++)
+ {
+ if (!At(index).Equals(other.At(index)))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ ///
+ /// Determines whether the specified is equal to the current .
+ ///
+ ///
+ /// true if the specified is equal to the current ; otherwise, false.
+ ///
+ /// The to compare with the current .
+ public override sealed bool Equals(object obj)
+ {
+ return Equals(obj as MatrixStorage);
+ }
+
+ ///
+ /// Serves as a hash function for a particular type.
+ ///
+ ///
+ /// A hash code for the current .
+ ///
+ public override int GetHashCode()
+ {
+ var hashNum = Math.Min(Length, 25);
+ int hash = 17;
+ unchecked
+ {
+ for (var i = 0; i < hashNum; i++)
+ {
+ hash = hash*31 + At(i).GetHashCode();
+ }
+ }
+ return hash;
+ }
+
+ /// Parameters assumed to be validated already.
+ public virtual void CopyTo(VectorStorage target, bool skipClearing = false)
+ {
+ for (int i = 0; i < Length; i++)
+ {
+ target.At(i, At(i));
+ }
+ }
+
+ public virtual void CopySubVectorTo(VectorStorage target,
+ int sourceIndex, int targetIndex, int count,
+ bool skipClearing = false)
+ {
+ if (target == null)
+ {
+ throw new ArgumentNullException("target");
+ }
+
+ if (ReferenceEquals(this, target))
+ {
+ throw new NotSupportedException();
+ }
+
+ ValidateSubVectorRange(target, sourceIndex, targetIndex, count);
+
+ for (int i = sourceIndex, ii = targetIndex; i < sourceIndex + count; i++, ii++)
+ {
+ target.At(ii, At(i));
+ }
+ }
+ }
+}
diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj
index da85deac..658891fc 100644
--- a/src/Numerics/Numerics.csproj
+++ b/src/Numerics/Numerics.csproj
@@ -353,6 +353,8 @@
+
+
@@ -489,4 +491,4 @@
-->
-
+
\ No newline at end of file
diff --git a/src/Portable/Portable.csproj b/src/Portable/Portable.csproj
index f24b497b..db4fecad 100644
--- a/src/Portable/Portable.csproj
+++ b/src/Portable/Portable.csproj
@@ -903,6 +903,12 @@
LinearAlgebra\Storage\SparseCompressedRowMatrixStorage.cs
+
+ LinearAlgebra\Storage\VectorStorage.cs
+
+
+ LinearAlgebra\Storage\VectorStorage.Validation.cs
+
NumberTheory\IntegerTheory.cs