// // Math.NET Numerics, part of the Math.NET Project // http://numerics.mathdotnet.com // http://github.com/mathnet/mathnet-numerics // http://mathnetnumerics.codeplex.com // Copyright (c) 2009-2010 Math.NET // Permission is hereby granted, free of charge, to any person // obtaining a copy of this software and associated documentation // files (the "Software"), to deal in the Software without // restriction, including without limitation the rights to use, // copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following // conditions: // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR // OTHER DEALINGS IN THE SOFTWARE. // namespace MathNet.Numerics.UnitTests.LinearAlgebraTests.Complex { using System; using System.Collections; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Numerics; using Distributions; using LinearAlgebra.Generic; using NUnit.Framework; /// /// Abstract class with the common set of vector tests. /// [TestFixture] public abstract partial class VectorTests { /// /// Test vector values. /// protected readonly Complex[] Data = { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1) }; /// /// Can clone a vector. /// [Test] public void CanCloneVector() { var vector = CreateVector(Data); var clone = vector.Clone(); Assert.AreNotSame(vector, clone); Assert.AreEqual(vector.Count, clone.Count); CollectionAssert.AreEqual(vector, clone); } /// /// Can clone a vector using IClonable interface method. /// [Test] public void CanCloneVectorUsingICloneable() { var vector = CreateVector(Data); var clone = (Vector)((ICloneable)vector).Clone(); Assert.AreNotSame(vector, clone); Assert.AreEqual(vector.Count, clone.Count); CollectionAssert.AreEqual(vector, clone); } /// /// Can convert vector to string. /// [Test] public void CanConvertVectorToString() { var vector = CreateVector(Data); var str = vector.ToString(); var sep = CultureInfo.CurrentCulture.TextInfo.ListSeparator; Assert.AreEqual(string.Format("(1{0} 1){1}(2{0} 1){1}(3{0} 1){1}(4{0} 1){1}(5{0} 1)", ",", sep), str); } /// /// Can copy part of a vector to another vector. /// [Test] public void CanCopyPartialVectorToAnother() { var vector = CreateVector(Data); var other = CreateVector(Data.Length); vector.CopyTo(other, 2, 2, 2); AssertHelpers.AreEqual(Complex.Zero, other[0]); AssertHelpers.AreEqual(Complex.Zero, other[1]); AssertHelpers.AreEqual(new Complex(3, 1), other[2]); AssertHelpers.AreEqual(new Complex(4, 1), other[3]); AssertHelpers.AreEqual(Complex.Zero, other[4]); } /// /// Can copy part of a vector to the same vector. /// [Test] public void CanCopyPartialVectorToSelf() { var vector = CreateVector(Data); vector.CopyTo(vector, 0, 2, 2); AssertHelpers.AreEqual(new Complex(1, 1), vector[0]); AssertHelpers.AreEqual(new Complex(2, 1), vector[1]); AssertHelpers.AreEqual(new Complex(1, 1), vector[2]); AssertHelpers.AreEqual(new Complex(2, 1), vector[3]); AssertHelpers.AreEqual(new Complex(5, 1), vector[4]); } /// /// Can copy a vector to another vector. /// [Test] public void CanCopyVectorToAnother() { var vector = CreateVector(Data); var other = CreateVector(Data.Length); vector.CopyTo(other); CollectionAssert.AreEqual(vector, other); } /// /// Can create a matrix using instance of a vector. /// [Test] public void CanCreateMatrix() { var vector = CreateVector(Data); var matrix = vector.CreateMatrix(10, 10); Assert.AreEqual(matrix.RowCount, 10); Assert.AreEqual(matrix.ColumnCount, 10); } /// /// Can create a vector using the instance of vector. /// [Test] public void CanCreateVector() { var expected = CreateVector(5); var actual = expected.CreateVector(5); Assert.AreEqual(expected.GetType(), actual.GetType(), "vectors are same type."); } /// /// Can enumerate over a vector. /// [Test] public void CanEnumerateOverVector() { var vector = CreateVector(Data); for (var i = 0; i < Data.Length; i++) { Assert.AreEqual(Data[i], vector[i]); } } /// /// Can enumerate over a vector using IEnumerable interface. /// [Test] public void CanEnumerateOverVectorUsingIEnumerable() { var enumerable = (IEnumerable)CreateVector(Data); var index = 0; foreach (var element in enumerable) { Assert.AreEqual(Data[index++], (Complex)element); } } /// /// Can equate vectors. /// [Test] public void CanEquateVectors() { var vector1 = CreateVector(Data); var vector2 = CreateVector(Data); var vector3 = CreateVector(4); Assert.IsTrue(vector1.Equals(vector1)); Assert.IsTrue(vector1.Equals(vector2)); Assert.IsFalse(vector1.Equals(vector3)); Assert.IsFalse(vector1.Equals(null)); Assert.IsFalse(vector1.Equals(2)); } /// /// CreateVector throws ArgumentException if size is not positive. /// [Test] public void SizeIsNotPositiveThrowsArgumentException() { Assert.Throws(() => CreateVector(-1)); Assert.Throws(() => CreateVector(0)); } /// /// Can equate vectors using Object.Equals. /// [Test] public void CanEquateVectorsUsingObjectEquals() { var vector1 = CreateVector(Data); var vector2 = CreateVector(Data); Assert.IsTrue(vector1.Equals((object)vector2)); } /// /// Can get hash code of a vector. /// [Test] public void CanGetHashCode() { var vector = CreateVector(new[] { new Complex(1, 1), new Complex(2, 1), new Complex(3, 1), new Complex(4, 1), new Complex(5, 1) }); Assert.AreEqual(1104007323, vector.GetHashCode()); } /// /// Can enumerate over a vector using indexed enumerator. /// [Test] public void CanEnumerateOverVectorUsingIndexedEnumerator() { var vector = CreateVector(Data); foreach (var pair in vector.GetIndexedEnumerator()) { Assert.AreEqual(Data[pair.Item1], pair.Item2); } } /// /// Can convert a vector to array. /// [Test] public void CanConvertVectorToArray() { var vector = CreateVector(Data); var array = vector.ToArray(); CollectionAssert.AreEqual(array, vector); } /// /// Can convert a vector to column matrix. /// [Test] public void CanConvertVectorToColumnMatrix() { var vector = CreateVector(Data); var matrix = vector.ToColumnMatrix(); Assert.AreEqual(vector.Count, matrix.RowCount); Assert.AreEqual(1, matrix.ColumnCount); for (var i = 0; i < vector.Count; i++) { Assert.AreEqual(vector[i], matrix[i, 0]); } } /// /// Can convert a vector to row matrix. /// [Test] public void CanConvertVectorToRowMatrix() { var vector = CreateVector(Data); var matrix = vector.ToRowMatrix(); Assert.AreEqual(vector.Count, matrix.ColumnCount); Assert.AreEqual(1, matrix.RowCount); for (var i = 0; i < vector.Count; i++) { Assert.AreEqual(vector[i], matrix[0, i]); } } /// /// Can set values in vector. /// [Test] public void CanSetValues() { var vector = CreateVector(Data); vector.SetValues(Data); CollectionAssert.AreEqual(vector, Data); } /// /// Can get subvector from a vector. /// /// The first element to begin copying from. /// The number of elements to copy. [Test, Sequential] public void CanGetSubVector([Values(0, 2, 1)] int index, [Values(5, 2, 4)] int length) { var vector = CreateVector(Data); var sub = vector.SubVector(index, length); Assert.AreEqual(length, sub.Count); for (var i = 0; i < length; i++) { Assert.AreEqual(vector[i + index], sub[i]); } } /// /// Getting subvector using wrong parameters throw an exception. /// /// The first element to begin copying from. /// The number of elements to copy. [Test, Combinatorial] public void CanGetSubVectorWithWrongValuesShouldThrowException([Values(6, 1)] int index, [Values(10, -10)] int length) { var vector = CreateVector(Data); Assert.Throws(() => vector.SubVector(index, length)); } /// /// Can find absolute minimum value index. /// [Test] public void CanFindAbsoluteMinimumIndex() { var source = CreateVector(Data); const int Expected = 0; var actual = source.AbsoluteMinimumIndex(); Assert.AreEqual(Expected, actual); } /// /// Can find absolute minimum value of a vector. /// [Test] public void CanFindAbsoluteMinimum() { var source = CreateVector(Data); var expected = new Complex(1, 1).Magnitude; var actual = source.AbsoluteMinimum(); Assert.AreEqual(expected, actual.Real); } /// /// Can find absolute maximum value index. /// [Test] public void CanFindAbsoluteMaximumIndex() { var source = CreateVector(Data); const int Expected = 4; var actual = source.AbsoluteMaximumIndex(); Assert.AreEqual(Expected, actual); } /// /// Can find absolute maximum value of a vector. /// [Test] public void CanFindAbsoluteMaximum() { var source = CreateVector(Data); var expected = new Complex(5, 1).Magnitude; var actual = source.AbsoluteMaximum(); Assert.AreEqual(expected, actual.Real); } /// /// Find maximum value index throws NotSupportedException. /// [Test] public void FindMaximumIndexThrowsNotSupportedException() { var vector = CreateVector(Data); Assert.Throws(() => { var actual = vector.MaximumIndex(); }); } /// /// Find maximum value throws NotSupportedException. /// [Test] public void FindMaximumThrowsNotSupportedException() { var vector = CreateVector(Data); Assert.Throws(() => { var actual = vector.Maximum(); }); } /// /// Find minimum value index throws NotSupportedException. /// [Test] public void FindMinimumIndexThrowsNotSupportedException() { var vector = CreateVector(Data); Assert.Throws(() => { var actual = vector.MinimumIndex(); }); } /// /// Find minimum value throws NotSupportedException. /// [Test] public void FindMinimumThrowsNotSupportedException() { var vector = CreateVector(Data); Assert.Throws(() => { var actual = vector.Minimum(); }); } /// /// Can compute the sum of a vector elements. /// [Test] public void CanSum() { Complex[] testData = { new Complex(-20, -1), new Complex(-10, -1), new Complex(10, 1), new Complex(20, 1), new Complex(30, 1) }; var vector = CreateVector(testData); var actual = vector.Sum(); var expected = new Complex(30, 1); Assert.AreEqual(expected, actual); } /// /// Can compute the sum of the absolute value a vector elements. /// [Test] public void CanSumMagnitudes() { Complex[] testData = { new Complex(-20, -1), new Complex(-10, -1), new Complex(10, 1), new Complex(20, 1), new Complex(30, 1) }; var vector = CreateVector(testData); var actual = vector.SumMagnitudes(); var expected = testData.Sum(complex => complex.Magnitude); Assert.AreEqual(expected, actual.Real); } /// /// Set values with null parameter throw exception. /// [Test] public void SetValuesWithNullParameterThrowsArgumentException() { var vector = CreateVector(Data); Assert.Throws(() => vector.SetValues(null)); } /// /// Set values with non-equal data length throw exception. /// [Test] public void SetValuesWithNonEqualDataLengthThrowsArgumentException() { var vector = CreateVector(Data.Length + 2); Assert.Throws(() => vector.SetValues(Data)); } /// /// Generate a vector with number of elements less than zero throw an exception. /// [Test] public void RandomWithNumberOfElementsLessThanZeroThrowsArgumentException() { var vector = CreateVector(4); Assert.Throws(() => vector.Random(-2, new ContinuousUniform())); } /// /// Can clear a vector. /// [Test] public void CanClearVector() { Complex[] testData = { new Complex(-20, -1), new Complex(-10, -1), new Complex(10, 1), new Complex(20, 1), new Complex(30, 1) }; var vector = CreateVector(testData); vector.Clear(); foreach (var element in vector) { Assert.AreEqual(Complex.Zero, element); } } /// /// Creates a new instance of the Vector class. /// /// The size of the Vector to construct. /// The new Vector. protected abstract Vector CreateVector(int size); /// /// Creates a new instance of the Vector class. /// /// The array to create this vector from. /// The new Vector. protected abstract Vector CreateVector(IList data); } }