diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs
index e846f644..ee6891c7 100644
--- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs
+++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs
@@ -512,11 +512,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double
///
/// The negated vector.
/// Added as an alternative to the unary negation operator.
- public virtual Vector Negate()
+ public override Vector Negate()
{
var result = new DenseVector(Count);
Parallel.For(0, Count, i => result[i] = -Data[i]);
return result;
}
+
+ ///
+ /// Multiplies a scalar to each element of the vector.
+ ///
+ /// The scalar to multiply.
+ public override void Multiply(double scalar)
+ {
+ if (scalar.AlmostEqual(1.0))
+ {
+ return;
+ }
+
+ _linearAlgebra.ScaleArray(scalar, Data);
+ }
}
}
\ No newline at end of file
diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs
index fcb2625c..e8c97ae0 100644
--- a/src/Numerics/LinearAlgebra/Double/Vector.cs
+++ b/src/Numerics/LinearAlgebra/Double/Vector.cs
@@ -324,7 +324,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
- CopyTo(result);
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
+ }
+
result.Add(scalar);
}
@@ -473,7 +477,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
}
- CopyTo(result);
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
+ }
+
result.Subtract(scalar);
}
@@ -590,7 +598,145 @@ namespace MathNet.Numerics.LinearAlgebra.Double
return ret;
}
+ ///
+ /// Multiplies a scalar to each element of the vector.
+ ///
+ /// The scalar to multiply.
+ public virtual void Multiply(double scalar)
+ {
+ if (scalar.AlmostEqual(1.0))
+ {
+ return;
+ }
+
+ Parallel.For(0, Count, i => this[i] *= scalar);
+ }
+
+ ///
+ /// Multiplies a scalar to each element of the vector and stores the result in the result vector.
+ ///
+ /// The scalar to multiply.
+ /// The vector to store the result of the multiplication.
+ /// If the result vector is .
+ /// If this vector and are not the same size.
+ public virtual void Multiply(double scalar, Vector result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (Count != result.Count)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
+ }
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
+ }
+
+ result.Multiply(scalar);
+ }
+
+ ///
+ /// Multiplies a vector with a scalar.
+ ///
+ /// The vector to scale.
+ /// The scalar value.
+ /// The result of the multiplication.
+ /// If is .
+ public static Vector operator *(Vector leftSide, double rightSide)
+ {
+ if (leftSide == null)
+ {
+ throw new ArgumentNullException("leftSide");
+ }
+
+ var ret = leftSide.Clone();
+ ret.Multiply(rightSide);
+ return ret;
+ }
+
+ ///
+ /// Multiplies a vector with a scalar.
+ ///
+ /// The scalar value.
+ /// The vector to scale.
+ /// The result of the multiplication.
+ /// If is .
+ public static Vector operator *(double leftSide, Vector rightSide)
+ {
+ if (rightSide == null)
+ {
+ throw new ArgumentNullException("rightSide");
+ }
+
+ var ret = rightSide.Clone();
+ ret.Multiply(leftSide);
+ return ret;
+ }
+
+ ///
+ /// Divides each element of the vector by a scalar.
+ ///
+ /// The scalar to divide with.
+ public virtual void Divide(double scalar)
+ {
+ if (scalar.AlmostEqual(1.0))
+ {
+ return;
+ }
+
+ Multiply(1.0 / scalar);
+ }
+
+ ///
+ /// Divides each element of the vector by a scalar and stores the result in the result vector.
+ ///
+ /// The scalar to divide with.
+ /// The vector to store the result of the division.
+ /// If the result vector is .
+ /// If this vector and are not the same size.
+ public virtual void Divide(double scalar, Vector result)
+ {
+ if (result == null)
+ {
+ throw new ArgumentNullException("result");
+ }
+
+ if (Count != result.Count)
+ {
+ throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
+ }
+
+ if (!ReferenceEquals(this, result))
+ {
+ CopyTo(result);
+ }
+
+ result.Multiply(1.0 / scalar);
+ }
+
+ ///
+ /// Divides a vector with a scalar.
+ ///
+ /// The vector to divide.
+ /// The scalar value.
+ /// The result of the division.
+ /// If is .
+ public static Vector operator /(Vector leftSide, double rightSide)
+ {
+ if (leftSide == null)
+ {
+ throw new ArgumentNullException("leftSide");
+ }
+
+ var ret = leftSide.Clone();
+ ret.Multiply(1.0 / rightSide);
+ return ret;
+ }
+
#region Implemented Interfaces
#region ICloneable
diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs
index 71dc7b02..fe719268 100644
--- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs
+++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs
@@ -571,7 +571,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
}
-
[Test]
[MultipleAsserts]
public void CanSubtractVectorFromItselfUsingResultVector()
@@ -602,6 +601,185 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
}
}
+ [Test]
+ [MultipleAsserts]
+ public void CanDivideVectorByScalar()
+ {
+ var vector = CreateVector(_data);
+ vector.Divide(2.0);
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] / 2.0, vector[i]);
+ }
+
+ vector.Divide(1.0);
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] / 2.0, vector[i]);
+ }
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void CanDivideVectorByScalarUsingResultVector()
+ {
+ var vector = CreateVector(_data);
+ var result = CreateVector(_data.Length);
+ vector.Divide(2.0, result);
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified.");
+ Assert.AreEqual(_data[i] / 2.0, result[i]);
+ }
+
+ vector.Divide(1.0, result);
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i], result[i]);
+ }
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void CanMultiplyVectorByScalar()
+ {
+ var vector = CreateVector(_data);
+ vector.Multiply(2.0);
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+
+ vector.Multiply(1.0);
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void CanMultiplyVectorByScalarUsingResultVector()
+ {
+ var vector = CreateVector(_data);
+ var result = CreateVector(_data.Length);
+ vector.Multiply(2.0, result);
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i], vector[i], "Making sure the original vector wasn't modified.");
+ Assert.AreEqual(_data[i] * 2.0, result[i]);
+ }
+
+ vector.Multiply(1.0, result);
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i], result[i]);
+ }
+ }
+
+ [Test]
+ public void ThrowsArgumentNullExceptionWhenMultiplyingScalarWithNullResultVector()
+ {
+ var vector = CreateVector(_data.Length);
+ Assert.Throws(() => vector.Multiply(1.0, null));
+ }
+
+ [Test]
+ public void ThrowsArgumentNullExceptionWhenDividingScalarWithNullResultVector()
+ {
+ var vector = CreateVector(_data.Length);
+ Assert.Throws(() => vector.Divide(1.0, null));
+ }
+
+ [Test]
+ public void ThrowsArgumentExceptionWhenMultiplyingScalarWithWrongSizeResultVector()
+ {
+ var vector = CreateVector(_data.Length);
+ var result = CreateVector(_data.Length + 1);
+ Assert.Throws(() => vector.Multiply(0.0, result));
+ }
+
+ [Test]
+ public void ThrowsArgumentExceptionWhenDividingScalarWithWrongSizeResultVector()
+ {
+ var vector = CreateVector(_data.Length);
+ var result = CreateVector(_data.Length + 1);
+ Assert.Throws(() => vector.Divide(0.0, result));
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void CanMultiplyVectorByScalarUsingOperators()
+ {
+ var vector = CreateVector(_data);
+ vector = vector * 2.0;
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+
+ vector = vector * 1.0;
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+
+ vector = CreateVector(_data);
+ vector = 2.0 * vector;
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+
+ vector = 1.0 * vector;
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] * 2.0, vector[i]);
+ }
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void CanDivideVectorByScalarUsingOperators()
+ {
+ var vector = CreateVector(_data);
+ vector = vector / 2.0;
+
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] / 2.0, vector[i]);
+ }
+
+ vector = vector / 1.0;
+ for (var i = 0; i < _data.Length; i++)
+ {
+ Assert.AreEqual(_data[i] / 2.0, vector[i]);
+ }
+ }
+
+ [Test]
+ [MultipleAsserts]
+ public void OperatorMultiplyThrowsArgumentNullExceptionWhenVectorIsNull()
+ {
+ Vector vector = null;
+ Vector result = null;
+ Assert.Throws(() => result = vector * 2.0);
+ Assert.Throws(() => result = 2.0 * vector);
+ }
+
+ [Test]
+ public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull()
+ {
+ Vector vector = null;
+ Assert.Throws(() => vector = vector / 2.0);
+ }
+
protected abstract Vector CreateVector(int size);
protected abstract Vector CreateVector(IList data);