diff --git a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebra.cs b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebra.cs index 01b0c8cb..2cc85450 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebra.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ILinearAlgebra.cs @@ -21,6 +21,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // + namespace MathNet.Numerics.Algorithms.LinearAlgebra { /// @@ -28,5 +29,11 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// public interface ILinearAlgebra { + /// + /// Adds the two arrays together: a += c. + /// + /// One of the arrays to add. + /// The other array to add. + void AddArrays(double[] a, double[] b); } } diff --git a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebra.cs b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebra.cs index 42bcf138..1749ef0a 100644 --- a/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebra.cs +++ b/src/Numerics/Algorithms/LinearAlgebra/ManagedLinearAlgebra.cs @@ -21,6 +21,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // +using System; +using MathNet.Numerics.Threading; namespace MathNet.Numerics.Algorithms.LinearAlgebra { @@ -29,5 +31,37 @@ namespace MathNet.Numerics.Algorithms.LinearAlgebra /// internal class ManagedLinearAlgebra : ILinearAlgebra { + #region ILinearAlgebra Members + + /// + /// Adds the two arrays together: a += c. + /// + /// + /// One of the arrays to add. + /// + /// + /// The other array to add. + /// + public void AddArrays(double[] a, double[] b) + { + if (a == null) + { + throw new ArgumentNullException("a"); + } + + if (b == null) + { + throw new ArgumentNullException("b"); + } + + if (a.Length != b.Length) + { + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); + } + + Parallel.For(0, a.Length, i => a[i] += b[i]); + } + + #endregion } -} +} \ No newline at end of file diff --git a/src/Numerics/Interpolation/Algorithms/AkimaSplineInterpolation.cs b/src/Numerics/Interpolation/Algorithms/AkimaSplineInterpolation.cs index 65318bd6..6d32cd5f 100644 --- a/src/Numerics/Interpolation/Algorithms/AkimaSplineInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/AkimaSplineInterpolation.cs @@ -129,7 +129,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Resources.ArgumentVectorsSameLength); } int n = samplePoints.Count; diff --git a/src/Numerics/Interpolation/Algorithms/BarycentricInterpolation.cs b/src/Numerics/Interpolation/Algorithms/BarycentricInterpolation.cs index 3a588545..624088f1 100644 --- a/src/Numerics/Interpolation/Algorithms/BarycentricInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/BarycentricInterpolation.cs @@ -127,12 +127,12 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } if (samplePoints.Count != barycentricWeights.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } _points = samplePoints; diff --git a/src/Numerics/Interpolation/Algorithms/BulirschStoerRationalInterpolation.cs b/src/Numerics/Interpolation/Algorithms/BulirschStoerRationalInterpolation.cs index 9734e8ed..51f5552c 100644 --- a/src/Numerics/Interpolation/Algorithms/BulirschStoerRationalInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/BulirschStoerRationalInterpolation.cs @@ -115,7 +115,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } _points = samplePoints; diff --git a/src/Numerics/Interpolation/Algorithms/CubicHermiteSplineInterpolation.cs b/src/Numerics/Interpolation/Algorithms/CubicHermiteSplineInterpolation.cs index 2918ad06..cf7dbde2 100644 --- a/src/Numerics/Interpolation/Algorithms/CubicHermiteSplineInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/CubicHermiteSplineInterpolation.cs @@ -141,7 +141,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count || samplePoints.Count != sampleDerivatives.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } double[] coefficients = new double[4 * (samplePoints.Count - 1)]; diff --git a/src/Numerics/Interpolation/Algorithms/CubicSplineInterpolation.cs b/src/Numerics/Interpolation/Algorithms/CubicSplineInterpolation.cs index b5bb0202..10655428 100644 --- a/src/Numerics/Interpolation/Algorithms/CubicSplineInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/CubicSplineInterpolation.cs @@ -200,7 +200,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Resources.ArgumentVectorsSameLength); } int n = samplePoints.Count; diff --git a/src/Numerics/Interpolation/Algorithms/FloaterHormannRationalInterpolation.cs b/src/Numerics/Interpolation/Algorithms/FloaterHormannRationalInterpolation.cs index b35613d6..cecf0ea2 100644 --- a/src/Numerics/Interpolation/Algorithms/FloaterHormannRationalInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/FloaterHormannRationalInterpolation.cs @@ -182,7 +182,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } if (0 > order || samplePoints.Count <= order) diff --git a/src/Numerics/Interpolation/Algorithms/LinearSplineInterpolation.cs b/src/Numerics/Interpolation/Algorithms/LinearSplineInterpolation.cs index d0a78577..d07811df 100644 --- a/src/Numerics/Interpolation/Algorithms/LinearSplineInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/LinearSplineInterpolation.cs @@ -128,7 +128,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } double[] coefficients = new double[4 * (samplePoints.Count - 1)]; diff --git a/src/Numerics/Interpolation/Algorithms/NevillePolynomialInterpolation.cs b/src/Numerics/Interpolation/Algorithms/NevillePolynomialInterpolation.cs index 469cfd8c..d7fc503a 100644 --- a/src/Numerics/Interpolation/Algorithms/NevillePolynomialInterpolation.cs +++ b/src/Numerics/Interpolation/Algorithms/NevillePolynomialInterpolation.cs @@ -120,7 +120,7 @@ namespace MathNet.Numerics.Interpolation.Algorithms if (samplePoints.Count != sampleValues.Count) { - throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLengths); + throw new ArgumentException(Properties.Resources.ArgumentVectorsSameLength); } _points = samplePoints; diff --git a/src/Numerics/LinearAlgebra/Double/DenseVector.cs b/src/Numerics/LinearAlgebra/Double/DenseVector.cs index bb440838..586fdb98 100644 --- a/src/Numerics/LinearAlgebra/Double/DenseVector.cs +++ b/src/Numerics/LinearAlgebra/Double/DenseVector.cs @@ -21,6 +21,10 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Algorithms; +using MathNet.Numerics.Algorithms.LinearAlgebra; +using MathNet.Numerics.Threading; + namespace MathNet.Numerics.LinearAlgebra.Double { using System; @@ -32,6 +36,11 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public class DenseVector : Vector { + /// + /// The linear algebra provider. + /// + private readonly ILinearAlgebra _linearAlgebra = AlgorithmFactory.LinearAlgebra; + /// /// Initializes a new instance of the class with a given size. /// @@ -176,7 +185,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != target.Count) { - throw new ArgumentException("target", Resources.ArgumentVectorsSameLengths); + throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); } var otherVector = target as DenseVector; @@ -192,5 +201,158 @@ namespace MathNet.Numerics.LinearAlgebra.Double Buffer.BlockCopy(Data, 0, otherVector.Data, 0, Data.Length * Constants.SizeOfDouble); } } + + /// + /// Adds a scalar to each element of the vector. + /// + /// The scalar to add. + public override void Add(double scalar) + { + if (scalar.AlmostZero()) + { + return; + } + + Parallel.For(0, Count, i => Data[i] += scalar); + } + + /// + /// Adds a scalar to each element of the vector and stores the result in the result vector. + /// + /// The scalar to add. + /// The vector to store the result of the addition. + /// If the result vector is . + /// If this vector and are not the same size. + public override void Add(double scalar, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + } + + CopyTo(result); + result.Add(scalar); + } + + /// + /// Adds another vector to this vector. + /// + /// The vector to add to this one. + /// If the other vector is . + /// If this vector and are not the same size. + public override void Add(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + } + + var denseVector = other as DenseVector; + + if (denseVector == null) + { + base.Add(other); + } + else + { + _linearAlgebra.AddArrays(Data, denseVector.Data); + } + } + + /// + /// Adds another vector to this vector and stores the result into the result vector. + /// + /// The vector to add to this one. + /// The vector to store the result of the 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 override void Add(Vector other, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != other.Count) + { + throw new ArgumentException("other", Resources.ArgumentVectorsSameLength); + } + + if (Count != result.Count) + { + throw new ArgumentException("result", Resources.ArgumentVectorsSameLength); + } + + if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) + { + var tmp = result.CreateVector(result.Count); + Add(other, tmp); + tmp.CopyTo(result); + } + else + { + CopyTo(result); + result.Add(other); + } + } + + /// + /// Returns a Vector containing the same values of rightSide. + /// + /// This method is included for completeness. + /// The vector to get the values from. + /// A vector containing a the same values as . + /// If is . + public static Vector operator +(DenseVector rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + return rightSide.Plus(); + } + + /// + /// Adds two Vectors together and returns the results. + /// + /// One of the vectors to add. + /// The other vector to add. + /// The result of the addition. + /// If and are not the same size. + /// If or is . + public static Vector operator +(DenseVector leftSide, DenseVector rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + if (leftSide == null) + { + throw new ArgumentNullException("leftSide"); + } + + if (leftSide.Count != rightSide.Count) + { + throw new ArgumentException("rightSide", Resources.ArgumentVectorsSameLength); + } + + var ret = leftSide.Clone(); + ret.Add(rightSide); + return ret; + } } } \ No newline at end of file diff --git a/src/Numerics/LinearAlgebra/Double/Vector.cs b/src/Numerics/LinearAlgebra/Double/Vector.cs index ca8ed532..b1f579e6 100644 --- a/src/Numerics/LinearAlgebra/Double/Vector.cs +++ b/src/Numerics/LinearAlgebra/Double/Vector.cs @@ -21,6 +21,8 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // +using MathNet.Numerics.Threading; + namespace MathNet.Numerics.LinearAlgebra.Double { using System; @@ -112,7 +114,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double if (Count != target.Count) { - throw new ArgumentException("target", Resources.ArgumentVectorsSameLengths); + throw new ArgumentException("target", Resources.ArgumentVectorsSameLength); } if (ReferenceEquals(this, target)) @@ -286,7 +288,156 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// public override string ToString() { - return this.ToString(null, null); + return ToString(null, null); + } + + /// + /// Adds a scalar to each element of the vector. + /// + /// The scalar to add. + public virtual void Add(double scalar) + { + if (scalar.AlmostZero()) + { + return; + } + + Parallel.For(0, Count, i => this[i] += scalar); + } + + /// + /// Adds a scalar to each element of the vector and stores the result in the result vector. + /// + /// The scalar to add. + /// The vector to store the result of the addition. + /// If the result vector is . + /// If this vector and are not the same size. + public virtual void Add(double scalar, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + CopyTo(result); + result.Add(scalar); + } + + /// + /// Returns a clone of this vector. + /// + /// A clone of this vector. + /// Added as an alternative to the unary addition operator. + public virtual Vector Plus() + { + return this; + } + + /// + /// Adds another vector to this vector. + /// + /// The vector to add to this one. + /// If the other vector is . + /// If this vector and are not the same size. + public virtual void Add(Vector other) + { + if (other == null) + { + throw new ArgumentNullException("other"); + } + + if (Count != other.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "other"); + } + + Parallel.For(0, Count, i => this[i] += other[i]); + } + + /// + /// Adds another vector to this vector and stores the result into the result vector. + /// + /// The vector to add to this one. + /// The vector to store the result of the 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 Add(Vector other, Vector result) + { + if (result == null) + { + throw new ArgumentNullException("result"); + } + + if (Count != result.Count) + { + throw new ArgumentException(Resources.ArgumentVectorsSameLength, "result"); + } + + if (ReferenceEquals(this, result) || ReferenceEquals(other, result)) + { + var tmp = result.CreateVector(result.Count); + Add(other, tmp); + tmp.CopyTo(result); + } + else + { + CopyTo(result); + result.Add(other); + } + } + + /// + /// Returns a Vector containing the same values of rightSide. + /// + /// This method is included for completeness. + /// The vector to get the values from. + /// A vector containing a the same values as . + /// If is . + public static Vector operator +(Vector rightSide) + { + if (rightSide == null) + { + throw new ArgumentNullException("rightSide"); + } + + return rightSide.Plus(); + } + + /// + /// Adds two Vectors together and returns the results. + /// + /// One of the vectors to add. + /// The other vector to add. + /// The result of the addition. + /// If and are not the same size. + /// If or is . + 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; } #region Implemented Interfaces @@ -301,7 +452,7 @@ namespace MathNet.Numerics.LinearAlgebra.Double /// object ICloneable.Clone() { - return this.Clone(); + return Clone(); } #endregion diff --git a/src/Numerics/Properties/Resources.Designer.cs b/src/Numerics/Properties/Resources.Designer.cs index bcfa4586..81e461da 100644 --- a/src/Numerics/Properties/Resources.Designer.cs +++ b/src/Numerics/Properties/Resources.Designer.cs @@ -387,9 +387,9 @@ namespace MathNet.Numerics.Properties { /// /// Looks up a localized string similar to All vectors must have the same dimensionality.. /// - internal static string ArgumentVectorsSameLengths { + internal static string ArgumentVectorsSameLength { get { - return ResourceManager.GetString("ArgumentVectorsSameLengths", resourceCulture); + return ResourceManager.GetString("ArgumentVectorsSameLength", resourceCulture); } } diff --git a/src/Numerics/Properties/Resources.resx b/src/Numerics/Properties/Resources.resx index 45834d99..9130340e 100644 --- a/src/Numerics/Properties/Resources.resx +++ b/src/Numerics/Properties/Resources.resx @@ -207,7 +207,7 @@ Array length must be a multiple of {0}. - + All vectors must have the same dimensionality. diff --git a/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs new file mode 100644 index 00000000..781c19b9 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Double/UserDefinedVectorTests.cs @@ -0,0 +1,60 @@ +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double +{ + using System; + using System.Collections.Generic; + + using MathNet.Numerics.LinearAlgebra.Double; + + internal class UserDefinedVector : Vector + { + private readonly double[] _data; + + public UserDefinedVector(int size) + : base(size) + { + _data = new double[size]; + } + + public override double this[int index] + { + get + { + return _data[index]; + } + + set + { + _data[index] = value; + } + } + + public override Matrix CreateMatrix(int rows, int columns) + { + throw new NotImplementedException(); + } + + public override Vector CreateVector(int size) + { + return new UserDefinedVector(size); + } + } + + public class UserDefinedVectorTests : VectorTests + { + protected override Vector CreateVector(int size) + { + return new UserDefinedVector(size); + } + + protected override Vector CreateVector(IList data) + { + var vector = new UserDefinedVector(data.Count); + for (var index = 0; index < data.Count; index++) + { + vector[index] = data[index]; + } + + return vector; + } + } +} \ No newline at end of file diff --git a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs index 7b001c41..0b4e0590 100644 --- a/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs +++ b/src/UnitTests/LinearAlgebraTests/Double/VectorTests.cs @@ -1,40 +1,38 @@ -// -------------------------------------------------------------------------------------------------------------------- -// -// -// -// vector tests. -// -// -------------------------------------------------------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Globalization; +using MathNet.Numerics.LinearAlgebra.Double; +using MbUnit.Framework; namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double { - using System; - using System.Collections.Generic; - using System.Globalization; - - using MathNet.Numerics.LinearAlgebra.Double; - - using MbUnit.Framework; - - /// - /// The vector tests. - /// public abstract class VectorTests { - /// - /// The test data. - /// - private readonly double[] _data = { 1, 2, 3, 4, 5 }; + private readonly double[] _data = {1, 2, 3, 4, 5}; - /// - /// can clone vector. - /// [Test] + [MultipleAsserts] public void CanCloneVector() { var vector = CreateVector(_data); var clone = vector.Clone(); + Assert.AreNotSame(vector, clone); + Assert.AreEqual(vector.Count, clone.Count); + for (var index = 0; index < _data.Length; index++) + { + Assert.AreEqual(vector[index], clone[index]); + } + } + + [Test] + [MultipleAsserts] + public void CanCloneVectorUsingICloneable() + { + var vector = CreateVector(_data); + var clone = (Vector)((ICloneable)vector).Clone(); + + Assert.AreNotSame(vector, clone); Assert.AreEqual(vector.Count, clone.Count); for (var index = 0; index < _data.Length; index++) { @@ -42,9 +40,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } - /// - /// can convert vector to string. - /// [Test] public void CanConvertVectorToString() { @@ -54,9 +49,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(string.Format("1{0}2{0}3{0}4{0}5", sep), str); } - /// - /// can copy partial vector to another. - /// [Test] [MultipleAsserts] public void CanCopyPartialVectorToAnother() @@ -73,9 +65,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(0.0, other[4]); } - /// - /// can copy vector to another. - /// [Test] [MultipleAsserts] public void CanCopyVectorToAnother() @@ -91,18 +80,12 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } - /// - /// can create matrix. - /// [Test] [Ignore] public void CanCreateMatrix() { } - /// - /// can create vector. - /// [Test] public void CanCreateVector() { @@ -111,9 +94,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.AreEqual(expected.GetType(), actual.GetType(), "vectors are same type."); } - /// - /// can enumerate over vector. - /// [Test] [MultipleAsserts] public void CanEnumerateOverVector() @@ -128,9 +108,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } - /// - /// can equate vectors. - /// [Test] [MultipleAsserts] public void CanEquateVectors() @@ -144,9 +121,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double Assert.IsFalse(vector1.Equals(null)); } - /// - /// can get indexed enumerator. - /// [Test] [MultipleAsserts] public void CanGetIndexedEnumerator() @@ -161,9 +135,6 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } - /// - /// can get indexed enumerator over range. - /// [Test] [MultipleAsserts] public void CanGetIndexedEnumeratorOverRange() @@ -178,16 +149,235 @@ namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Double } } - /// - /// throws argument exception if size is not positive. - /// [Test] + [MultipleAsserts] public void ThrowsArgumentExceptionIfSizeIsNotPositive() { Assert.Throws(() => CreateVector(-1)); Assert.Throws(() => 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(() => 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(() => vector.Add(0.0, null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenAddingScalarWithWrongSizeResultVector() + { + var vector = CreateVector(_data.Length); + var result = CreateVector(_data.Length + 1); + Assert.Throws(() => vector.Add(0.0, result)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndOneIsNull() + { + var vector = CreateVector(_data); + Assert.Throws(() => vector.Add(null)); + } + + [Test] + public void ThrowsArgumentExceptionWhenAddingTwoVectorsOfDifferingSize() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length +1); + Assert.Throws(() => vector.Add(other)); + } + + [Test] + public void ThrowsArgumentNullExceptionWhenAddingTwoVectorsAndResultIsNull() + { + var vector = CreateVector(_data.Length); + var other = CreateVector(_data.Length+1); + Assert.Throws(() => 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(() => vector.Add(other, result)); + } + + [Test] + public void AdditionOperatorThrowsArgumentNullExpectionIfAVectorIsNull() + { + Vector a = null; + var b = CreateVector(_data.Length); + Assert.Throws(()=> a += b); + + a = b; + b = null; + Assert.Throws(() => a += b); + } + + [Test] + public void AdditionOperatorThrowsArgumentExpectionIfVectorsAreDifferentSize() + { + var a = CreateVector(_data.Length); + var b = CreateVector(_data.Length + 1); + Assert.Throws(() => 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]); + } + } + + protected abstract Vector CreateVector(int size); protected abstract Vector CreateVector(IList data); diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index e118bcba..d32db935 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -81,6 +81,7 @@ +