Browse Source

Vector: added scaling methods

Signed-off-by: Marcus Cuda <marcus@cuda.net>
pull/2/head
Marcus Cuda 17 years ago
parent
commit
7b8b404182
  1. 16
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  2. 150
      src/Numerics/LinearAlgebra/Double/Vector.cs
  3. 180
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

16
src/Numerics/LinearAlgebra/Double/DenseVector.cs

@ -512,11 +512,25 @@ namespace MathNet.Numerics.LinearAlgebra.Double
/// </summary>
/// <returns>The negated vector.</returns>
/// <remarks>Added as an alternative to the unary negation operator.</remarks>
public virtual Vector Negate()
public override Vector Negate()
{
var result = new DenseVector(Count);
Parallel.For(0, Count, i => result[i] = -Data[i]);
return result;
}
/// <summary>
/// Multiplies a scalar to each element of the vector.
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
public override void Multiply(double scalar)
{
if (scalar.AlmostEqual(1.0))
{
return;
}
_linearAlgebra.ScaleArray(scalar, Data);
}
}
}

150
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;
}
/// <summary>
/// Multiplies a scalar to each element of the vector.
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
public virtual void Multiply(double scalar)
{
if (scalar.AlmostEqual(1.0))
{
return;
}
Parallel.For(0, Count, i => this[i] *= scalar);
}
/// <summary>
/// Multiplies a scalar to each element of the vector and stores the result in the result vector.
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
/// <param name="result">The vector to store the result of the multiplication.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
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);
}
/// <summary>
/// Multiplies a vector with a scalar.
/// </summary>
/// <param name="leftSide">The vector to scale.</param>
/// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
public static Vector operator *(Vector leftSide, double rightSide)
{
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
var ret = leftSide.Clone();
ret.Multiply(rightSide);
return ret;
}
/// <summary>
/// Multiplies a vector with a scalar.
/// </summary>
/// <param name="leftSide">The scalar value.</param>
/// <param name="rightSide">The vector to scale.</param>
/// <returns>The result of the multiplication.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator *(double leftSide, Vector rightSide)
{
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
var ret = rightSide.Clone();
ret.Multiply(leftSide);
return ret;
}
/// <summary>
/// Divides each element of the vector by a scalar.
/// </summary>
/// <param name="scalar">The scalar to divide with.</param>
public virtual void Divide(double scalar)
{
if (scalar.AlmostEqual(1.0))
{
return;
}
Multiply(1.0 / scalar);
}
/// <summary>
/// Divides each element of the vector by a scalar and stores the result in the result vector.
/// </summary>
/// <param name="scalar">The scalar to divide with.</param>
/// <param name="result">The vector to store the result of the division.</param>
/// <exception cref="ArgumentNullException">If the result vector is <see langword="null" />.</exception>
/// <exception cref="ArgumentException">If this vector and <paramref name="result"/> are not the same size.</exception>
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);
}
/// <summary>
/// Divides a vector with a scalar.
/// </summary>
/// <param name="leftSide">The vector to divide.</param>
/// <param name="rightSide">The scalar value.</param>
/// <returns>The result of the division.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> is <see langword="null" />.</exception>
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

180
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<ArgumentNullException>(() => vector.Multiply(1.0, null));
}
[Test]
public void ThrowsArgumentNullExceptionWhenDividingScalarWithNullResultVector()
{
var vector = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => vector.Divide(1.0, null));
}
[Test]
public void ThrowsArgumentExceptionWhenMultiplyingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Multiply(0.0, result));
}
[Test]
public void ThrowsArgumentExceptionWhenDividingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => 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<ArgumentNullException>(() => result = vector * 2.0);
Assert.Throws<ArgumentNullException>(() => result = 2.0 * vector);
}
[Test]
public void OperatorDivideThrowsArgumentNullExceptionWhenVectorIsNull()
{
Vector vector = null;
Assert.Throws<ArgumentNullException>(() => vector = vector / 2.0);
}
protected abstract Vector CreateVector(int size);
protected abstract Vector CreateVector(IList<double> data);

Loading…
Cancel
Save