Browse Source

Vector: added norm methods and broke up unit tests

Signed-off-by: Marcus Cuda <marcus@cuda.net>
pull/2/head
Marcus Cuda 17 years ago
parent
commit
ce54b3eba4
  1. 80
      src/Numerics/LinearAlgebra/Double/DenseVector.cs
  2. 548
      src/Numerics/LinearAlgebra/Double/Vector.cs
  3. 634
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs
  4. 59
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs
  5. 625
      src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs
  6. 2
      src/UnitTests/UnitTests.csproj

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

@ -543,5 +543,85 @@ namespace MathNet.Numerics.LinearAlgebra.Double
_linearAlgebra.ScaleArray(scalar, Data);
}
#region Vector Norms
/// <summary>
/// Euclidean Norm also known as 2-Norm.
/// </summary>
/// <returns>Scalar ret = sqrt(sum(this[i]^2))</returns>
public override double Norm()
{
var sum = 0.0;
for (var i = 0; i < Data.Length; i++)
{
sum = SpecialFunctions.Hypotenuse(sum, Data[i]);
}
return sum;
}
/// <summary>
/// 1-Norm also known as Manhattan Norm or Taxicab Norm.
/// </summary>
/// <returns>Scalar ret = sum(abs(this[i]))</returns>
public override double Norm1()
{
double sum = 0;
for (var i = 0; i < Data.Length; i++)
{
sum += Math.Abs(Data[i]);
}
return sum;
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar ret = (sum(abs(this[i])^p))^(1/p)</returns>
public override double NormP(int p)
{
if (1 > p)
{
throw new ArgumentOutOfRangeException("p");
}
if (1 == p)
{
return Norm1();
}
if (2 == p)
{
return Norm();
}
var sum = 0.0;
for (var i = 0; i < Data.Length; i++)
{
sum += Math.Pow(Math.Abs(Data[i]), p);
}
return Math.Pow(sum, 1.0 / p);
}
/// <summary>
/// Infinity Norm.
/// </summary>
/// <returns>Scalar ret = max(abs(this[i]))</returns>
public override double NormInfinity()
{
double max = 0;
for (int i = 0; i < Data.Length; i++)
{
max = Math.Max(max, Math.Abs(Data[i]));
}
return max;
}
#endregion
}
}

548
src/Numerics/LinearAlgebra/Double/Vector.cs

@ -80,111 +80,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
set;
}
/// <summary>
/// Returns a deep-copy clone of the vector.
/// </summary>
/// <returns>
/// A deep-copy clone of the vector.
/// </returns>
public Vector Clone()
{
var retrunVector = CreateVector(Count);
CopyTo(retrunVector);
return retrunVector;
}
/// <summary>
/// Copies the values of this vector into the target vector.
/// </summary>
/// <param name="target">
/// The vector to copy elements into.
/// </param>
/// <exception cref="ArgumentNullException">
/// If <paramref name="target"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector.
/// </exception>
public virtual void CopyTo(Vector target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (Count != target.Count)
{
throw new ArgumentException("target", Resources.ArgumentVectorsSameLength);
}
if (ReferenceEquals(this, target))
{
return;
}
for (var index = 0; index < Count; index++)
{
target[index] = this[index];
}
}
/// <summary>
/// Copies the requested elements from this vector to another.
/// </summary>
/// <param name="destination">
/// The vector to copy the elements to.
/// </param>
/// <param name="offset">
/// The element to start copying from.
/// </param>
/// <param name="destinationOffset">
/// The element to start copying to.
/// </param>
/// <param name="count">
/// The number of elements to copy.
/// </param>
public virtual void CopyTo(Vector destination, int offset, int destinationOffset, int count)
{
if (destination == null)
{
throw new ArgumentNullException("destination");
}
if (offset >= Count)
{
throw new ArgumentOutOfRangeException("offset");
}
if (offset + count > Count)
{
throw new ArgumentOutOfRangeException("count");
}
if (destinationOffset >= destination.Count)
{
throw new ArgumentOutOfRangeException("destinationOffset");
}
if (destinationOffset + count > destination.Count)
{
throw new ArgumentOutOfRangeException("count");
}
if (ReferenceEquals(this, destination))
{
var tmpVector = destination.CreateVector(destination.Count);
CopyTo(tmpVector, offset, destinationOffset, count);
tmpVector.CopyTo(destination);
}
else
{
for (var index = 0; index < count; index++)
{
destination[destinationOffset + index] = this[offset + index];
}
}
}
/// <summary>
/// Creates a matrix with the given dimensions using the same storage type
/// as this vector.
@ -280,17 +175,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString()
{
return ToString(null, null);
}
#region Elementary operations
/// <summary>
/// Adds a scalar to each element of the vector.
/// </summary>
@ -397,53 +282,6 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
}
/// <summary>
/// Returns a <strong>Vector</strong> containing the same values of rightSide.
/// </summary>
/// <remarks>This method is included for completeness.</remarks>
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(Vector rightSide)
{
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
return rightSide.Plus();
}
/// <summary>
/// Adds two <strong>Vectors</strong> together and returns the results.
/// </summary>
/// <param name="leftSide">One of the vectors to add.</param>
/// <param name="rightSide">The other vector to add.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator +(Vector leftSide, Vector rightSide)
{
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
if (leftSide == null)
{
throw new ArgumentNullException("leftSide");
}
if (leftSide.Count != rightSide.Count)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide");
}
var ret = leftSide.Clone();
ret.Add(rightSide);
return ret;
}
/// <summary>
/// Subtracts a scalar from each element of the vector.
/// </summary>
@ -553,30 +391,115 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Returns a <strong>Vector</strong> containing the negated values of rightSide.
/// 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>
/// 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);
}
#endregion
#region Arithmetic Operator Overloading
/// <summary>
/// Returns a <strong>Vector</strong> containing the same values of rightSide.
/// </summary>
/// <remarks>This method is included for completeness.</remarks>
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <returns>A vector containing the same values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector rightSide)
public static Vector operator +(Vector rightSide)
{
if (rightSide == null)
{
throw new ArgumentNullException("rightSide");
}
return rightSide.Negate();
return rightSide.Plus();
}
/// <summary>
/// Subtracts two <strong>Vectors</strong> and returns the results.
/// Adds two <strong>Vectors</strong> together and returns the results.
/// </summary>
/// <param name="leftSide">The vector to subtract from.</param>
/// <param name="rightSide">The vector to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <param name="leftSide">One of the vectors to add.</param>
/// <param name="rightSide">The other vector to add.</param>
/// <returns>The result of the addition.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector leftSide, Vector rightSide)
public static Vector operator +(Vector leftSide, Vector rightSide)
{
if (rightSide == null)
{
@ -594,49 +517,54 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
var ret = leftSide.Clone();
ret.Subtract(rightSide);
ret.Add(rightSide);
return ret;
}
/// <summary>
/// Multiplies a scalar to each element of the vector.
/// Returns a <strong>Vector</strong> containing the negated values of rightSide.
/// </summary>
/// <param name="scalar">The scalar to multiply.</param>
public virtual void Multiply(double scalar)
/// <param name="rightSide">The vector to get the values from.</param>
/// <returns>A vector containing the negated values as <paramref name="rightSide"/>.</returns>
/// <exception cref="ArgumentNullException">If <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector rightSide)
{
if (scalar.AlmostEqual(1.0))
if (rightSide == null)
{
return;
throw new ArgumentNullException("rightSide");
}
Parallel.For(0, Count, i => this[i] *= scalar);
return rightSide.Negate();
}
/// <summary>
/// Multiplies a scalar to each element of the vector and stores the result in the result vector.
/// Subtracts two <strong>Vectors</strong> and returns the results.
/// </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)
/// <param name="leftSide">The vector to subtract from.</param>
/// <param name="rightSide">The vector to subtract.</param>
/// <returns>The result of the subtraction.</returns>
/// <exception cref="ArgumentException">If <paramref name="leftSide"/> and <paramref name="rightSide"/> are not the same size.</exception>
/// <exception cref="ArgumentNullException">If <paramref name="leftSide"/> or <paramref name="rightSide"/> is <see langword="null" />.</exception>
public static Vector operator -(Vector leftSide, Vector rightSide)
{
if (result == null)
if (rightSide == null)
{
throw new ArgumentNullException("result");
throw new ArgumentNullException("rightSide");
}
if (Count != result.Count)
if (leftSide == null)
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
throw new ArgumentNullException("leftSide");
}
if (!ReferenceEquals(this, result))
if (leftSide.Count != rightSide.Count)
{
CopyTo(result);
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "rightSide");
}
result.Multiply(scalar);
var ret = leftSide.Clone();
ret.Subtract(rightSide);
return ret;
}
/// <summary>
@ -678,65 +606,239 @@ namespace MathNet.Numerics.LinearAlgebra.Double
}
/// <summary>
/// Divides each element of the vector by a scalar.
/// Divides a vector with a scalar.
/// </summary>
/// <param name="scalar">The scalar to divide with.</param>
public virtual void Divide(double scalar)
/// <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 (scalar.AlmostEqual(1.0))
if (leftSide == null)
{
return;
throw new ArgumentNullException("leftSide");
}
Multiply(1.0 / scalar);
var ret = leftSide.Clone();
ret.Multiply(1.0 / rightSide);
return ret;
}
#endregion
#region Vector Norms
/// <summary>
/// Euclidean Norm also known as 2-Norm.
/// </summary>
/// <returns>
/// Scalar ret = sqrt(sum(this[i]^2))
/// </returns>
public virtual double Norm()
{
return NormP(2);
}
/// <summary>
/// Divides each element of the vector by a scalar and stores the result in the result vector.
/// Squared Euclidean 2-Norm.
/// </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)
/// <returns>
/// Scalar ret = sum(this[i]^2)
/// </returns>
public virtual double SquaredNorm()
{
if (result == null)
var norm = Norm();
return norm * norm;
}
/// <summary>
/// 1-Norm also known as Manhattan Norm or Taxicab Norm.
/// </summary>
/// <returns>
/// Scalar ret = sum(abs(this[i]))
/// </returns>
public virtual double Norm1()
{
return NormP(1);
}
/// <summary>
/// Computes the p-Norm.
/// </summary>
/// <param name="p">The p value.</param>
/// <returns>Scalar ret = (sum(abs(this[i])^p))^(1/p)</returns>
public virtual double NormP(int p)
{
if (1 > p)
{
throw new ArgumentNullException("result");
throw new ArgumentOutOfRangeException("p");
}
if (Count != result.Count)
var sum = 0.0;
foreach (var pair in GetIndexedEnumerator())
{
throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result");
sum += Math.Pow(Math.Abs(pair.Value), p);
}
if (!ReferenceEquals(this, result))
return Math.Pow(sum, 1.0 / p);
}
/// <summary>
/// Infinity Norm.
/// </summary>
/// <returns>
/// Scalar ret = max(abs(this[i]))
/// </returns>
public virtual double NormInfinity()
{
var max = 0.0;
foreach (var pair in GetIndexedEnumerator())
{
CopyTo(result);
max = Math.Max(max, Math.Abs(pair.Value));
}
result.Multiply(1.0 / scalar);
return max;
}
/// <summary>
/// Divides a vector with a scalar.
/// Normalizes this vector to a unit vector with respect to the Eucliden 2-Norm.
/// </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)
/// <returns>This vector normalized to a unit vector with respect to the Eucliden 2-Norm.</returns>
public virtual Vector Normalize()
{
if (leftSide == null)
var norm = Norm();
var clone = Clone();
if (norm.AlmostZero())
{
throw new ArgumentNullException("leftSide");
return clone;
}
var ret = leftSide.Clone();
ret.Multiply(1.0 / rightSide);
return ret;
clone.Multiply(1.0 / norm);
return clone;
}
#endregion
#region Coping and Conversion
/// <summary>
/// Returns a deep-copy clone of the vector.
/// </summary>
/// <returns>
/// A deep-copy clone of the vector.
/// </returns>
public Vector Clone()
{
var retrunVector = CreateVector(Count);
CopyTo(retrunVector);
return retrunVector;
}
/// <summary>
/// Copies the values of this vector into the target vector.
/// </summary>
/// <param name="target">
/// The vector to copy elements into.
/// </param>
/// <exception cref="ArgumentNullException">
/// If <paramref name="target"/> is <see langword="null"/>.
/// </exception>
/// <exception cref="ArgumentException">
/// If <paramref name="target"/> is not the same size as this vector.
/// </exception>
public virtual void CopyTo(Vector target)
{
if (target == null)
{
throw new ArgumentNullException("target");
}
if (Count != target.Count)
{
throw new ArgumentException("target", Resources.ArgumentVectorsSameLength);
}
if (ReferenceEquals(this, target))
{
return;
}
for (var index = 0; index < Count; index++)
{
target[index] = this[index];
}
}
/// <summary>
/// Copies the requested elements from this vector to another.
/// </summary>
/// <param name="destination">
/// The vector to copy the elements to.
/// </param>
/// <param name="offset">
/// The element to start copying from.
/// </param>
/// <param name="destinationOffset">
/// The element to start copying to.
/// </param>
/// <param name="count">
/// The number of elements to copy.
/// </param>
public virtual void CopyTo(Vector destination, int offset, int destinationOffset, int count)
{
if (destination == null)
{
throw new ArgumentNullException("destination");
}
if (offset >= Count)
{
throw new ArgumentOutOfRangeException("offset");
}
if (offset + count > Count)
{
throw new ArgumentOutOfRangeException("count");
}
if (destinationOffset >= destination.Count)
{
throw new ArgumentOutOfRangeException("destinationOffset");
}
if (destinationOffset + count > destination.Count)
{
throw new ArgumentOutOfRangeException("count");
}
if (ReferenceEquals(this, destination))
{
var tmpVector = destination.CreateVector(destination.Count);
CopyTo(tmpVector, offset, destinationOffset, count);
tmpVector.CopyTo(destination);
}
else
{
for (var index = 0; index < count; index++)
{
destination[destinationOffset + index] = this[offset + index];
}
}
}
/// <summary>
/// Returns a <see cref="System.String"/> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String"/> that represents this instance.
/// </returns>
public override string ToString()
{
return ToString(null, null);
}
#endregion
#region Implemented Interfaces
#region ICloneable

634
src/UnitTests/LinearAlgebraTests/Double/VectorTests.Arithmetic.cs

@ -0,0 +1,634 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using MathNet.Numerics.LinearAlgebra.Double;
using MbUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
public abstract partial class VectorTests
{
[Test]
public void CanCallPlus()
{
var vector = CreateVector(_data);
var other = vector.Plus();
Assert.AreSame(vector, other, "Should be the same vector");
}
[Test]
public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Assert.Throws<ArgumentNullException>(() => other = +vector);
}
[Test]
public void CanCallUnaryPlusOperator()
{
var vector = CreateVector(_data);
var other = +vector;
Assert.AreSame(vector, other, "Should be the same vector");
}
[Test]
[MultipleAsserts]
public void CanAddScalarToVector()
{
var vector = CreateVector(_data);
vector.Add(2.0);
for( var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i]+2.0, vector[i]);
}
vector.Add(0.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] + 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddScalarToVectorUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(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.Add(0.0, result);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], result[i]);
}
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingScalarWithNullResultVector()
{
var vector = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => vector.Add(0.0, null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Add(0.0, result));
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndOneIsNull()
{
var vector = CreateVector(_data);
Assert.Throws<ArgumentNullException>(() => vector.Add(null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingTwoVectorsOfDifferingSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length +1);
Assert.Throws<ArgumentException>(() => vector.Add(other));
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndResultIsNull()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length+1);
Assert.Throws<ArgumentNullException>(() => vector.Add(other,null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingTwoVectorsAndResultIsDifferentSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Add(other, result));
}
[Test]
public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
var b = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(()=> a += b);
a = b;
b = null;
Assert.Throws<ArgumentNullException>(() => a += b);
}
[Test]
public void AdditionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize()
{
var a = CreateVector(_data.Length);
var b = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => a += b);
}
[Test]
public void CanAddTwoVectors()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Add(other);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(other, 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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingOperator()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = vector + other;
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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, result[i]);
}
}
[Test]
public void CanAddVectorToItself()
{
var vector = CreateVector(_data);
vector.Add(vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddVectorToItselfUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(vector, 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]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingItselfAsResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Add(other, vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
public void CanCallNegate()
{
var vector = CreateVector(_data);
var other = vector.Negate();
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(-_data[i], other[i]);
}
}
[Test]
public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Assert.Throws<ArgumentNullException>(() => other = -vector);
}
[Test]
public void CanCallUnaryNegationOperator()
{
var vector = CreateVector(_data);
var other = -vector;
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(-_data[i], other[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractScalarFromVector()
{
var vector = CreateVector(_data);
vector.Subtract(2.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] - 2.0, vector[i]);
}
vector.Subtract(0.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] - 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractScalarFromVectorUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(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.Subtract(0.0, result);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], result[i]);
}
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingScalarWithNullResultVector()
{
var vector = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(0.0, null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(0.0, result));
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndOneIsNull()
{
var vector = CreateVector(_data);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsOfDifferingSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(other));
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndResultIsNull()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(other, null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsAndResultIsDifferentSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(other, result));
}
[Test]
public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
var b = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => a -= b);
a = b;
b = null;
Assert.Throws<ArgumentNullException>(() => a -= b);
}
[Test]
public void SubtractionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize()
{
var a = CreateVector(_data.Length);
var b = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => a -= b);
}
[Test]
public void CanSubtractTwoVectors()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Subtract(other);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(0.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(other, 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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingOperator()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = vector - other;
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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, result[i]);
}
}
[Test]
public void CanSubtractVectorFromItself()
{
var vector = CreateVector(_data);
vector.Subtract(vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(0.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractVectorFromItselfUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(vector, 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(0.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingItselfAsResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Subtract(other, vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, vector[i]);
}
}
[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);
}
}
}

59
src/UnitTests/LinearAlgebraTests/Double/VectorTests.Norm.cs

@ -0,0 +1,59 @@
using MbUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
public abstract partial class VectorTests
{
[Test]
public void CanComputeNorm()
{
var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(7.416198487095663, vector.Norm(), 15);
}
[Test]
public void CanComputeNorm1()
{
var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(15.0, vector.Norm1(), 15);
}
[Test]
public void CanComputeSquareNorm()
{
var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(55.0, vector.SquaredNorm(), 15);
}
[Test]
[Row(1, 15.0)]
[Row(2, 7.416198487095663)]
[Row(3, 6.0822019955734001)]
[Row(10, 5.0540557845353753)]
public void CanComputeNormP(int p, double expected)
{
var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(expected, vector.NormP(p), 15);
}
[Test]
public void CanComputeNormInfinity()
{
var vector = CreateVector(_data);
AssertHelpers.AlmostEqual(5.0, vector.NormInfinity(), 15);
}
[Test]
[MultipleAsserts]
public void CanNormalizeVector()
{
var vector = CreateVector(_data);
var result = vector.Normalize();
AssertHelpers.AlmostEqual(0.134839972492648, result[0], 14);
AssertHelpers.AlmostEqual(0.269679944985297, result[1], 14);
AssertHelpers.AlmostEqual(0.404519917477945, result[2], 14);
AssertHelpers.AlmostEqual(0.539359889970594, result[3], 14);
AssertHelpers.AlmostEqual(0.674199862463242, result[4], 14);
}
}
}

625
src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs

@ -6,7 +6,7 @@ using MbUnit.Framework;
namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
{
public abstract class VectorTests
public abstract partial class VectorTests
{
private readonly double[] _data = {1, 2, 3, 4, 5};
@ -157,629 +157,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double
Assert.Throws<ArgumentException>(() => CreateVector(0));
}
[Test]
public void CanCallPlus()
{
var vector = CreateVector(_data);
var other = vector.Plus();
Assert.AreSame(vector, other, "Should be the same vector");
}
[Test]
public void OperatorPlusThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Assert.Throws<ArgumentNullException>(() => other = +vector);
}
[Test]
public void CanCallUnaryPlusOperator()
{
var vector = CreateVector(_data);
var other = +vector;
Assert.AreSame(vector, other, "Should be the same vector");
}
[Test]
[MultipleAsserts]
public void CanAddScalarToVector()
{
var vector = CreateVector(_data);
vector.Add(2.0);
for( var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i]+2.0, vector[i]);
}
vector.Add(0.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] + 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddScalarToVectorUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(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.Add(0.0, result);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], result[i]);
}
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingScalarWithNullResultVector()
{
var vector = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => vector.Add(0.0, null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Add(0.0, result));
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndOneIsNull()
{
var vector = CreateVector(_data);
Assert.Throws<ArgumentNullException>(() => vector.Add(null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingTwoVectorsOfDifferingSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length +1);
Assert.Throws<ArgumentException>(() => vector.Add(other));
}
[Test]
public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndResultIsNull()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length+1);
Assert.Throws<ArgumentNullException>(() => vector.Add(other,null));
}
[Test]
public void ThrowsArgumentExceptionWhenAddingTwoVectorsAndResultIsDifferentSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Add(other, result));
}
[Test]
public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
var b = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(()=> a += b);
a = b;
b = null;
Assert.Throws<ArgumentNullException>(() => a += b);
}
[Test]
public void AdditionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize()
{
var a = CreateVector(_data.Length);
var b = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => a += b);
}
[Test]
public void CanAddTwoVectors()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Add(other);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(other, 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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingOperator()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = vector + other;
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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, result[i]);
}
}
[Test]
public void CanAddVectorToItself()
{
var vector = CreateVector(_data);
vector.Add(vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanAddVectorToItselfUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Add(vector, 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]);
}
}
[Test]
[MultipleAsserts]
public void CanAddTwoVectorsUsingItselfAsResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Add(other, vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(_data[i] * 2.0, vector[i]);
}
}
[Test]
public void CanCallNegate()
{
var vector = CreateVector(_data);
var other = vector.Negate();
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(-_data[i], other[i]);
}
}
[Test]
public void OperatorNegateThrowsArgumentNullExceptionWhenCallOnNullVector()
{
Vector vector = null;
Vector other = null;
Assert.Throws<ArgumentNullException>(() => other = -vector);
}
[Test]
public void CanCallUnaryNegationOperator()
{
var vector = CreateVector(_data);
var other = -vector;
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(-_data[i], other[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractScalarFromVector()
{
var vector = CreateVector(_data);
vector.Subtract(2.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] - 2.0, vector[i]);
}
vector.Subtract(0.0);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i] - 2.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractScalarFromVectorUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(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.Subtract(0.0, result);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], result[i]);
}
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingScalarWithNullResultVector()
{
var vector = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(0.0, null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingScalarWithWrongSizeResultVector()
{
var vector = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(0.0, result));
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndOneIsNull()
{
var vector = CreateVector(_data);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsOfDifferingSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(other));
}
[Test]
public void ThrowsArgumentNullExceptionWhenSubtractingTwoVectorsAndResultIsNull()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentNullException>(() => vector.Subtract(other, null));
}
[Test]
public void ThrowsArgumentExceptionWhenSubtractingTwoVectorsAndResultIsDifferentSize()
{
var vector = CreateVector(_data.Length);
var other = CreateVector(_data.Length);
var result = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => vector.Subtract(other, result));
}
[Test]
public void SubtractionOperatorThrowsArgumentNullExpectionIfAVectorIsNull()
{
Vector a = null;
var b = CreateVector(_data.Length);
Assert.Throws<ArgumentNullException>(() => a -= b);
a = b;
b = null;
Assert.Throws<ArgumentNullException>(() => a -= b);
}
[Test]
public void SubtractionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize()
{
var a = CreateVector(_data.Length);
var b = CreateVector(_data.Length + 1);
Assert.Throws<ArgumentException>(() => a -= b);
}
[Test]
public void CanSubtractTwoVectors()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Subtract(other);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(0.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(other, 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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingOperator()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
var result = vector - other;
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], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, result[i]);
}
}
[Test]
public void CanSubtractVectorFromItself()
{
var vector = CreateVector(_data);
vector.Subtract(vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(0.0, vector[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractVectorFromItselfUsingResultVector()
{
var vector = CreateVector(_data);
var result = CreateVector(_data.Length);
vector.Subtract(vector, 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(0.0, result[i]);
}
}
[Test]
[MultipleAsserts]
public void CanSubtractTwoVectorsUsingItselfAsResultVector()
{
var vector = CreateVector(_data);
var other = CreateVector(_data);
vector.Subtract(other, vector);
for (var i = 0; i < _data.Length; i++)
{
Assert.AreEqual(_data[i], other[i], "Making sure the original vector wasn't modified.");
Assert.AreEqual(0.0, vector[i]);
}
}
[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);

2
src/UnitTests/UnitTests.csproj

@ -80,6 +80,8 @@
<Compile Include="InterpolationTests\InterpolationFunctionalContract.cs" />
<Compile Include="InterpolationTests\InterpolationInfrastructureContract.cs" />
<Compile Include="InterpolationTests\InterpolationFunctionalTest.cs" />
<Compile Include="LinearAlgebraTests\Double\VectorTests.Arithmetic.cs" />
<Compile Include="LinearAlgebraTests\Double\VectorTests.Norm.cs" />
<Compile Include="LinearAlgebraTests\Double\DenseVectorTests.cs" />
<Compile Include="LinearAlgebraTests\Double\UserDefinedVectorTests.cs" />
<Compile Include="LinearAlgebraTests\Double\VectorTests.cs" />

Loading…
Cancel
Save