diff --git a/src/UnitTests/LinearAlgebraTests/Build.cs b/src/UnitTests/LinearAlgebraTests/Build.cs new file mode 100644 index 00000000..ce254596 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/Build.cs @@ -0,0 +1,73 @@ +// +// 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-2014 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. +// + +using System; +using System.Collections.Generic; +using MathNet.Numerics.LinearAlgebra.Storage; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests +{ + public enum VectorStorageType + { + DenseVector = 1, + SparseVector = 2 + } + + public static class Build + { + public static VectorStorage VectorStorage(VectorStorageType type, IEnumerable data) + where T : struct, IEquatable, IFormattable + { + switch (type) + { + case VectorStorageType.DenseVector: + return DenseVectorStorage.OfEnumerable(data); + case VectorStorageType.SparseVector: + return SparseVectorStorage.OfEnumerable(data); + default: + throw new NotSupportedException(); + } + } + + public static VectorStorage VectorStorage(VectorStorageType type, int length) + where T : struct, IEquatable, IFormattable + { + switch (type) + { + case VectorStorageType.DenseVector: + return new DenseVectorStorage(length); + case VectorStorageType.SparseVector: + return new SparseVectorStorage(length); + default: + throw new NotSupportedException(); + } + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/VectorStorageCombinatorsTests.cs b/src/UnitTests/LinearAlgebraTests/VectorStorageCombinatorsTests.cs new file mode 100644 index 00000000..4f6528c9 --- /dev/null +++ b/src/UnitTests/LinearAlgebraTests/VectorStorageCombinatorsTests.cs @@ -0,0 +1,140 @@ +// +// 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-2014 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. +// + +using System.Threading; +using MathNet.Numerics.LinearAlgebra; +using MathNet.Numerics.LinearAlgebra.Storage; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.LinearAlgebraTests +{ + [TestFixture, Category("LA")] + public class VectorStorageCombinatorsTests + { + [Theory] + public void MapToSkipZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { -1.0, -2.0, 0.0, -4.0 }); + a.MapTo(result, u => -u, Zeros.AllowSkip); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void MapToForceIncludeZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); + a.MapTo(result, u => -u + 1.0, Zeros.Include); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void MapToAutoIncludeZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); + a.MapTo(result, u => -u + 1.0, Zeros.AllowSkip); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void MapIndexedToSkipZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { -1.0, -2.0, 0.0, -4.0 }); + int badValueCount = 0; // one time is OK for zero-check + a.MapIndexedTo(result, (i, u) => { if (a.At(i) != u) Interlocked.Increment(ref badValueCount); return -u; }, Zeros.AllowSkip); + Assert.That(badValueCount, Is.LessThanOrEqualTo(1)); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void MapIndexedToForceIncludeZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); + int badValueCount = 0; // one time is OK for zero-check + a.MapIndexedTo(result, (i, u) => { if (a.At(i) != u) Interlocked.Increment(ref badValueCount); return -u + 1.0; }, Zeros.Include); + Assert.That(badValueCount, Is.LessThanOrEqualTo(1)); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void MapIndexedToAutoIncludeZeros(VectorStorageType aType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0 }); + var result = Build.VectorStorage(resultType, 4); + var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); + int badValueCount = 0; // one time is OK for zero-check + a.MapIndexedTo(result, (i, u) => { if (a.At(i) != u) Interlocked.Increment(ref badValueCount); return -u + 1.0; }, Zeros.AllowSkip); + Assert.That(badValueCount, Is.LessThanOrEqualTo(1)); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void Map2ToSkipZeros(VectorStorageType aType, VectorStorageType bType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }); + var b = Build.VectorStorage(bType, new[] { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }); + var result = Build.VectorStorage(resultType, 6); + var expected = new DenseVectorStorage(6, new[] { 12.0, 14.0, 13.0, 4.0, 0.0, 22.0 }); + a.Map2To(result, b, (u, v) => u + v, Zeros.AllowSkip); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void Map2ToForceIncludeZeros(VectorStorageType aType, VectorStorageType bType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }); + var b = Build.VectorStorage(bType, new[] { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }); + var result = Build.VectorStorage(resultType, 6); + var expected = new DenseVectorStorage(6, new[] { 13.0, 15.0, 14.0, 5.0, 1.0, 23.0 }); + a.Map2To(result, b, (u, v) => u + v + 1.0, Zeros.Include); + Assert.That(result.Equals(expected)); + } + + [Theory] + public void Map2ToAutoIncludeZeros(VectorStorageType aType, VectorStorageType bType, VectorStorageType resultType) + { + var a = Build.VectorStorage(aType, new[] { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }); + var b = Build.VectorStorage(bType, new[] { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }); + var result = Build.VectorStorage(resultType, 6); + var expected = new DenseVectorStorage(6, new[] { 13.0, 15.0, 14.0, 5.0, 1.0, 23.0 }); + a.Map2To(result, b, (u, v) => u + v + 1.0, Zeros.AllowSkip); + Assert.That(result.Equals(expected)); + } + } +} diff --git a/src/UnitTests/LinearAlgebraTests/VectorStorageTests.cs b/src/UnitTests/LinearAlgebraTests/VectorStorageTests.cs deleted file mode 100644 index 79687772..00000000 --- a/src/UnitTests/LinearAlgebraTests/VectorStorageTests.cs +++ /dev/null @@ -1,271 +0,0 @@ -// -// 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-2014 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. -// - -using MathNet.Numerics.LinearAlgebra; -using MathNet.Numerics.LinearAlgebra.Storage; -using NUnit.Framework; - -namespace MathNet.Numerics.UnitTests.LinearAlgebraTests -{ - [TestFixture, Category("LA")] - public class VectorStorageTests - { - [Test] - public void MapToSkipZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(4, new[] { -1.0, -2.0, 0.0, -4.0 }); - - rdense.Clear(); - adense.MapTo(rdense, u => -u, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense->dense"); - - rsparse.Clear(); - adense.MapTo(rsparse, u => -u, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense->sparse"); - - rdense.Clear(); - asparse.MapTo(rdense, u => -u, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse->dense"); - - rsparse.Clear(); - asparse.MapTo(rsparse, u => -u, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse->sparse"); - } - - [Test] - public void MapToForceIncludeZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); - - rdense.Clear(); - adense.MapTo(rdense, u => -u + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "dense->dense"); - - rsparse.Clear(); - adense.MapTo(rsparse, u => -u + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "dense->sparse"); - - rdense.Clear(); - asparse.MapTo(rdense, u => -u + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "sparse->dense"); - - rsparse.Clear(); - asparse.MapTo(rsparse, u => -u + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "sparse->sparse"); - } - - [Test] - public void MapToAutoIncludeZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(4, new[] { 0.0, -1.0, 1.0, -3.0 }); - - rdense.Clear(); - adense.MapTo(rdense, u => -u + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense->dense"); - - rsparse.Clear(); - adense.MapTo(rsparse, u => -u + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense->sparse"); - - rdense.Clear(); - asparse.MapTo(rdense, u => -u + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse->dense"); - - rsparse.Clear(); - asparse.MapTo(rsparse, u => -u + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse->sparse"); - } - - [Test] - public void Map2ToSkipZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }; - double[] b = { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - var bdense = DenseVectorStorage.OfEnumerable(b); - var bsparse = SparseVectorStorage.OfEnumerable(b); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(6, new[] { 12.0, 14.0, 13.0, 4.0, 0.0, 22.0 }); - - rdense.Clear(); - adense.Map2To(rdense, bdense, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense*dense->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bdense, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense*dense->sparse"); - - rdense.Clear(); - adense.Map2To(rdense, bsparse, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense*sparse->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bsparse, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense*sparse->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bdense, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse*dense->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bdense, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse*dense->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bsparse, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse*sparse->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bsparse, (u, v) => u + v, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse*sparse->sparse"); - } - - [Test] - public void Map2ToForceIncludeZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }; - double[] b = { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - var bdense = DenseVectorStorage.OfEnumerable(b); - var bsparse = SparseVectorStorage.OfEnumerable(b); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(6, new[] { 13.0, 15.0, 14.0, 5.0, 1.0, 23.0 }); - - rdense.Clear(); - adense.Map2To(rdense, bdense, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "dense*dense->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bdense, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "dense*dense->sparse"); - - rdense.Clear(); - adense.Map2To(rdense, bsparse, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "dense*sparse->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bsparse, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "dense*sparse->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bdense, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "sparse*dense->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bdense, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "sparse*dense->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bsparse, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rdense.Equals(expected), "sparse*sparse->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bsparse, (u, v) => u + v + 1.0, Zeros.Include); - Assert.That(rsparse.Equals(expected), "sparse*sparse->sparse"); - } - - [Test] - public void Map2ToAutoIncludeZeros() - { - double[] a = { 1.0, 2.0, 0.0, 4.0, 0.0, 6.0 }; - double[] b = { 11.0, 12.0, 13.0, 0.0, 0.0, 16.0 }; - var adense = DenseVectorStorage.OfEnumerable(a); - var asparse = SparseVectorStorage.OfEnumerable(a); - var bdense = DenseVectorStorage.OfEnumerable(b); - var bsparse = SparseVectorStorage.OfEnumerable(b); - - var rdense = new DenseVectorStorage(a.Length); - var rsparse = new SparseVectorStorage(a.Length); - - var expected = new DenseVectorStorage(6, new[] { 13.0, 15.0, 14.0, 5.0, 1.0, 23.0 }); - - rdense.Clear(); - adense.Map2To(rdense, bdense, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense*dense->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bdense, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense*dense->sparse"); - - rdense.Clear(); - adense.Map2To(rdense, bsparse, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "dense*sparse->dense"); - - rsparse.Clear(); - adense.Map2To(rsparse, bsparse, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "dense*sparse->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bdense, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse*dense->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bdense, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse*dense->sparse"); - - rdense.Clear(); - asparse.Map2To(rdense, bsparse, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rdense.Equals(expected), "sparse*sparse->dense"); - - rsparse.Clear(); - asparse.Map2To(rsparse, bsparse, (u, v) => u + v + 1.0, Zeros.AllowSkip); - Assert.That(rsparse.Equals(expected), "sparse*sparse->sparse"); - } - } -} diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 31dbc0b7..8afdf751 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -152,6 +152,7 @@ + @@ -350,7 +351,7 @@ - +