diff --git a/src/FSharp/Main.fs b/src/FSharp/Main.fs index 0afbd4b8..55e2ac23 100644 --- a/src/FSharp/Main.fs +++ b/src/FSharp/Main.fs @@ -34,7 +34,7 @@ open MathNet.Numerics.LinearAlgebra.Double module FSharp = /// Construct a dense matrix from a list of floating point numbers. - let inline matrix (lst: list>) = DenseMatrix.of_list lst :> Matrix + //let inline matrix (lst: list>) = DenseMatrix.of_list lst :> Matrix /// Construct a dense vector from a list of floating point numbers. let inline vector (lst: list) = DenseVector.of_list lst :> Vector \ No newline at end of file diff --git a/src/FSharpUnitTests/Program.fs b/src/FSharpUnitTests/Program.fs index c088b4e4..e73ad1aa 100644 --- a/src/FSharpUnitTests/Program.fs +++ b/src/FSharpUnitTests/Program.fs @@ -23,57 +23,6 @@ let DenseVectorTests = spec "DenseVector.range" (DenseVector.range 0 99 |> should equal (new DenseVector( [| for i in 0 .. 99 -> float i |] ) )) ] - - -/// Unit tests for the matrix type. -let MatrixTests = - - /// A small uniform vector. - let smallM = new DenseMatrix( Array2D.create 2 2 0.3 ) - - /// A large vector with increasingly large entries - let largeM = new DenseMatrix( Array2D.init 100 100 (fun i j -> float i * 100.0 + float j) ) - - specs "Matrix" [ - spec "Matrix.fold" - (Matrix.fold (fun a b -> a + b) 0.0 smallM |> should equal 1.2) - spec "Matrix.foldi" - (Matrix.foldi (fun i j acc x -> acc + x + float (i+j)) 0.0 smallM |> should equal 5.2) - spec "Matrix.toArray2" - (Matrix.toArray2 smallM |> should equal (Array2D.create 2 2 0.3)) - spec "Matrix.forall" - (Matrix.forall (fun x -> x = 0.3) smallM |> should equal true) - spec "Matrix.exists" - (Matrix.exists (fun x -> x = 0.5) smallM |> should equal false) - spec "Matrix.foralli" - (Matrix.foralli (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) - spec "Matrix.existsi" - (Matrix.existsi (fun i j x -> x = float i * 100.0 + float j) largeM |> should equal true) - spec "Matrix.map" - (Matrix.map (fun x -> 2.0 * x) smallM |> should equal (2.0 * smallM)) - spec "Matrix.mapi" - (Matrix.mapi (fun i j x -> float i * 100.0 + float j + x) largeM |> should equal (2.0 * largeM)) - spec "Matrix.inplaceAssign" - ( let N = smallM.Clone() - Matrix.inplaceAssign (fun i j -> 0.0) N - N |> should equal (0.0 * smallM)) - spec "Matrix.inplaceMapi" - ( let N = largeM.Clone() - Matrix.inplaceMapi (fun i j x -> 2.0 * (float i * 100.0 + float j) + x) N - N |> should equal (3.0 * largeM)) - spec "Matrix.nonZeroEntries" - (Seq.length (Matrix.nonZeroEntries smallM) |> should equal 4) - spec "Matrix.sum" - (Matrix.sum smallM |> should equal 1.2) - spec "Matrix.foldCol" - (Matrix.foldCol (+) 0.0 largeM 0 |> should equal 495000.0) - spec "Matrix.foldRow" - (Matrix.foldRow (+) 0.0 largeM 0 |> should equal 4950.0) - spec "Matrix.foldByCol" - (Matrix.foldByCol (+) 0.0 smallM |> should equal (DenseVector.of_list [0.6;0.6] :> Vector)) - spec "Matrix.foldByRow" - (Matrix.foldByRow (+) 0.0 smallM |> should equal (DenseVector.of_list [0.6;0.6] :> Vector)) - ] /// Report on errors and success and exit. printfn "F# Test Results:" diff --git a/src/Numerics/Distributions/Continuous/LogNormal.cs b/src/Numerics/Distributions/Continuous/LogNormal.cs new file mode 100644 index 00000000..b10f3c93 --- /dev/null +++ b/src/Numerics/Distributions/Continuous/LogNormal.cs @@ -0,0 +1,361 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 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.Distributions +{ + using System; + using System.Collections.Generic; + using Properties; + + /// + /// Implements the univariate Log-Normal distribution. For details about this distribution, see + /// Wikipedia - Log-Normal distribution. + /// + /// The distribution will use the by default. + /// Users can get/set the random number generator by using the property. + /// The statistics classes will check all the incoming parameters whether they are in the allowed + /// range. This might involve heavy computation. Optionally, by setting Control.CheckDistributionParameters + /// to false, all parameter checks can be turned off. + public class LogNormal : IContinuousDistribution + { + /// + /// Keeps track of the mu of the logarithm of the log-log-normal distribution. + /// + private double _mu; + + /// + /// Keeps track of the standard deviation of the logarithm of the log-log-normal distribution. + /// + private double _sigma; + + /// + /// The distribution's random number generator. + /// + private Random _random; + + /// + /// Initializes a new instance of the Log-Normal class. The distribution will + /// be initialized with the default random number generator. + /// + /// The mu of the logarithm of the distribution. + /// The standard deviation of the logarithm of the distribution. + public LogNormal(double mu, double sigma) + { + SetParameters(mu, sigma); + RandomSource = new Random(); + } + + /// + /// A string representation of the distribution. + /// + /// a string representation of the distribution. + public override string ToString() + { + return "LogNormal(Mu = " + _mu + ", Sigma = " + _sigma + ")"; + } + + /// + /// Checks whether the parameters of the distribution are valid. + /// + /// The mu of the logarithm of the distribution. + /// The standard deviation of the logarithm of the distribution. + /// True when the parameters are valid, false otherwise. + private static bool IsValidParameterSet(double mu, double sigma) + { + if (sigma < 0.0 || Double.IsNaN(mu) || Double.IsNaN(mu) || Double.IsNaN(sigma)) + { + return false; + } + + return true; + } + + /// + /// Sets the parameters of the distribution after checking their validity. + /// + /// The mu of the logarithm of the distribution. + /// The standard deviation of the logarithm of the distribution. + /// When the parameters don't pass the function. + private void SetParameters(double mu, double sigma) + { + if (Control.CheckDistributionParameters && !IsValidParameterSet(mu, sigma)) + { + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + } + + _mu = mu; + _sigma = sigma; + } + + /// + /// Gets or sets the mean of the logarithm of the log-normal. + /// + public double Mu + { + get { return _mu; } + + set { SetParameters(value, _sigma); } + } + + /// + /// Gets or sets the standard deviation of the logarithm of the log-normal. + /// + public double Sigma + { + get { return _sigma; } + + set { SetParameters(_mu, value); } + } + + #region IDistribution implementation + + /// + /// Gets or sets the random number generator which is used to draw random samples. + /// + public Random RandomSource + { + get + { + return _random; + } + + set + { + if (value == null) + { + throw new ArgumentNullException(); + } + + _random = value; + } + } + + /// + /// Gets the mu of the log-normal distribution. + /// + public double Mean + { + get { return Math.Exp(_mu + _sigma * _sigma / 2.0); } + } + + /// + /// Gets the variance of the log-normal distribution. + /// + public double Variance + { + get + { + double sigma2 = _sigma * _sigma; + return (Math.Exp(sigma2) - 1.0) * Math.Exp(_mu + _mu + sigma2); + } + } + + /// + /// Gets the standard deviation of the log-normal distribution. + /// + public double StdDev + { + get + { + double sigma2 = _sigma * _sigma; + return Math.Sqrt((Math.Exp(sigma2) - 1.0) * Math.Exp(_mu + _mu + sigma2)); + } + } + + /// + /// Gets the entropy of the log-normal distribution. + /// + public double Entropy + { + get { return 0.5 + Math.Log(_sigma) + _mu + Constants.LogSqrt2Pi; } + } + + /// + /// Gets the skewness of the log-normal distribution. + /// + public double Skewness + { + get + { + double expsigma2 = Math.Exp(_sigma * _sigma); + return (expsigma2 + 2.0) * Math.Sqrt(expsigma2 - 1); + } + } + #endregion + + #region IContinuousDistribution implementation + + /// + /// Gets the mode of the log-normal distribution. + /// + public double Mode + { + get { return Math.Exp(_mu - _sigma * _sigma); } + } + + /// + /// Gets the median of the log-normal distribution. + /// + public double Median + { + get { return Math.Exp(_mu); } + } + + /// + /// Gets the minimum of the log-normal distribution. + /// + public double Minimum + { + get { return 0.0; } + } + + /// + /// Gets the maximum of the log-normal distribution. + /// + public double Maximum + { + get { return Double.PositiveInfinity; } + } + + /// + /// Computes the density of the log-normal distribution. + /// + /// The location at which to compute the density. + /// the density at . + public double Density(double x) + { + if (x < 0.0) + { + return 0.0; + } + + double a = (Math.Log(x) - _mu) / _sigma; + return Math.Exp(-0.5 * a * a) / (x * _sigma * Constants.Sqrt2Pi); + } + + /// + /// Computes the log density of the log-normal distribution. + /// + /// The location at which to compute the log density. + /// the log density at . + public double DensityLn(double x) + { + if (x < 0.0) + { + return Double.NegativeInfinity; + } + + double a = (Math.Log(x) - _mu) / _sigma; + return -0.5 * a * a - Math.Log(x * _sigma) - Constants.LogSqrt2Pi; + } + + /// + /// Computes the cumulative distribution function of the log-normal distribution. + /// + /// The location at which to compute the cumulative density. + /// the cumulative density at . + public double CumulativeDistribution(double x) + { + if (x < 0.0) + { + return 0.0; + } + + return 0.5 * (1.0 + SpecialFunctions.Erf((Math.Log(x) - _mu) / (_sigma * Constants.Sqrt2))); + } + + /// + /// Generates a sample from the log-normal distribution using the Box-Muller algorithm. + /// + /// a sample from the distribution. + public double Sample() + { + double r2; + return Math.Exp(_mu + (_sigma * Normal.SampleBoxMuller(RandomSource, out r2))); + } + + /// + /// Generates a sequence of samples from the log-normal distribution using the Box-Muller algorithm. + /// + /// a sequence of samples from the distribution. + public IEnumerable Samples() + { + double r2; + + while (true) + { + double r1 = Normal.SampleBoxMuller(RandomSource, out r2); + yield return Math.Exp(_mu + (_sigma * r1)); + yield return Math.Exp(_mu + (_sigma * r2)); + } + } + #endregion + + /// + /// Generates a sample from the log-normal distribution using the Box-Muller algorithm. + /// + /// The random number generator to use. + /// The mu of the logarithm of the distribution. + /// The standard deviation of the logarithm of the distribution. + /// a sample from the distribution. + public static double Sample(Random rng, double mu, double sigma) + { + if (Control.CheckDistributionParameters && !IsValidParameterSet(mu, sigma)) + { + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + } + + double r2; + return Math.Exp(mu + (sigma * Normal.SampleBoxMuller(rng, out r2))); + } + + /// + /// Generates a sequence of samples from the log-normal distribution using the Box-Muller algorithm. + /// + /// The random number generator to use. + /// The mu of the logarithm of the distribution. + /// The standard deviation of the logarithm of the distribution. + /// a sequence of samples from the distribution. + public static IEnumerable Samples(Random rng, double mu, double sigma) + { + if (Control.CheckDistributionParameters && !IsValidParameterSet(mu, sigma)) + { + throw new ArgumentOutOfRangeException(Resources.InvalidDistributionParameters); + } + + double r2; + + while (true) + { + double r1 = Normal.SampleBoxMuller(rng, out r2); + yield return Math.Exp(mu + (sigma * r1)); + yield return Math.Exp(mu + (sigma * r2)); + } + } + } +} diff --git a/src/Numerics/Numerics.csproj b/src/Numerics/Numerics.csproj index 52b1c4ba..c7103461 100644 --- a/src/Numerics/Numerics.csproj +++ b/src/Numerics/Numerics.csproj @@ -53,6 +53,7 @@ + diff --git a/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs b/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs new file mode 100644 index 00000000..c6c6a0ae --- /dev/null +++ b/src/UnitTests/DistributionTests/Continuous/LogNormalTests.cs @@ -0,0 +1,431 @@ +// +// Math.NET Numerics, part of the Math.NET Project +// http://mathnet.opensourcedotnet.info +// +// Copyright (c) 2009 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.DistributionTests +{ + using System; + using System.Linq; + using MbUnit.Framework; + using MathNet.Numerics.Distributions; + + [TestFixture] + public class LogNormalTests + { + [SetUp] + public void SetUp() + { + Control.CheckDistributionParameters = true; + } + + [Test, MultipleAsserts] + [Row(0.0, 0.0)] + [Row(0.0, 0.1)] + [Row(0.0, 1.0)] + [Row(0.0, 10.0)] + [Row(10.0, 1.0)] + [Row(-5.0, 100.0)] + [Row(0.0, Double.PositiveInfinity)] + public void CanCreateLogNormal(double mu, double sigma) + { + var n = new LogNormal(mu, sigma); + AssertEx.AreEqual(mu, n.Mu); + AssertEx.AreEqual(sigma, n.Sigma); + } + + [Test] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + [Row(Double.NaN, 1.0)] + [Row(1.0, Double.NaN)] + [Row(Double.NaN, Double.NaN)] + [Row(1.0, -1.0)] + public void LogNormalCreateFailsWithBadParameters(double mu, double sigma) + { + var n = new LogNormal(mu, sigma); + } + + [Test] + public void ValidateToString() + { + var n = new LogNormal(1.0, 2.0); + AssertEx.AreEqual("LogNormal(Mu = 1, Sigma = 2)", n.ToString()); + } + + [Test] + [Row(-0.0)] + [Row(0.0)] + [Row(0.1)] + [Row(1.0)] + [Row(10.0)] + [Row(Double.PositiveInfinity)] + public void CanSetSigma(double sigma) + { + var n = new LogNormal(1.0, 2.0); + n.Sigma = sigma; + } + + [Test] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void SetSigmaFailsWithNegativeSigma() + { + var n = new LogNormal(1.0, 2.0); + n.Sigma = -1.0; + } + + [Test] + [Row(Double.NegativeInfinity)] + [Row(-1.0)] + [Row(-0.0)] + [Row(0.0)] + [Row(0.1)] + [Row(1.0)] + [Row(10.0)] + [Row(Double.PositiveInfinity)] + public void CanSetMu(double mu) + { + var n = new LogNormal(1.0, 2.0); + n.Mu = mu; + } + + [Test] + [Row(-1.000000, 0.100000, -1.8836465597893728867265104870209210873020761202386)] + [Row(-1.000000, 1.500000, 0.82440364131283712375834285186996677643338789710028)] + [Row(-1.000000, 2.500000, 1.335229265078827806963856948173628711311498693546)] + [Row(-1.000000, 5.500000, 2.1236866254430979764250411929125703716076041932149)] + [Row(-0.100000, 0.100000, -0.9836465597893728922776256101467037894202344606927)] + [Row(-0.100000, 1.500000, 1.7244036413128371182072277287441840743152295566462)] + [Row(-0.100000, 2.500000, 2.2352292650788278014127418250478460091933403530919)] + [Row(-0.100000, 5.500000, 3.0236866254430979708739260697867876694894458527608)] + [Row(0.100000, 0.100000, -0.7836465597893728811753953638951383851839177797845)] + [Row(0.100000, 1.500000, 1.9244036413128371293094579749957494785515462375544)] + [Row(0.100000, 2.500000, 2.4352292650788278125149720712994114134296570340001)] + [Row(0.100000, 5.500000, 3.223686625443097981976156316038353073725762533669)] + [Row(1.500000, 0.100000, 0.6163534402106271132734895129790789126979238797614)] + [Row(1.500000, 1.500000, 3.3244036413128371237583428518699667764333878971003)] + [Row(1.500000, 2.500000, 3.835229265078827806963856948173628711311498693546)] + [Row(1.500000, 5.500000, 4.6236866254430979764250411929125703716076041932149)] + [Row(2.500000, 0.100000, 1.6163534402106271132734895129790789126979238797614)] + [Row(2.500000, 1.500000, 4.3244036413128371237583428518699667764333878971003)] + [Row(2.500000, 2.500000, 4.835229265078827806963856948173628711311498693546)] + [Row(2.500000, 5.500000, 5.6236866254430979764250411929125703716076041932149)] + [Row(5.500000, 0.100000, 4.6163534402106271132734895129790789126979238797614)] + [Row(5.500000, 1.500000, 7.3244036413128371237583428518699667764333878971003)] + [Row(5.500000, 2.500000, 7.835229265078827806963856948173628711311498693546)] + [Row(5.500000, 5.500000, 8.6236866254430979764250411929125703716076041932149)] + [Row(3.0, 0.0, System.Double.NegativeInfinity)] + public void ValidateEntropy(double mu, double sigma, double entropy) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(entropy, n.Entropy, 14); + } + + [Test] + [Row(-1.000000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(-1.000000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(-1.000000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(-1.000000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + [Row(-0.100000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(-0.100000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(-0.100000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(-0.100000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + [Row(0.100000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(0.100000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(0.100000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(0.100000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + [Row(1.500000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(1.500000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(1.500000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(1.500000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + [Row(2.500000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(2.500000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(2.500000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(2.500000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + [Row(5.500000, 0.100000, 0.30175909933883402945387113824982918009810212213629)] + [Row(5.500000, 1.500000, 33.46804679732172529147579024311650645764144530123)] + [Row(5.500000, 2.500000, 11824.007933610287521341659465200553739278936344799)] + [Row(5.500000, 5.500000, 50829064464591483629.132631635472412625371367420496)] + public void ValidateSkewness(double mu, double sigma, double skewness) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(skewness, n.Skewness, 14); + } + + [Test] + [Row(-1.000000, 0.100000, 0.36421897957152331652213191863106773137983085909534)] + [Row(-1.000000, 1.500000, 0.03877420783172200988689983526759614326014406193602)] + [Row(-1.000000, 2.500000, 0.0007101743888425490635846003705775444086763023873619)] + [Row(-1.000000, 5.500000, 0.000000000000026810038677818032221548731163905979029274677187036)] + [Row(-0.100000, 0.100000, 0.89583413529652823774737070060865897390995185639633)] + [Row(-0.100000, 1.500000, 0.095369162215549610417813418326627245539514227574881)] + [Row(-0.100000, 2.500000, 0.0017467471362611196181003627521060283221112106850165)] + [Row(-0.100000, 5.500000, 0.00000000000006594205454219929159167575814655534255162059017114)] + [Row(0.100000, 0.100000, 1.0941742837052103542285651753780976842292770841345)] + [Row(0.100000, 1.500000, 0.11648415777349696821514223131929465848700730137808)] + [Row(0.100000, 2.500000, 0.0021334817700377079925027678518795817076296484352472)] + [Row(0.100000, 5.500000, 0.000000000000080541807296590798973741710866097756565304960216803)] + [Row(1.500000, 0.100000, 4.4370955190036645692996309927420381428715912422597)] + [Row(1.500000, 1.500000, 0.47236655274101470713804655094326791297020357913648)] + [Row(1.500000, 2.500000, 0.008651695203120634177071503957250390848166331197708)] + [Row(1.500000, 5.500000, 0.00000000000032661313427874471360158184468030186601222739665225)] + [Row(2.500000, 0.100000, 12.061276120444720299113038763305617245808510584994)] + [Row(2.500000, 1.500000, 1.2840254166877414840734205680624364583362808652815)] + [Row(2.500000, 2.500000, 0.023517745856009108236151185100432939470067655273072)] + [Row(2.500000, 5.500000, 0.00000000000088782654784596584473099190326928541185172970391855)] + [Row(5.500000, 0.100000, 242.2572068579541371904816252345031593584721473492)] + [Row(5.500000, 1.500000, 25.790339917193062089080107669377221876655268848954)] + [Row(5.500000, 2.500000, 0.47236655274101470713804655094326791297020357913648)] + [Row(5.500000, 5.500000, 0.000000000017832472908146389493511850431527026413424899198327)] + public void ValidateMode(double mu, double sigma, double mode) + { + var n = new LogNormal(mu, sigma); + AssertEx.AreEqual(mode, n.Mode); + } + + [Test] + [Row(-1.000000, 0.100000, 0.36787944117144232159552377016146086744581113103177)] + [Row(-1.000000, 1.500000, 0.36787944117144232159552377016146086744581113103177)] + [Row(-1.000000, 2.500000, 0.36787944117144232159552377016146086744581113103177)] + [Row(-1.000000, 5.500000, 0.36787944117144232159552377016146086744581113103177)] + [Row(-0.100000, 0.100000, 0.90483741803595956814139238421693559530906465375738)] + [Row(-0.100000, 1.500000, 0.90483741803595956814139238421693559530906465375738)] + [Row(-0.100000, 2.500000, 0.90483741803595956814139238421693559530906465375738)] + [Row(-0.100000, 5.500000, 0.90483741803595956814139238421693559530906465375738)] + [Row(0.100000, 0.100000, 1.1051709180756476309466388234587796577416634163742)] + [Row(0.100000, 1.500000, 1.1051709180756476309466388234587796577416634163742)] + [Row(0.100000, 2.500000, 1.1051709180756476309466388234587796577416634163742)] + [Row(0.100000, 5.500000, 1.1051709180756476309466388234587796577416634163742)] + [Row(1.500000, 0.100000, 4.4816890703380648226020554601192758190057498683697)] + [Row(1.500000, 1.500000, 4.4816890703380648226020554601192758190057498683697)] + [Row(1.500000, 2.500000, 4.4816890703380648226020554601192758190057498683697)] + [Row(1.500000, 5.500000, 4.4816890703380648226020554601192758190057498683697)] + [Row(2.500000, 0.100000, 12.182493960703473438070175951167966183182767790063)] + [Row(2.500000, 1.500000, 12.182493960703473438070175951167966183182767790063)] + [Row(2.500000, 2.500000, 12.182493960703473438070175951167966183182767790063)] + [Row(2.500000, 5.500000, 12.182493960703473438070175951167966183182767790063)] + [Row(5.500000, 0.100000, 244.6919322642203879151889495118393501842287101075)] + [Row(5.500000, 1.500000, 244.6919322642203879151889495118393501842287101075)] + [Row(5.500000, 2.500000, 244.6919322642203879151889495118393501842287101075)] + [Row(5.500000, 5.500000, 244.6919322642203879151889495118393501842287101075)] + public void ValidateMedian(double mu, double sigma, double median) + { + var n = new LogNormal(mu, sigma); + AssertEx.AreEqual(median, n.Median); + } + + [Test] + [Row(-1.000000, 0.100000, 0.36972344454405898424295931933535060663729727450496)] + [Row(-1.000000, 1.500000, 1.1331484530668263168290072278117938725655031317452)] + [Row(-1.000000, 2.500000, 8.3728974881272646632047051583699874196015291437918)] + [Row(-1.000000, 5.500000, 1362729.1842528548177103892815156762190272224157908)] + [Row(-0.100000, 0.100000, 0.90937293446823141948366366799116134283184493055232)] + [Row(-0.100000, 1.500000, 2.7870954605658505209699655454000403395863724001622)] + [Row(-0.100000, 2.500000, 20.594004711196027346218102453235151379866942184579)] + [Row(-0.100000, 5.500000, 3351772.9412526949983798753257651403306685815830315)] + [Row(0.100000, 0.100000, 1.1107106103557052433570611860384876269319432656698)] + [Row(0.100000, 1.500000, 3.4041660827908192886708290528609320712960422205023)] + [Row(0.100000, 2.500000, 25.153574155818364061848601838108180348672588964125)] + [Row(0.100000, 5.500000, 4093864.7151726636524297378613262447736728507467499)] + [Row(1.500000, 0.100000, 4.5041536302884836520306376113128094189800629942172)] + [Row(1.500000, 1.500000, 13.804574186067094919261248628970575865946258844868)] + [Row(1.500000, 2.500000, 102.00277308269968445339478193484494686013688925329)] + [Row(1.500000, 5.500000, 16601440.057234774713918640507932346750889433699096)] + [Row(2.500000, 0.100000, 12.243558965801025772304627735965552181680541950402)] + [Row(2.500000, 1.500000, 37.524723159600998914070697772298569304087527691818)] + [Row(2.500000, 2.500000, 277.27228452313398040814702091277144916631260200421)] + [Row(2.500000, 5.500000, 45127392.833833379992911980630933945681066040228608)] + [Row(5.500000, 0.100000, 245.91845567882191847293631456824227914641401674654)] + [Row(5.500000, 1.500000, 753.70421255456126566058070133948176772966773355511)] + [Row(5.500000, 2.500000, 5569.16270856600407442234466894967473356247174813)] + [Row(5.500000, 5.500000, 906407915.01115491334464289369168840924937330105415)] + public void ValidateMean(double mu, double sigma, double mean) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(mean, n.Mean, 14); + } + + [Test] + public void ValidateMinimum() + { + var n = new LogNormal(1.0, 2.0); + AssertEx.AreEqual(0.0, n.Minimum); + } + + [Test] + public void ValidateMaximum() + { + var n = new LogNormal(1.0, 2.0); + AssertEx.AreEqual(System.Double.PositiveInfinity, n.Maximum); + } + + [Test] + [Row(-0.100000, 0.100000, -0.100000, 0.0)] + [Row(-0.100000, 0.100000, 0.100000, 1.7968349035073582236359415565799753846986440127816e-104)] + [Row(-0.100000, 0.100000, 0.500000, 0.00000018288923328441197822391757965928083462391836798722)] + [Row(-0.100000, 0.100000, 0.800000, 2.3363114904470413709866234247494393485647978367885)] + [Row(-0.100000, 1.500000, 0.100000, 0.90492497850024368541682348133921492204585092983646)] + [Row(-0.100000, 1.500000, 0.500000, 0.49191985207660942803818797602364034466489243416574)] + [Row(-0.100000, 1.500000, 0.800000, 0.33133347214343229148978298237579567194870525187207)] + [Row(-0.100000, 2.500000, 0.100000, 1.0824698632626565182080576574958317806389057196768)] + [Row(-0.100000, 2.500000, 0.500000, 0.31029619474753883558901295436486123689563749784867)] + [Row(-0.100000, 2.500000, 0.800000, 0.19922929916156673799861939824205622734205083805245)] + [Row(1.500000, 0.100000, 0.100000, 4.1070141770545881694056265342787422035256248474059e-313)] + [Row(1.500000, 0.100000, 0.500000, 2.8602688726477103843476657332784045661507239533567e-104)] + [Row(1.500000, 0.100000, 0.800000, 1.6670425710002183246335601541889400558525870482613e-64)] + [Row(1.500000, 1.500000, 0.100000, 0.10698412103361841220076392503406214751353235895732)] + [Row(1.500000, 1.500000, 0.500000, 0.18266125308224685664142384493330155315630876975024)] + [Row(1.500000, 1.500000, 0.800000, 0.17185785323404088913982425377565512294017306418953)] + [Row(1.500000, 2.500000, 0.100000, 0.50186885259059181992025035649158160252576845315332)] + [Row(1.500000, 2.500000, 0.500000, 0.21721369314437986034957451699565540205404697589349)] + [Row(1.500000, 2.500000, 0.800000, 0.15729636000661278918949298391170443742675565300598)] + [Row(2.500000, 0.100000, 0.100000, 5.6836826548848916385760779034504046896805825555997e-500)] + [Row(2.500000, 0.100000, 0.500000, 3.1225608678589488061206338085285607881363155340377e-221)] + [Row(2.500000, 0.100000, 0.800000, 4.6994713794671660918554320071312374073172560048297e-161)] + [Row(2.500000, 1.500000, 0.100000, 0.015806486291412916772431170442330946677601577502353)] + [Row(2.500000, 1.500000, 0.500000, 0.055184331257528847223852028950484131834529030116388)] + [Row(2.500000, 1.500000, 0.800000, 0.063982134749859504449658286955049840393511776984362)] + [Row(2.500000, 2.500000, 0.100000, 0.25212505662402617595900822552548977822542300480086)] + [Row(2.500000, 2.500000, 0.500000, 0.14117186955911792460646517002386088579088567275401)] + [Row(2.500000, 2.500000, 0.800000, 0.11021452580363707866161369621432656293405065561317)] + public void ValidateDensity(double mu, double sigma, double x, double p) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(p, n.Density(x), 14); + } + + [Test] + [Row(-0.100000, 0.100000, -0.100000, Double.NegativeInfinity)] + [Row(-0.100000, 0.100000, 0.100000, -238.88282294119596467794686179588610665317241097599)] + [Row(-0.100000, 0.100000, 0.500000, -15.514385149961296196003163062199569075052113039686)] + [Row(-0.100000, 0.100000, 0.800000, 0.84857339958981283964373051826407417105725729082041)] + [Row(-0.100000, 1.500000, 0.100000, -0.099903235403144611051953094864849327288457482212211)] + [Row(-0.100000, 1.500000, 0.500000, -0.70943947804316122682964396008813828577195771418027)] + [Row(-0.100000, 1.500000, 0.800000, -1.1046299420497998262946038709903250420774183529995)] + [Row(-0.100000, 2.500000, 0.100000, 0.07924534056485078867266307735371665927517517183681)] + [Row(-0.100000, 2.500000, 0.500000, -1.1702279707433794860424967893989374511050637417043)] + [Row(-0.100000, 2.500000, 0.800000, -1.6132988605030400828957768752511536087538109996183)] + [Row(1.500000, 0.100000, 0.100000, -719.29643782024317312262673764204041218720576249741)] + [Row(1.500000, 0.100000, 0.500000, -238.41793403955250272430898754048547661932857086122)] + [Row(1.500000, 0.100000, 0.800000, -146.85439481068371057247137024006716189469284256628)] + [Row(1.500000, 1.500000, 0.100000, -2.2350748570877992856465076624973458117562108140674)] + [Row(1.500000, 1.500000, 0.500000, -1.7001219175524556705452882616787223585705662860012)] + [Row(1.500000, 1.500000, 0.800000, -1.7610875785399045023354101841009649273236721172008)] + [Row(1.500000, 2.500000, 0.100000, -0.68941644324162489418137656699398207513321602763104)] + [Row(1.500000, 2.500000, 0.500000, -1.5268736489667254857801287379715477173125628275598)] + [Row(1.500000, 2.500000, 0.800000, -1.8496236096394777662704671479709839674424623547308)] + [Row(2.500000, 0.100000, 0.100000, -1149.5549471196476523788026360929146688367845019398)] + [Row(2.500000, 0.100000, 0.500000, -507.73265209554698134113704985174959301922196605736)] + [Row(2.500000, 0.100000, 0.800000, -369.16874994210463740474549611573497379941224077335)] + [Row(2.500000, 1.500000, 0.100000, -4.1473348984184862316495477617980296904955324113457)] + [Row(2.500000, 1.500000, 0.500000, -2.8970762200235424747307247601045786110485663457169)] + [Row(2.500000, 1.500000, 0.800000, -2.7491513791239977024488074547907467152956602019989)] + [Row(2.500000, 2.500000, 0.100000, -1.3778300581206721947424710027422282714793718026513)] + [Row(2.500000, 2.500000, 0.500000, -1.9577771978563167352868858774048559682046428490575)] + [Row(2.500000, 2.500000, 0.800000, -2.2053265778497513183112901654193054111123780652581)] + public void ValidateDensityLn(double mu, double sigma, double x, double p) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(p, n.DensityLn(x), 14); + } + + [Test] + public void CanSampleStatic() + { + var d = LogNormal.Sample(new Random(), 0.0, 1.0); + } + + [Test] + public void CanSampleSequenceStatic() + { + var ied = LogNormal.Samples(new Random(), 0.0, 1.0); + var arr = ied.Take(5).ToArray(); + } + + [Test] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void FailSampleStatic() + { + var d = LogNormal.Sample(new Random(), 0.0, -1.0); + } + + [Test] + [ExpectedException(typeof(ArgumentOutOfRangeException))] + public void FailSampleSequenceStatic() + { + var ied = LogNormal.Samples(new Random(), 0.0, -1.0).First(); + } + + [Test] + public void CanSample() + { + var n = new LogNormal(1.0, 2.0); + var d = n.Sample(); + } + + [Test] + public void CanSampleSequence() + { + var n = new LogNormal(1.0, 2.0); + var ied = n.Samples(); + var e = ied.Take(5).ToArray(); + } + + [Test] + [Row(-0.100000, 0.100000, -0.100000, 0.0)] + [Row(-0.100000, 0.100000, 0.100000, 0.0)] + [Row(-0.100000, 0.100000, 0.500000, 0.0000000015011556178148777579869633555518882664666520593658)] + [Row(-0.100000, 0.100000, 0.800000, 0.10908001076375810900224507908874442583171381706127)] + [Row(-0.100000, 1.500000, 0.100000, 0.070999149762464508991968731574953594549291668468349)] + [Row(-0.100000, 1.500000, 0.500000, 0.34626224992888089297789445771047690175505847991946)] + [Row(-0.100000, 1.500000, 0.800000, 0.46728530589487698517090261668589508746353129242404)] + [Row(-0.100000, 2.500000, 0.100000, 0.18914969879695093477606645992572208111152994999076)] + [Row(-0.100000, 2.500000, 0.500000, 0.40622798321378106125020505907901206714868922279347)] + [Row(-0.100000, 2.500000, 0.800000, 0.48035707589956665425068652807400957345208517749893)] + [Row(1.500000, 0.100000, 0.100000, 0.0)] + [Row(1.500000, 0.100000, 0.500000, 0.0)] + [Row(1.500000, 0.100000, 0.800000, 0.0)] + [Row(1.500000, 1.500000, 0.100000, 0.005621455876973168709588070988239748831823850202953)] + [Row(1.500000, 1.500000, 0.500000, 0.07185716187918271235246980951571040808235628115265)] + [Row(1.500000, 1.500000, 0.800000, 0.12532699044614938400496547188720940854423187977236)] + [Row(1.500000, 2.500000, 0.100000, 0.064125647996943514411570834861724406903677144126117)] + [Row(1.500000, 2.500000, 0.500000, 0.19017302281590810871719754032332631806011441356498)] + [Row(1.500000, 2.500000, 0.800000, 0.24533064397555500690927047163085419096928289095201)] + [Row(2.500000, 0.100000, 0.100000, 0.0)] + [Row(2.500000, 0.100000, 0.500000, 0.0)] + [Row(2.500000, 0.100000, 0.800000, 0.0)] + [Row(2.500000, 1.500000, 0.100000, 0.00068304052220788502001572635016579586444611070077399)] + [Row(2.500000, 1.500000, 0.500000, 0.016636862816580533038130583128179878924863968664206)] + [Row(2.500000, 1.500000, 0.800000, 0.034729001282904174941366974418836262996834852343018)] + [Row(2.500000, 2.500000, 0.100000, 0.027363708266690978870139978537188410215717307180775)] + [Row(2.500000, 2.500000, 0.500000, 0.10075543423327634536450625420610429181921642201567)] + [Row(2.500000, 2.500000, 0.800000, 0.13802019192453118732001307556787218421918336849121)] + public void ValidateCumulativeDistribution(double mu, double sigma, double x, double f) + { + var n = new LogNormal(mu, sigma); + AssertHelpers.AlmostEqual(f, n.CumulativeDistribution(x), 8); + } + } +} \ No newline at end of file diff --git a/src/UnitTests/DistributionTests/Multivariate/VectorNormalTests.cs b/src/UnitTests/DistributionTests/Multivariate/VectorNormalTests.cs deleted file mode 100644 index 6371dcaa..00000000 --- a/src/UnitTests/DistributionTests/Multivariate/VectorNormalTests.cs +++ /dev/null @@ -1,213 +0,0 @@ -// -// Math.NET Numerics, part of the Math.NET Project -// http://mathnet.opensourcedotnet.info -// -// Copyright (c) 2009 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.DistributionTests -{ - using System; - using System.Linq; - using MbUnit.Framework; - using MathNet.Numerics.Distributions; - - [TestFixture] - public class VectorNormalTests - { - [SetUp] - public void SetUp() - { - Control.CheckDistributionParameters = true; - } - - //[Test] - //[ExpectedException(typeof(ArgumentOutOfRangeException))] - //public void NormalConstructorFail() - //{ - // Matrix cov = new DenseMatrix(new double[,] { { 1.0, 1.0 }, { -1.0, 2.0 } }); - // Vector mean = new DenseVector(new double[] { 5.0, 5.0 }); - - // // Build a new vector normal distribution. - // VectorNormal normal = new VectorNormal(mean, cov); - //} - - [Test] - public void StandardNormal() - { - VectorNormal normal = new VectorNormal(5); - - // Test the mean. - for (int i = 0; i < 5; i++) - { - Assert.AreEqual(0.0, normal.Mean[i]); - } - - // Test the covariance. - for (int i = 0; i < 5; i++) - { - for (int j = 0; j < 5; j++) - { - if (i == j) - { - Assert.AreEqual(1.0, normal.Covariance[i, j]); - } - else - { - Assert.AreEqual(0.0, normal.Covariance[i, j]); - } - } - } - - // Test the pdf. - Assert.AreEqual(0.010105326013812, normal.Density(new DenseVector(5, 0.0)), mAcceptableError); - Assert.AreEqual(8.294956719377678e-004, normal.Density(new DenseVector(5, 1.0)), mAcceptableError); - - // Test the mode. - for (int i = 0; i < 5; i++) - { - Assert.AreEqual(0.0, normal.Mode[i]); - } - - // Test the median. - for (int i = 0; i < 5; i++) - { - Assert.AreEqual(0.0, normal.Median[i]); - } - - // Test the entropy. - Assert.AreEqual(7.094692666023364, normal.Entropy, mAcceptableError); - } - - [Test] - public void NormalFromCovariance() - { - Matrix cov = new DenseMatrix(new double[,] { { 1.0, 0.9 }, { 0.9, 1.0 } }); - Vector mean = new DenseVector(new double[] { 5.0, 5.0 }); - - // Check that these are valid mean and covariances. - Assert.DoesNotThrow(() => VectorNormal.CheckParameters(mean, cov)); - - // Build a new vector normal distribution. - VectorNormal normal = new VectorNormal(mean, cov); - - // Test the mean. - Assert.AreEqual(5.0, normal.Mean[0]); - Assert.AreEqual(5.0, normal.Mean[1]); - - // Test the covariance. - Assert.AreEqual(1.0, normal.Covariance[0, 0]); - Assert.AreEqual(0.9, normal.Covariance[0, 1]); - Assert.AreEqual(0.9, normal.Covariance[1, 0]); - Assert.AreEqual(1.0, normal.Covariance[1, 1]); - - // Test the mode. - Assert.AreEqual(5.0, normal.Mode[0]); - Assert.AreEqual(5.0, normal.Mode[1]); - - // Test the median. - Assert.AreEqual(5.0, normal.Median[0]); - Assert.AreEqual(5.0, normal.Median[1]); - - // Test the entropy. - Assert.AreEqual(2.007511462998520, normal.Entropy, mAcceptableError); - - // Get the RNG. - System.Random rnd = normal.RandomNumberGenerator; - } - - - - - - - - - [Test] - public void HasRandomSource(int i) - { - VectorNormal d = new VectorNormal(0.3, 5); - Assert.IsNotNull(d.RandomSource); - } - - [Test] - public void CanSetRandomSource(int i) - { - VectorNormal d = new VectorNormal(0.3, 5); - d.RandomSource = new Random(); - } - - [Test] - [ExpectedException(typeof(ArgumentNullException))] - public void FailSetRandomSourceWithNullReference(int i) - { - VectorNormal d = new VectorNormal(0.3, 5); - d.RandomSource = null; - } - - [Test] - public void CanGetDimension() - { - VectorNormal d = new VectorNormal(0.3, 10); - Assert.AreEqual(10, d.Dimension); - } - - [Test] - public void ValidateMean() - { - VectorNormal d = new VectorNormal(0.3, 5); - - for (int i = 0; i < 5; i++) - { - AssertHelpers.AlmostEqual(0.3/1.5, d.Mean[i], 15); - } - } - - [Test] - public void ValidateVariance() - { - double[] alpha = new double[10]; - double sum = 0.0; - for (int i = 0; i < 10; i++) - { - alpha[i] = i; - sum += i; - } - - VectorNormal d = new VectorNormal(alpha); - - for (int i = 0; i < 10; i++) - { - AssertHelpers.AlmostEqual(i * (sum - i) / (sum * sum * (sum + 1.0)), d.Variance[i], 15); - } - } - - [Test] - public void CanSampleVectorNormal() - { - VectorNormal d = new VectorNormal(1.0, 5); - double[] s = d.Sample(); - } - } -} \ No newline at end of file diff --git a/src/UnitTests/UnitTests.csproj b/src/UnitTests/UnitTests.csproj index 67a3b9cd..3799ad3a 100644 --- a/src/UnitTests/UnitTests.csproj +++ b/src/UnitTests/UnitTests.csproj @@ -67,12 +67,12 @@ + -