diff --git a/src/FSharpUnitTests100602(1).vsp b/src/FSharpUnitTests100602(1).vsp new file mode 100644 index 00000000..099e8fee Binary files /dev/null and b/src/FSharpUnitTests100602(1).vsp differ diff --git a/src/FSharpUnitTests100602(2).vsp b/src/FSharpUnitTests100602(2).vsp new file mode 100644 index 00000000..c9cfadc9 Binary files /dev/null and b/src/FSharpUnitTests100602(2).vsp differ diff --git a/src/FSharpUnitTests100602.vsp b/src/FSharpUnitTests100602.vsp new file mode 100644 index 00000000..1f3920d0 Binary files /dev/null and b/src/FSharpUnitTests100602.vsp differ diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index a7a801c2..ffa7a56d 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -752,6 +752,510 @@ namespace MathNet.Numerics.LinearAlgebra.Double return ret; } + /// + /// Returns the value of the absolute minimum element. + /// + /// The value of the absolute minimum element. + public override double AbsoluteMinimum() + { + return Math.Abs(this.Data[AbsoluteMinimumIndex()]); + } + + /// + /// Returns the index of the absolute minimum element. + /// + /// The index of absolute minimum element. + public override int AbsoluteMinimumIndex() + { + int index = 0; + double min = System.Math.Abs(this.Data[index]); + for (int i = 1; i < Count; i++) + { + double test = System.Math.Abs(this.Data[i]); + if (test < min) + { + index = i; + min = test; + } + } + + return index; + } + + /// + /// Creates a vector containing specified elements. + /// + /// The first element to begin copying from. + /// The number of elements to copy. + /// A vector containing a copy of the specified elements. + /// If is not positive or + /// greater than or equal to the size of the vector. + /// If + is greater than or equal to the size of the vector. + /// + /// If is not positive. + public override Vector SubVector(int index, int length) + { + if (index < 0 || index >= Count) + { + throw new ArgumentOutOfRangeException("start"); + } + + if (length <= 0) + { + throw new ArgumentOutOfRangeException("length"); + } + + if (index + length > Count) + { + throw new ArgumentOutOfRangeException("start"); + } + + DenseVector result = new DenseVector(length); + + CommonParallel.For( + index, + index + length, + i => result.Data[i - index] = this.Data[i]); + return result; + } + + /// + /// Set the values of this vector to the given values. + /// + /// The array containing the values to use. + /// If is . + /// If is not the same size as this vector. + public override void SetValues(double[] values) + { + if (values == null) + { + throw new ArgumentNullException("values"); + } + + if (values.Length != Count) + { + throw new ArgumentException("values", Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For( + 0, + values.Length, + i => this.Data[i] = values[i]); + } + + /// + /// Returns the value of maximum element. + /// + /// The value of maximum element. + public override double Maximum() + { + return this.Data[MaximumIndex()]; + } + + /// + /// Returns the index of the absolute maximum element. + /// + /// The index of absolute maximum element. + public override int MaximumIndex() + { + int index = 0; + double max = this.Data[0]; + for (int i = 1; i < Count; i++) + { + if (max < this.Data[i]) + { + index = i; + max = this.Data[i]; + } + } + + return index; + } + + /// + /// Returns the value of the minimum element. + /// + /// The value of the minimum element. + public override double Minimum() + { + return this.Data[MinimumIndex()]; + } + + /// + /// Returns the index of the minimum element. + /// + /// The index of minimum element. + public override int MinimumIndex() + { + int index = 0; + double min = this.Data[0]; + for (int i = 1; i < Count; i++) + { + if (min > this.Data[i]) + { + index = i; + min = this.Data[i]; + } + } + + return index; + } + + /// + /// Computes the sum of the vector's elements. + /// + /// The sum of the vector's elements. + public override double Sum() + { + double result = 0; + for (int i = 0; i < Count; i++) + { + result += this.Data[i]; + } + + return result; + } + + /// + /// Computes the sum of the absolute value of the vector's elements. + /// + /// The sum of the absolute value of the vector's elements. + public override double SumMagnitudes() + { + double result = 0; + for (int i = 0; i < Count; i++) + { + result += Math.Abs(this.Data[i]); + } + + return result; + } + + /// + /// Pointwise multiplies this vector with another vector. + /// + /// The vector to pointwise multiply with this one. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise multiplication of this vector and . + public virtual DenseVector PointWiseMultiply(DenseVector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + DenseVector result = new DenseVector(Count); + PointWiseMultiply(other, result); + return result; + } + + /// + /// Pointwise multiplies this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise multiply with this one. + /// The vector to store the result of the pointwise multiplication. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseMultiply(DenseVector other, DenseVector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result.Data[index] = this.Data[index] * other.Data[index]); + } + + /// + /// Pointwise add this vector with another vector. + /// + /// The vector to pointwise add with this one. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise addition of this vector and . + public virtual DenseVector PointWiseAdd(DenseVector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + DenseVector result = new DenseVector(Count); + PointWiseAdd(other, result); + return result; + } + + /// + /// Pointwise add this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise add with this one. + /// The vector to store the result of the pointwise addition. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseAdd(DenseVector other, DenseVector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result.Data[index] = this.Data[index] + other.Data[index]); + } + + /// + /// Pointwise subtarct this vector with another vector. + /// + /// The vector to pointwise subtract from this one. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise subtraction of this vector and . + public virtual DenseVector PointWiseSubtract(DenseVector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + DenseVector result = new DenseVector(Count); + PointWiseSubtract(other, result); + return result; + } + + /// + /// Pointwise subtract this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise subtract from this one. + /// The vector to store the result of the pointwise subtraction. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseSubtract(DenseVector other, DenseVector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result.Data[index] = this.Data[index] - other.Data[index]); + } + + /// + /// Pointwise divide this vector with another vector. + /// + /// The vector to pointwise divide this one by. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise division of this vector and . + public virtual DenseVector PointWiseDivide(DenseVector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + DenseVector result = new DenseVector(Count); + PointWiseDivide(other, result); + return result; + } + + /// + /// Pointwise divide this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise divide this one by. + /// The vector to store the result of the pointwise division. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseDivide(DenseVector other, DenseVector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result.Data[index] = this.Data[index] / other.Data[index]); + } + + /// + /// Dyadic product of two vectors + /// + /// First vector + /// Second vector + /// Matrix M[i,j] = u[i]*v[j] + /// If the u vector is . + /// If the v vector is . + public static DenseMatrix DyadicProduct(DenseVector u, DenseVector v) + { + if (u == null) + { + throw new ArgumentNullException("u"); + } + + if (v == null) + { + throw new ArgumentNullException("v"); + } + + DenseMatrix matrix = new DenseMatrix(u.Count, v.Count); + CommonParallel.For( + 0, + u.Count, + i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u.Data[i] * v.Data[j]))); + return matrix; + } + + /// + /// Generates vector with random elements + /// + /// Dimensionality of vector. + /// + /// An n-dimensional vector with uniformly distributed + /// random elements in [0, 1) interval. + /// + /// If the n vector is non poisitive. + public new virtual DenseVector Random(int n) + { + // use any class which inherits the AbstractRandomNumberGenerator + return Random(n, new MathNet.Numerics.Random.SystemCryptoRandomNumberGenerator()); + } + + /// + /// Generates a vector with random elements + /// + /// Number of elements in the vector. + /// Continuous Random Distribution or Source + /// + /// A vector with n-random elements distributed according + /// to the specified random distribution. + /// + /// If the n vector is non poisitive. + public new virtual DenseVector Random(int n, MathNet.Numerics.Random.AbstractRandomNumberGenerator randomDistribution) + { + if (n < 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "n"); + } + + DenseVector v = new DenseVector(n); + CommonParallel.For( + 0, + v.Count, + index => v.Data[index] = randomDistribution.NextDouble()); + return v; + } + + /// + /// Tensor Product (Dyadic) of this and another vector. + /// + /// The vector to operate on. + /// + /// Matrix M[i,j] = this[i] * v[j]. + /// + /// + public Matrix TensorMultiply(DenseVector v) + { + return DyadicProduct(this, v); + } + #region Vector Norms /// diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs index e3b7d47b..855ab364 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.Arithmetic.cs @@ -652,26 +652,26 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException(Resources.ArgumentMatrixSameColumnDimension); } - CommonParallel.For( - 0, - this.RowCount, - i => - { - for (int j = 0; j < this.ColumnCount; j++) - { - result.At(i, j, At(i, j)); - } - }); - - CommonParallel.For( - 0, - right.RowCount, - i => - { - for (int j = 0; j < right.ColumnCount; j++) - { - result.At(i, j + ColumnCount, right.At(i, j)); - } + CommonParallel.Invoke( + () => + { + CommonParallel.For( + 0, + this.RowCount, + i => + { + CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j))); + }); + }, + () => + { + CommonParallel.For( + 0, + right.RowCount, + i => + { + CommonParallel.For(0, right.ColumnCount, j => result.At(i, j + ColumnCount, right.At(i, j))); + }); }); } @@ -727,27 +727,27 @@ namespace MathNet.Numerics.LinearAlgebra.Double { throw new ArgumentException("result", Resources.ArgumentMatrixDimensions); } - - CommonParallel.For( - 0, - this.RowCount, - i => + + CommonParallel.Invoke( + () => { - for (int j = 0; j < this.ColumnCount; j++) - { - result.At(i, j, At(i, j)); - } - }); - - CommonParallel.For( - 0, - lower.RowCount, - i => + CommonParallel.For( + 0, + this.RowCount, + i => + { + CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j))); + }); + }, + () => { - for (int j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j, lower.At(i, j)); - } + CommonParallel.For( + 0, + lower.RowCount, + i => + { + CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j, lower.At(i, j))); + }); }); } @@ -817,27 +817,36 @@ namespace MathNet.Numerics.LinearAlgebra.Double throw new ArgumentException("result", Resources.ArgumentMatrixDimensions); } - CommonParallel.For( - 0, - this.RowCount, - i => + CommonParallel.Invoke( + () => { - for (var j = 0; j < this.ColumnCount; j++) - { - result.At(i, j, At(i, j)); - } + CommonParallel.For( + 0, + this.RowCount, + i => + { + CommonParallel.For(0, this.ColumnCount, j => result.At(i, j, At(i, j))); + }); + }, + () => + { + CommonParallel.For( + 0, + lower.RowCount, + i => + { + CommonParallel.For(0, lower.ColumnCount, j => result.At(i + RowCount, j + ColumnCount, lower.At(i, j))); + }); }); + } - CommonParallel.For( - 0, - lower.RowCount, - i => - { - for (var j = 0; j < lower.ColumnCount; j++) - { - result.At(i + RowCount, j + ColumnCount, lower.At(i, j)); - } - }); + /// + /// Calculates the rank of the matrix + /// + /// effective numerical rank, obtained from SVD + public virtual int Rank() + { + throw new NotImplementedException(); } } } \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Matrix.cs b/src/Numerics/LinearAlgebra/Double/Matrix.cs index ca2f0a57..d36cd2fa 100644 --- a/src/Numerics/LinearAlgebra/Double/Matrix.cs +++ b/src/Numerics/LinearAlgebra/Double/Matrix.cs @@ -654,6 +654,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double ret.At(j, i, At(i, j)); } } + return ret; } } diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 27b67cd0..360f1e63 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -609,6 +609,270 @@ namespace MathNet.Numerics.LinearAlgebra.Double index => result[index] = this[index] * other[index]); } + /// + /// Pointwise add this vector with another vector. + /// + /// The vector to pointwise add with this one. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise addition of this vector and . + public virtual Vector PointWiseAdd(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + Vector result = CreateVector(Count); + PointWiseAdd(other, result); + return result; + } + + /// + /// Pointwise add this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise add with this one. + /// The vector to store the result of the pointwise addition. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseAdd(Vector other, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result[index] = this[index] + other[index]); + } + + /// + /// Pointwise subtarct this vector with another vector. + /// + /// The vector to pointwise subtract from this one. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise subtraction of this vector and . + public virtual Vector PointWiseSubtract(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + Vector result = CreateVector(Count); + PointWiseSubtract(other, result); + return result; + } + + /// + /// Pointwise subtract this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise subtract from this one. + /// The vector to store the result of the pointwise subtraction. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseSubtract(Vector other, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result[index] = this[index] - other[index]); + } + + /// + /// Pointwise divide this vector with another vector. + /// + /// The vector to pointwise divide this one by. + /// If the other vector is . + /// If this vector and are not the same size. + /// A new vector that is the pointwise division of this vector and . + public virtual Vector PointWiseDivide(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + Vector result = CreateVector(Count); + PointWiseDivide(other, result); + return result; + } + + /// + /// Pointwise divide this vector with another vector and stores the result into the result vector. + /// + /// The vector to pointwise divide this one by. + /// The vector to store the result of the pointwise division. + /// If the other vector is . + /// If the result vector is . + /// If this vector and are not the same size. + /// If this vector and are not the same size. + public virtual void PointWiseDivide(Vector other, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CommonParallel.For( + 0, + this.Count, + index => result[index] = this[index] / other[index]); + } + + /// + /// Dyadic product of two vectors + /// + /// First vector + /// Second vector + /// Matrix M[i,j] = u[i]*v[j] + /// If the u vector is . + /// If the v vector is . + public static DenseMatrix DyadicProduct(Vector u, Vector v) + { + if (u == null) + { + throw new ArgumentNullException("u"); + } + + if (v == null) + { + throw new ArgumentNullException("v"); + } + + DenseMatrix matrix = new DenseMatrix(u.Count, v.Count); + CommonParallel.For( + 0, + u.Count, + i => CommonParallel.For(0, v.Count, j => matrix.At(i, j, u[i] * v[j]))); + return matrix; + } + + /// + /// Generates vector with random elements + /// + /// Dimensionality of vector. + /// + /// An n-dimensional vector with uniformly distributed + /// random elements in [0, 1) interval. + /// + /// If the n vector is non poisitive. + public virtual Vector Random(int length) + { + // Just use any class which inherits the AbstractRandomNumberGenerator + return Random(length, new MathNet.Numerics.Random.SystemCryptoRandomNumberGenerator()); + } + + /// + /// Generates a vector with random elements + /// + /// Number of elements in the vector. + /// Continuous Random Distribution or Source + /// + /// A vector with n-random elements distributed according + /// to the specified random distribution. + /// + /// If the n vector is non poisitive. + public virtual Vector Random(int length, MathNet.Numerics.Random.AbstractRandomNumberGenerator randomDistribution) + { + if (length < 0) + { + throw new ArgumentException(Resources.ArgumentMustBePositive, "length"); + } + + Vector v = CreateVector(length); + CommonParallel.For( + 0, + v.Count, + index => v[index] = randomDistribution.NextDouble()); + return v; + } + + /// + /// Tensor Product (Dyadic) of this and another vector. + /// + /// The vector to operate on. + /// + /// Matrix M[i,j] = this[i] * v[j]. + /// + /// + public Matrix TensorMultiply(Vector v) + { + return DyadicProduct(this, v); + } + /// /// Returns the value of the absolute minimum element. /// @@ -635,10 +899,97 @@ namespace MathNet.Numerics.LinearAlgebra.Double min = test; } } + return index; + } + + /// + /// Returns the value of maximum element. + /// + /// The value of maximum element. + public virtual double Maximum() + { + return this[MaximumIndex()]; } + /// + /// Returns the index of the absolute maximum element. + /// + /// The index of absolute maximum element. + public virtual int MaximumIndex() + { + int index = 0; + double max = this[0]; + for (int i = 1; i < Count; i++) + { + if (max < this[i]) + { + index = i; + max = this[i]; + } + } + + return index; + } + + /// + /// Returns the value of the minimum element. + /// + /// The value of the minimum element. + public virtual double Minimum() + { + return this[MinimumIndex()]; + } + /// + /// Returns the index of the minimum element. + /// + /// The index of minimum element. + public virtual int MinimumIndex() + { + int index = 0; + double min = this[0]; + for (int i = 1; i < Count; i++) + { + if (min > this[i]) + { + index = i; + min = this[i]; + } + } + + return index; + } + + /// + /// Computes the sum of the vector's elements. + /// + /// The sum of the vector's elements. + public virtual double Sum() + { + double result = 0; + for (int i = 0; i < Count; i++) + { + result += this[i]; + } + + return result; + } + + /// + /// Computes the sum of the absolute value of the vector's elements. + /// + /// The sum of the absolute value of the vector's elements. + public virtual double SumMagnitudes() + { + double result = 0; + for (int i = 0; i < Count; i++) + { + result += Math.Abs(this[i]); + } + + return result; + } #endregion #region Arithmetic Operator Overloading @@ -1110,32 +1461,63 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// /// Creates a vector containing specified elements. /// - /// The first element to begin copying from. + /// The first element to begin copying from. /// The number of elements to copy. /// A vector containing a copy of the specified elements. - /// If is not positive or + /// If is not positive or /// greater than or equal to the size of the vector. - /// If + is greater than or equal to the size of the vector. + /// If + is greater than or equal to the size of the vector. /// /// If is not positive. - public virtual Vector SubVector(int start, int length) + public virtual Vector SubVector(int index, int length) { - if (start < 0 || start >= Count) + if (index < 0 || index >= Count) { throw new ArgumentOutOfRangeException("start"); } - if (start + length > Count) + + if (length <= 0) + { + throw new ArgumentOutOfRangeException("length"); + } + + if (index + length > Count) { throw new ArgumentOutOfRangeException("start"); } Vector result = CreateVector(length); - - CommonParallel.For(start, - start + length, index => result[index-start] = this[index]); + + CommonParallel.For( + index, + index + length, + i => result[i - index] = this[i]); return result; } + /// + /// Set the values of this vector to the given values. + /// + /// The array containing the values to use. + /// If is . + /// If is not the same size as this vector. + public virtual void SetValues(double[] values) + { + if (values == null) + { + throw new ArgumentNullException("values"); + } + + if (values.Length != Count) + { + throw new ArgumentException("values", Resources.ArgumentVectorsSameLength); + } + + CommonParallel.For( + 0, + values.Length, + i => this[i] = values[i]); + } #endregion #region Implemented Interfaces diff --git a/src/Numerics/Settings.StyleCop b/src/Numerics/Settings.StyleCop new file mode 100644 index 00000000..a27e5f5c --- /dev/null +++ b/src/Numerics/Settings.StyleCop @@ -0,0 +1,6 @@ + + + ..\Settings.StyleCop + Linked + + \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs index 5095d79b..7b5cc195 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/DenseVectorTests.cs @@ -33,6 +33,7 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double using System.Collections.Generic; using MbUnit.Framework; using LinearAlgebra.Double; + using System; public class DenseVectorTests : VectorTests { @@ -254,22 +255,400 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } [Test] - [MultipleAsserts] - public void CanCopyToNonDenseVector() + public void CanFindAbsoluteMinimumIndexInDenseVector() { - var vector = new DenseVector(_data); - var other = new UserDefinedVector(_data.Length); - vector.CopyTo(other, 1,1,2); + DenseVector source = new DenseVector(_data); + int expected = 0; + int actual = source.AbsoluteMinimumIndex(); + Assert.AreEqual(expected, actual); + } - Assert.AreEqual(vector[1], other[1]); - Assert.AreEqual(vector[2], other[2]); - vector.CopyTo(other); + [Test] + public void CanFindAbsoluteMinimumInDenseVector() + { + DenseVector source = new DenseVector(_data); + double expected = 1; + double actual = source.AbsoluteMinimum(); + Assert.AreEqual(expected, actual); - for(var i = 0; i < vector.Count; i++) + } + + [Test] + [Row(0, 5)] + [Row(2, 2)] + [Row(1, 4)] + [Row(6, 10, ExpectedException = typeof(ArgumentOutOfRangeException))] + [Row(1, 10, ExpectedException = typeof(ArgumentOutOfRangeException))] + [Row(1, -10, ExpectedException = typeof(ArgumentOutOfRangeException))] + public void CanCalculateSubVector(int index, int length) + { + DenseVector vector = new DenseVector(_data); + Vector sub = vector.SubVector(index, length); + Assert.AreEqual(length, sub.Count); + for (int i = 0; i < length; i++) { - Assert.AreEqual(vector[i], other[i]); + Assert.AreEqual(vector[i + index], sub[i]); + } + } + + [Test] + public void CanFindMaximumIndexInDenseVector() + { + DenseVector vector = new DenseVector(_data); + + int expected = 4; + int actual = vector.MaximumIndex(); + + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMaximumInDenseVector() + { + DenseVector vector = new DenseVector(_data); + double expected = 5; + double actual = vector.Maximum(); + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMinimumIndexOfDenseVector() + { + DenseVector vector = new DenseVector(_data); + int expected = 0; + int actual = vector.MinimumIndex(); + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMinimumOfDenseVector() + { + DenseVector vector = new DenseVector(_data); + double expected = 1; + double actual = vector.Minimum(); + Assert.AreEqual(expected, actual); + } + + [Test] + public void SumOfDenseVector() + { + double[] testData = { -20, -10, 10, 20, 30, }; + DenseVector vector = new DenseVector(testData); + double actual = vector.Sum(); + double expected = 30; + Assert.AreEqual(expected, actual); + } + + [Test] + public void SumMagnitudesOfDenseVector() + { + double[] testData = { -20, -10, 10, 20, 30, }; + DenseVector vector = new DenseVector(testData); + double actual = vector.SumMagnitudes(); + double expected = 90; + Assert.AreEqual(expected, actual); + } + + [Test] + [ExpectedArgumentNullException] + public new void SetValuesWithNullParameterShouldThrowException() + { + DenseVector vector = new DenseVector(_data); + vector.SetValues(null); + } + + [Test] + [ExpectedArgumentException] + public new void SetValuesWithNonEqualDataLengthShouldThrowException() + { + DenseVector vector = new DenseVector(_data.Length + 2); + vector.SetValues(_data); + } + + [Test] + public new void PointWiseMultiply() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseMultiply(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] * _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseMultiplyWithOtherNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseMultiply(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseMultiplyWithResultNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = null; + vector1.PointWiseMultiply(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public new void PointWiseMultiplyWithInvalidResultLengthShouldThrowException() + { + Vector vector1 = new DenseVector(_data); + Vector vector2 = new DenseVector(_data); + Vector result = CreateVector(vector1.Count + 1); + vector1.PointWiseMultiply(vector2, result); + } + + [Test] + public new void PointWiseMultiplyWithResult() + { + Vector vector1 = new DenseVector(_data); + Vector vector2 = new DenseVector(_data); + Vector result = vector1.PointWiseMultiply(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] * _data[i], result[i]); + } + } + + [Test] + public new void PointWiseAdd() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseAdd(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] + _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseAddWithOtherNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseAdd(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseAddWithResultNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = null; + vector1.PointWiseAdd(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public new void PointWiseAddWithInvalidResultLengthShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count + 1); + vector1.PointWiseAdd(vector2, result); + } + + [Test] + public new void PointWiseAddWithResult() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = vector1.PointWiseAdd(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] + _data[i], result[i]); + } + } + + [Test] + public new void PointWiseSubtract() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseSubtract(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] - _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseSubtractWithOtherNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseSubtractWithResultNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + Vector result = null; + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public new void PointWiseSubtractWithInvalidResultLengthShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count + 1); + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + public new void PointWiseSubtractWithResult() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = vector1.PointWiseSubtract(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] - _data[i], result[i]); + } + } + + [Test] + public new void PointWiseDivide() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseDivide(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] / _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseDivideWithOtherNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + DenseVector result = new DenseVector(vector1.Count); + vector1.PointWiseDivide(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public new void PointWiseDivideWithResultNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = null; + vector1.PointWiseDivide(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public new void PointWiseDivideWithInvalidResultLengthShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = new DenseVector(vector1.Count + 1); + vector1.PointWiseDivide(vector2, result); + } + + [Test] + public new void PointWiseDivideWithResult() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + DenseVector result = vector1.PointWiseDivide(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] / _data[i], result[i]); + } + } + + [Test] + public new void CanCalculateDyadicProduct() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + Matrix m = DenseVector.DyadicProduct(vector1, vector2); + for (int i = 0; i < vector1.Count; i++) + { + for (int j = 0; j < vector2.Count; j++) + { + Assert.AreEqual(m[i, j], vector1[i] * vector2[j]); + } + } + } + + [Test] + [ExpectedArgumentNullException] + public new void DyadicProductWithFirstParameterNullShouldThrowException() + { + DenseVector vector1 = null; + DenseVector vector2 = new DenseVector(_data); + DenseVector.DyadicProduct(vector1, vector2); + } + + [Test] + [ExpectedArgumentNullException] + public new void DyadicProductWithSecondParameterNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + Vector.DyadicProduct(vector1, vector2); + } + + [Test] + public new void CanCalculateTensorMultiply() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = new DenseVector(_data); + Matrix m = vector1.TensorMultiply(vector2); + for (int i = 0; i < vector1.Count; i++) + { + for (int j = 0; j < vector2.Count; j++) + { + Assert.AreEqual(m[i, j], vector1[i] * vector2[j]); + } } + } + + [Test] + [ExpectedArgumentNullException] + public new void TensorMultiplyWithNullParameterNullShouldThrowException() + { + DenseVector vector1 = new DenseVector(_data); + DenseVector vector2 = null; + vector1.TensorMultiply(vector2); + } + + [Test] + [ExpectedArgumentException] + public new void RandomWithNumberOfElementsLessThanZeroShouldThrowException() + { + DenseVector vector = new DenseVector(4); + vector = vector.Random(-3); } } } diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs index a9b429f7..08efb8b1 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs @@ -782,6 +782,171 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } + [Test] + public void PointWiseAdd() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count); + vector1.PointWiseAdd(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] + _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseAddWithOtherNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = null; + Vector result = CreateVector(vector1.Count); + vector1.PointWiseAdd(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseAddWithResultNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = null; + vector1.PointWiseAdd(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public void PointWiseAddWithInvalidResultLengthShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count + 1); + vector1.PointWiseAdd(vector2, result); + } + + [Test] + public void PointWiseAddWithResult() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = vector1.PointWiseAdd(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] + _data[i], result[i]); + } + } + + [Test] + public void PointWiseSubtract() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count); + vector1.PointWiseSubtract(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] - _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseSubtractWithOtherNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = null; + Vector result = CreateVector(vector1.Count); + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseSubtractWithResultNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = null; + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public void PointWiseSubtractWithInvalidResultLengthShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count + 1); + vector1.PointWiseSubtract(vector2, result); + } + + [Test] + public void PointWiseSubtractWithResult() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = vector1.PointWiseSubtract(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] - _data[i], result[i]); + } + } + + [Test] + public void PointWiseDivide() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count); + vector1.PointWiseDivide(vector2, result); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] / _data[i], result[i]); + } + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseDivideWithOtherNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = null; + Vector result = CreateVector(vector1.Count); + vector1.PointWiseDivide(vector2, result); + } + + [Test] + [ExpectedArgumentNullException] + public void PointWiseDivideWithResultNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = null; + vector1.PointWiseDivide(vector2, result); + } + + [Test] + [ExpectedArgumentException] + public void PointWiseDivideWithInvalidResultLengthShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = CreateVector(vector1.Count + 1); + vector1.PointWiseDivide(vector2, result); + } + + [Test] + public void PointWiseDivideWithResult() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Clone(); + Vector result = vector1.PointWiseDivide(vector2); + for (int i = 0; i < vector1.Count; i++) + { + Assert.AreEqual(_data[i] / _data[i], result[i]); + } + } + [Test] public void CanFindAbsoluteMinimumIndex() { @@ -801,22 +966,153 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } + [Test] + public void CanFindMaximumIndex() + { + Vector vector = CreateVector(_data); + + int expected = 4; + int actual = vector.MaximumIndex(); + + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMaximum() + { + Vector vector = CreateVector(_data); + + double expected = 5; + double actual = vector.Maximum(); + + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMinimumIndex() + { + Vector vector = CreateVector(_data); + + int expected = 0; + int actual = vector.MinimumIndex(); + + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanFindMinimum() + { + Vector vector = CreateVector(_data); + + double expected = 1; + double actual = vector.Minimum(); + + Assert.AreEqual(expected, actual); + } + [Test] [Row(0, 5)] [Row(2, 2)] [Row(1, 4)] [Row(6, 10, ExpectedException = typeof(ArgumentOutOfRangeException))] [Row(1, 10, ExpectedException = typeof(ArgumentOutOfRangeException))] - public void SubVector(int start, int length) + [Row(1, -10, ExpectedException = typeof(ArgumentOutOfRangeException))] + public void SubVector(int index, int length) { Vector vector = CreateVector(_data); - Vector sub = vector.SubVector(start, length); + Vector sub = vector.SubVector(index, length); Assert.AreEqual(length, sub.Count); for (int i = 0; i < length; i++) { - Assert.AreEqual(vector[i + start], sub[i]); + Assert.AreEqual(vector[i + index], sub[i]); } } + [Test] + public void Sum() + { + double[] testData = { -20, -10, 10, 20, 30, }; + Vector vector = CreateVector(testData); + double actual = vector.Sum(); + double expected = 30; + Assert.AreEqual(expected, actual); + } + + [Test] + public void SumMagnitudes() + { + double[] testData = { -20, -10, 10, 20, 30, }; + Vector vector = CreateVector(testData); + double actual = vector.SumMagnitudes(); + double expected = 90; + Assert.AreEqual(expected, actual); + } + + [Test] + public void CanCalculateDyadicProduct() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = CreateVector(_data); + Matrix m = Vector.DyadicProduct(vector1,vector2); + for (int i = 0; i < vector1.Count; i++) + { + for (int j = 0; j < vector2.Count; j++) + { + Assert.AreEqual(m[i, j], vector1[i] * vector2[j]); + } + } + } + + [Test] + [ExpectedArgumentNullException] + public void DyadicProductWithFirstParameterNullShouldThrowException() + { + Vector vector1 = null; + Vector vector2 = CreateVector(_data); + Vector.DyadicProduct(vector1, vector2); + } + + [Test] + [ExpectedArgumentNullException] + public void DyadicProductWithSecondParameterNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = null; + Vector.DyadicProduct(vector1, vector2); + } + + [Test] + public void CanCalculateTensorMultiply() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = CreateVector(_data); + Matrix m = vector1.TensorMultiply(vector2); + for (int i = 0; i < vector1.Count; i++) + { + for (int j = 0; j < vector2.Count; j++) + { + Assert.AreEqual(m[i, j], vector1[i] * vector2[j]); + } + } + } + + [Test] + [ExpectedArgumentNullException] + public void TensorMultiplyWithNullParameterNullShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = null; + vector1.TensorMultiply(vector2); + } + + [Test] + [ExpectedArgumentException] + public void RandomWithNumberOfElementsLessThanZeroShouldThrowException() + { + Vector vector1 = CreateVector(_data); + Vector vector2 = vector1.Random(-5); + } + + } } \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 087f61ad..d7a626bd 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -252,9 +252,35 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(vector[i], matrix[0, i]); } } + + [Test] + public void CanSetValues() + { + Vector vector = CreateVector(_data); + vector.SetValues(_data); + for (int i = 0; i < _data.Length; i++) + { + Assert.AreEqual(vector[i], _data[i]); + } + } - protected abstract Vector CreateVector(int size); + [Test] + [ExpectedArgumentNullException] + public void SetValuesWithNullParameterShouldThrowException() + { + Vector vector = CreateVector(_data); + vector.SetValues(null); + } + + [Test] + [ExpectedArgumentException] + public void SetValuesWithNonEqualDataLengthShouldThrowException() + { + Vector vector = CreateVector(_data.Length + 2); + vector.SetValues(_data); + } + protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(IList data); } } \ No newline at end of file