diff --git a/src/Numerics/LinearAlgebra/Complex/Vector.cs b/src/Numerics/LinearAlgebra/Complex/Vector.cs index 14ba0aaa..2304f062 100644 --- a/src/Numerics/LinearAlgebra/Complex/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex/Vector.cs @@ -195,6 +195,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex return dot; } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(Complex divisor, Vector result) + { + throw new NotImplementedException(); + } + /// /// Returns the value of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Complex32/Vector.cs b/src/Numerics/LinearAlgebra/Complex32/Vector.cs index 32769f3b..48976909 100644 --- a/src/Numerics/LinearAlgebra/Complex32/Vector.cs +++ b/src/Numerics/LinearAlgebra/Complex32/Vector.cs @@ -195,6 +195,16 @@ namespace MathNet.Numerics.LinearAlgebra.Complex32 return dot; } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(Complex32 divisor, Vector result) + { + throw new NotImplementedException(); + } + /// /// Returns the value of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index a573a618..18a51154 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -591,6 +591,48 @@ namespace MathNet.Numerics.LinearAlgebra.Double return (DenseVector)leftSide.Multiply(1.0 / rightSide); } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(double divisor, Vector result) + { + var denseResult = result as DenseVector; + if (denseResult == null) + { + for (var index = 0; index < Count; index++) + { + result.At(index, Data[index] % divisor); + } + } + else + { + for (var index = 0; index < Count; index++) + { + denseResult.Data[index] = Data[index] % divisor; + } + } + } + + /// + /// Computes the modulus of each element of the vector of the given divisor. + /// + /// The vector whose elements we want to compute the modulus of. + /// The divisor to use, + /// The result of the calculation + /// If is . + public static DenseVector operator %(DenseVector leftSide, float rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + return (DenseVector)leftSide.Modulus(rightSide); + } + + /// /// Returns the index of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Double/SparseVector.cs b/src/Numerics/LinearAlgebra/Double/SparseVector.cs index 8f97c05c..a279ee23 100644 --- a/src/Numerics/LinearAlgebra/Double/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/SparseVector.cs @@ -697,6 +697,47 @@ namespace MathNet.Numerics.LinearAlgebra.Double return (SparseVector)leftSide.Multiply(1.0 / rightSide); } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(double divisor, Vector result) + { + if (ReferenceEquals(this, result)) + { + for (var index = 0; index < NonZerosCount; index++) + { + _nonZeroValues[index] %= divisor; + } + } + else + { + result.Clear(); + for (var index = 0; index < NonZerosCount; index++) + { + result.At(_nonZeroIndices[index], _nonZeroValues[index] % divisor); + } + } + } + + /// + /// Computes the modulus of each element of the vector of the given divisor. + /// + /// The vector whose elements we want to compute the modulus of. + /// The divisor to use, + /// The result of the calculation + /// If is . + public static SparseVector operator %(SparseVector leftSide, float rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + return (SparseVector)leftSide.Modulus(rightSide); + } + /// /// Returns the index of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index 8dd27dd9..f3cfd6e0 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -194,6 +194,19 @@ namespace MathNet.Numerics.LinearAlgebra.Double return dot; } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(double divisor, Vector result) + { + for (var index = 0; index < Count; index++) + { + result[index] = At(index) % divisor; + } + } + /// /// Returns the value of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Generic/Vector.cs b/src/Numerics/LinearAlgebra/Generic/Vector.cs index d3723990..717ee750 100644 --- a/src/Numerics/LinearAlgebra/Generic/Vector.cs +++ b/src/Numerics/LinearAlgebra/Generic/Vector.cs @@ -872,6 +872,45 @@ namespace MathNet.Numerics.LinearAlgebra.Generic /// The sum of the absolute value of the vector's elements. public abstract T SumMagnitudes(); + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector containing the result. + public virtual Vector Modulus(T divisor) + { + var result = CreateVector(Count); + Modulus(divisor, result); + return result; + } + + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + public virtual void Modulus(T divisor, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + DoModulus(divisor, result); + } + + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected abstract void DoModulus(T divisor, Vector result); + #endregion #region Arithmetic Operator Overloading @@ -1044,6 +1083,23 @@ namespace MathNet.Numerics.LinearAlgebra.Generic return leftSide.Divide(rightSide); } + /// + /// Computes the modulus of each element of the vector of the given divisor. + /// + /// The vector whose elements we want to compute the modulus of. + /// The divisor to use, + /// The result of the calculation + /// If is . + public static Vector operator %(Vector leftSide, T rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + return leftSide.Modulus(rightSide); + } + #endregion #region Vector Norms diff --git a/src/Numerics/LinearAlgebra/Single/DenseVector.cs b/src/Numerics/LinearAlgebra/Single/DenseVector.cs index d5ea42e2..3dc950c6 100644 --- a/src/Numerics/LinearAlgebra/Single/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/DenseVector.cs @@ -591,6 +591,47 @@ namespace MathNet.Numerics.LinearAlgebra.Single return (DenseVector)leftSide.Multiply(1f / rightSide); } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(float divisor, Vector result) + { + var denseResult = result as DenseVector; + if (denseResult == null) + { + for (var index = 0; index < Count; index++) + { + result.At(index, Data[index] % divisor); + } + } + else + { + for (var index = 0; index < Count; index++) + { + denseResult.Data[index] = Data[index] % divisor; + } + } + } + + /// + /// Computes the modulus of each element of the vector of the given divisor. + /// + /// The vector whose elements we want to compute the modulus of. + /// The divisor to use, + /// The result of the calculation + /// If is . + public static DenseVector operator %(DenseVector leftSide, float rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + return (DenseVector)leftSide.Modulus(rightSide); + } + /// /// Returns the index of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Single/SparseVector.cs b/src/Numerics/LinearAlgebra/Single/SparseVector.cs index ceefd77b..f41380a6 100644 --- a/src/Numerics/LinearAlgebra/Single/SparseVector.cs +++ b/src/Numerics/LinearAlgebra/Single/SparseVector.cs @@ -704,6 +704,47 @@ namespace MathNet.Numerics.LinearAlgebra.Single return (SparseVector)leftSide.Multiply(1.0f / rightSide); } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(float divisor, Vector result) + { + if (ReferenceEquals(this, result)) + { + for (var index = 0; index < NonZerosCount; index++) + { + _nonZeroValues[index] %= divisor; + } + } + else + { + result.Clear(); + for (var index = 0; index < NonZerosCount; index++) + { + result.At(_nonZeroIndices[index], _nonZeroValues[index] % divisor); + } + } + } + + /// + /// Computes the modulus of each element of the vector of the given divisor. + /// + /// The vector whose elements we want to compute the modulus of. + /// The divisor to use, + /// The result of the calculation + /// If is . + public static SparseVector operator %(SparseVector leftSide, float rightSide) + { + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + return (SparseVector)leftSide.Modulus(rightSide); + } + /// /// Returns the index of the absolute minimum element. /// diff --git a/src/Numerics/LinearAlgebra/Single/Vector.cs b/src/Numerics/LinearAlgebra/Single/Vector.cs index e191cb18..b94323b4 100644 --- a/src/Numerics/LinearAlgebra/Single/Vector.cs +++ b/src/Numerics/LinearAlgebra/Single/Vector.cs @@ -195,6 +195,19 @@ namespace MathNet.Numerics.LinearAlgebra.Single return dot; } + /// + /// Computes the modulus for each element of the vector for the given divisor. + /// + /// The divisor to use. + /// A vector to store the results in. + protected override void DoModulus(float divisor, Vector result) + { + for (var index = 0; index < Count; index++) + { + result.At(index, At(index) % divisor); + } + } + /// /// Returns the value of the absolute minimum element. /// diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs index c986a640..80441647 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs @@ -1073,5 +1073,62 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Vector vector2 = null; Assert.Throws(() => vector1.OuterProduct(vector2)); } + + /// + /// Can compute the modules of each element of vector. + /// + [Test] + public void CanComputeModulus() + { + var vector = CreateVector(Data); + var mod = vector.Modulus(3.2f); + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, mod[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using a result vector. + /// + public void CanComputeModulusUsingResultVector() + { + var vector = CreateVector(Data); + var mod = CreateVector(vector.Count); + vector.Modulus(3.2f, mod); + + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, mod[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using a result vector. + /// + public void CanComputeModulusUsingSameResultVector() + { + var vector = CreateVector(Data); + vector.Modulus(3.2f, vector); + + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, vector[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using the operator %. + /// + [Test] + public void CanComputeModulusUsingOperator() + { + var vector = CreateVector(Data); + var mod = vector % 4.5f; + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 4.5, mod[index], 7); + } + } } } diff --git a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Arithmetic.cs b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Arithmetic.cs index c0866184..4d02f587 100644 --- a/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Arithmetic.cs +++ b/src/UnitTests/LinearAlgebraTests/Single/VectorTests.Arithmetic.cs @@ -1073,5 +1073,62 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Single Vector vector2 = null; Assert.Throws(() => vector1.OuterProduct(vector2)); } + + /// + /// Can compute the modules of each element of vector. + /// + [Test] + public void CanComputeModulus() + { + var vector = CreateVector(Data); + var mod = vector.Modulus(3.2f); + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, mod[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using a result vector. + /// + public void CanComputeModulusUsingResultVector() + { + var vector = CreateVector(Data); + var mod = CreateVector(vector.Count); + vector.Modulus(3.2f, mod); + + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, mod[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using a result vector. + /// + public void CanComputeModulusUsingSameResultVector() + { + var vector = CreateVector(Data); + vector.Modulus(3.2f, vector); + + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 3.2, vector[index], 7); + } + } + + /// + /// Can compute the modules of each element of vector using the operator %. + /// + [Test] + public void CanComputeModulusUsingOperator() + { + var vector = CreateVector(Data); + var mod = vector % 4.5f; + for (var index = 0; index < Data.Length; index++) + { + AssertHelpers.AlmostEqual(Data[index] % 4.5, mod[index], 7); + } + } } }