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 @@
+