From 8af9880a0c198e54b7078983b24e63c3d72ad9e4 Mon Sep 17 00:00:00 2001 From: David Prince Date: Mon, 24 Mar 2014 22:33:53 +0800 Subject: [PATCH] - Added unit tests file for Triangular distribution (TriangularTests.cs). - Added some unit tests for Triangular distribution, using BetaTests.cs as a template. There are still more unit tests to bring over from BetaTests.cs. - (fixed) Triangular dist's static sample methods weren't declared as static. * To fix: Three of the existing tests are still failing. --- src/Numerics/Distributions/Triangular.cs | 8 +- .../Continuous/TriangularTests.cs | 203 ++++++++++++++++++ src/UnitTests/UnitTests.csproj | 1 + 3 files changed, 208 insertions(+), 4 deletions(-) create mode 100644 src/UnitTests/DistributionTests/Continuous/TriangularTests.cs diff --git a/src/Numerics/Distributions/Triangular.cs b/src/Numerics/Distributions/Triangular.cs index dcfd8061..3a27b3ab 100644 --- a/src/Numerics/Distributions/Triangular.cs +++ b/src/Numerics/Distributions/Triangular.cs @@ -388,7 +388,7 @@ namespace MathNet.Numerics.Distributions /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper /// a sample from the distribution. - public double Sample(System.Random rnd, double lower, double upper, double mode) + public static double Sample(System.Random rnd, double lower, double upper, double mode) { var a = lower; var b = upper; @@ -408,7 +408,7 @@ namespace MathNet.Numerics.Distributions /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper /// a sequence of samples from the distribution. - public IEnumerable Samples(System.Random rnd, double lower, double upper, double mode) + public static IEnumerable Samples(System.Random rnd, double lower, double upper, double mode) { while (true) { @@ -423,7 +423,7 @@ namespace MathNet.Numerics.Distributions /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper /// a sample from the distribution. - public double Sample(double lower, double upper, double mode) + public static double Sample(double lower, double upper, double mode) { return Sample(SystemRandomSource.Default, lower, upper, mode); } @@ -435,7 +435,7 @@ namespace MathNet.Numerics.Distributions /// Upper bound. Range: lower ≤ mode ≤ upper /// Mode (most frequent value). Range: lower ≤ mode ≤ upper /// a sequence of samples from the distribution. - public IEnumerable Samples(double lower, double upper, double mode) + public static IEnumerable Samples(double lower, double upper, double mode) { return Samples(SystemRandomSource.Default, lower, upper, mode); } diff --git a/src/UnitTests/DistributionTests/Continuous/TriangularTests.cs b/src/UnitTests/DistributionTests/Continuous/TriangularTests.cs new file mode 100644 index 00000000..d196e2ef --- /dev/null +++ b/src/UnitTests/DistributionTests/Continuous/TriangularTests.cs @@ -0,0 +1,203 @@ +// +// 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.Linq; +using MathNet.Numerics.Distributions; +using NUnit.Framework; + +namespace MathNet.Numerics.UnitTests.DistributionTests.Continuous +{ + using Random = System.Random; + + /// + /// Triangular distribution tests. + /// + [TestFixture, Category("Distributions")] + public class TriangularTests + { + /// + /// Can create Triangular distribution. + /// + /// Lower Bound. + /// Upper Bound. + /// Mode. + [TestCase(0.0, 0.0, 0.0)] + [TestCase(-1.0, 1.0, 0.0)] + [TestCase(1.0, 2.0, 1.0)] + [TestCase(5.0, 25.0, 25.0)] + [TestCase(1.0e-5, 1.0e5, 1.0e-3)] + [TestCase(0.0, 1.0, 0.9)] + [TestCase(-4.0, -0.5, -2.0)] + [TestCase(-13.039, 8.42, 1.17)] + public void CanCreateTriangular(double lower, double upper, double mode) + { + var n = new Triangular(lower, upper, mode); + Assert.AreEqual(lower, n.LowerBound); + Assert.AreEqual(upper, n.UpperBound); + Assert.AreEqual(mode, n.Mode); + } + + /// + /// Triangular create fails with bad parameters. + /// + //[TestCase(0.0, 0.1, 0.6)] // Todo: Split this test into separate test cases (and do the same in BetaTests.cs). + [Test] + public void TriangularCreateFailsWithBadParameters() + { + Assert.That(() => new Triangular(0.0, 1.0, -0.1), Throws.ArgumentException); + Assert.That(() => new Triangular(0.0, 1.0, 1.1), Throws.ArgumentException); + Assert.That(() => new Triangular(0.0, -1.0, 0.5), Throws.ArgumentException); + Assert.That(() => new Triangular(2.0, 1.0, 1.5), Throws.ArgumentException); + Assert.That(() => new Triangular(Double.NaN, 1.0, 0.5), Throws.ArgumentException); + Assert.That(() => new Triangular(0.2, Double.NaN, 0.5), Throws.ArgumentException); + Assert.That(() => new Triangular(0.5, 1.0, Double.NaN), Throws.ArgumentException); + Assert.That(() => new Triangular(Double.NaN, Double.NaN, Double.NaN), Throws.ArgumentException); + Assert.That(() => new Triangular(Double.NegativeInfinity, 1.0, 0.5), Throws.ArgumentException); + Assert.That(() => new Triangular(0.0, Double.PositiveInfinity, 0.5), Throws.ArgumentException); + } + + /// + /// Validate to string. + /// + [Test] + public void ValidateToString() + { + var n = new Triangular(0d, 2d, 1d); + Assert.AreEqual("Triangular(Lower = 0, Upper = 2, Mode = 1)", n.ToString()); + } + + /// + /// Can Set Lower Bound + /// + /// New Lower Bound. + [TestCase(-0.0)] + [TestCase(0.0)] + [TestCase(0.1)] + [TestCase(1.0)] + [TestCase(10.0)] + public void CanSetLowerBound(double lower) + { + new Triangular(0.0, 20.0, 10.0) + { + LowerBound = lower + }; + } + + /// + /// Set LowerBound fails if greater than Mode. + /// + [TestCase(1.0, 0.5)] + [TestCase(Double.PositiveInfinity, 0.5)] + public void SetLowerBoundFailsIfGreaterThanMode(double lower, double mode) + { + var n = new Triangular(0.0, 100.0, mode); + Assert.That(() => n.LowerBound = lower, Throws.ArgumentException); + } + + // Todo: Add tests for setting upper bound and mode values. + + // Todo: Add tests for: + // - Mean, + // - Entropy, + // - Skewness, + // - Mode (note: Mode is an input parameter for this distribution), + // - Median + // - Minimum (should be the same as LowerBound) + // - Maximum (should be the same as UpperBound) + + /// + /// Can sample static. + /// + [Test] + public void CanSampleStatic() + { + Triangular.Sample(new Random(0), 2.0, 3.0, 2.5); + Triangular.Sample(10.0, 100.0, 30.0); + } + + /// + /// Can sample sequence static. + /// + [Test] + public void CanSampleSequenceStatic() + { + var ied = Triangular.Samples(new Random(0), 2.0, 3.0, 2.5); + ied.Take(5).ToArray(); + ied = Triangular.Samples(10.0, 100.0, 30.0); + ied.Take(5).ToArray(); + } + + /// + /// Fail sample static with wrong parameters. + /// + [Test] + public void FailSampleStatic() + { + Assert.That(() => Triangular.Sample(new Random(0), 1.0, -1.0, 0.1), Throws.ArgumentException); + } + + /// + /// Fail sample sequence static with wrong parameters. + /// + [Test] + public void FailSampleSequenceStatic() + { + Assert.That(() => Triangular.Samples(new Random(0), 1.0, -1.0, 0.1).First(), Throws.ArgumentException); + } + + /// + /// Can sample. + /// + [Test] + public void CanSample() + { + var n = new Triangular(0.1, 0.3, 0.2); + n.Sample(); + } + + /// + /// Can sample sequence. + /// + [Test] + public void CanSampleSequence() + { + var n = new Triangular(0.1, 0.3, 0.2); + var ied = n.Samples(); + ied.Take(5).ToArray(); + } + + // Todo: Add tests for: + // - Density + // - DensityLn + // - Cumulative Dist. + // - Inverse Cumulative Dist. + } +} diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 66b8fcb8..9dba09e9 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -110,6 +110,7 @@ +