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