4
4
// http://github.com/mathnet/mathnet-numerics
5
5
// http://mathnetnumerics.codeplex.com
6
6
//
7
- // Copyright (c) 2009-2013 Math.NET
7
+ // Copyright (c) 2009-2015 Math.NET
8
8
//
9
9
// Permission is hereby granted, free of charge, to any person
10
10
// obtaining a copy of this software and associated documentation
@@ -42,24 +42,27 @@ namespace MathNet.Numerics.Distributions {
42
42
/// </summary>
43
43
public class TruncatedNormal : IContinuousDistribution
44
44
{
45
-
46
45
System . Random _random ;
47
46
48
47
/// <summary>
49
48
/// Mean of the untruncated normal distribution.
50
49
/// </summary>
51
- readonly double _mu ;
50
+ readonly double _mu ;
51
+
52
52
/// <summary>
53
53
/// Standard deviation of the uncorrected normal distribution.
54
54
/// </summary>
55
55
readonly double _sigma ;
56
+
56
57
readonly double _lowerBound ;
57
58
readonly double _upperBound ;
58
59
readonly Normal _standardNormal = new Normal ( 0.0 , 1.0 ) ;
60
+
59
61
/// <summary>
60
62
/// Position in the standard normal distribution of the lower bound.
61
63
/// </summary>
62
64
readonly double _alpha ;
65
+
63
66
/// <summary>
64
67
/// Position in the standard normal distribution of the upper bound.
65
68
/// </summary>
@@ -73,18 +76,17 @@ public class TruncatedNormal : IContinuousDistribution
73
76
74
77
/// <summary>
75
78
/// Initializes a new instance of the TruncatedNormal class. The distribution will
76
- /// be initialized with the default <seealso cref="System.Random"/> random number generator. The mean
79
+ /// be initialized with the default <seealso cref="System.Random"/> random number generator. The mean
77
80
/// and standard deviation are that of the untruncated normal distribution.
78
81
/// </summary>
79
82
/// <param name="mean">The mean (μ) of the untruncated distribution.</param>
80
83
/// <param name="stddev">The standard deviation (σ) of the untruncated distribution. Range: σ > 0.</param>
81
84
/// <param name="lowerBound">The inclusive lower bound of the truncated distribution. Default is double.NegativeInfinity.</param>
82
85
/// <param name="upperBound">The inclusive upper bound of the truncated distribution. Must be larger than <paramref name="lowerBound"/>.
83
86
/// Default is double.PositiveInfinity.</param>
84
- public TruncatedNormal ( double mean , double stddev , double lowerBound = double . NegativeInfinity , double upperBound = double . PositiveInfinity )
85
- : this ( mean , stddev , SystemRandomSource . Default , lowerBound , upperBound )
87
+ public TruncatedNormal ( double mean , double stddev , double lowerBound = double . NegativeInfinity , double upperBound = double . PositiveInfinity )
88
+ : this ( mean , stddev , SystemRandomSource . Default , lowerBound , upperBound )
86
89
{
87
-
88
90
}
89
91
90
92
/// <summary>
@@ -98,9 +100,9 @@ public TruncatedNormal(double mean, double stddev, double lowerBound = double.Ne
98
100
/// <param name="upperBound">The inclusive upper bound of the truncated distribution. Must be larger than <paramref name="lowerBound"/>.
99
101
/// Default is double.PositiveInfinity.</param>
100
102
101
- public TruncatedNormal ( double untruncatedMean , double untruncatedStdDev , System . Random randomSource , double lowerBound = double . NegativeInfinity , double upperBound = double . PositiveInfinity )
103
+ public TruncatedNormal ( double untruncatedMean , double untruncatedStdDev , System . Random randomSource , double lowerBound = double . NegativeInfinity , double upperBound = double . PositiveInfinity )
102
104
{
103
- if ( ! IsValidParameterSet ( untruncatedMean , untruncatedStdDev , lowerBound , upperBound ) )
105
+ if ( ! IsValidParameterSet ( untruncatedMean , untruncatedStdDev , lowerBound , upperBound ) )
104
106
{
105
107
throw new ArgumentException ( Resources . InvalidDistributionParameters ) ;
106
108
}
@@ -121,23 +123,24 @@ public TruncatedNormal(double untruncatedMean, double untruncatedStdDev, System.
121
123
/// </summary>
122
124
/// <param name="mean">The mean (μ) of the normal distribution.</param>
123
125
/// <param name="stddev">The standard deviation (σ) of the normal distribution. Range: σ > 0.</param>
124
- public static bool IsValidParameterSet ( double mean , double stddev , double lowerBound , double upperBound )
126
+ public static bool IsValidParameterSet ( double mean , double stddev , double lowerBound , double upperBound )
125
127
{
126
128
bool normalRequirements = Normal . IsValidParameterSet ( mean , stddev ) && stddev > 0 ;
127
129
bool boundsAreOrdered = lowerBound < upperBound ;
128
130
return normalRequirements && boundsAreOrdered ;
129
131
}
130
132
131
- public override string ToString ( ) {
133
+ public override string ToString ( )
134
+ {
132
135
return "TruncatedNormal(μ = " + _mu + ", σ = " + _sigma + ", LowerBound = " + _lowerBound + ", UpperBound = " + _upperBound + ")" ;
133
136
}
134
137
135
- /// <summary>
136
- /// Gets the mode of the normal distribution.
137
- /// </summary>
138
- public double Mode
138
+ /// <summary>
139
+ /// Gets the mode of the truncated normal distribution.
140
+ /// </summary>
141
+ public double Mode
139
142
{
140
- get
143
+ get
141
144
{
142
145
if ( _mu < _lowerBound )
143
146
return _lowerBound ;
@@ -150,25 +153,25 @@ public double Mode
150
153
/// <summary>
151
154
/// Gets the minimum of the truncated normal distribution.
152
155
/// </summary>
153
- public double Minimum
156
+ public double Minimum
154
157
{
155
158
get { return _lowerBound ; }
156
159
}
157
160
158
161
/// <summary>
159
162
/// Gets the maximum of the truncated normal distribution.
160
163
/// </summary>
161
- public double Maximum
164
+ public double Maximum
162
165
{
163
166
get { return _upperBound ; }
164
167
}
165
168
166
169
/// <summary>
167
170
/// Gets the mean (μ) of the truncated normal distribution.
168
171
/// </summary>
169
- public double Mean
172
+ public double Mean
170
173
{
171
- get
174
+ get
172
175
{
173
176
var pdfDifference = _standardNormal . Density ( _alpha ) - _standardNormal . Density ( _beta ) ;
174
177
var diffFromUncorrected = pdfDifference * _sigma / _cumulativeDensityWithinBounds ;
@@ -177,11 +180,11 @@ public double Mean
177
180
}
178
181
179
182
/// <summary>
180
- /// Gets the variance of the truncated normal distribution.
183
+ /// Gets the variance of the truncated normal distribution.
181
184
/// </summary>
182
- public double Variance
185
+ public double Variance
183
186
{
184
- get
187
+ get
185
188
{
186
189
//Apparently "Barr and Sherrill (1999)" has a simpler expression for one sided truncations, if anyone has access...
187
190
@@ -209,17 +212,17 @@ public double Variance
209
212
/// <summary>
210
213
/// Gets the standard deviation (σ) of the truncated normal distribution. Range: σ > 0.
211
214
/// </summary>
212
- public double StdDev
215
+ public double StdDev
213
216
{
214
217
get { return Math . Sqrt ( Variance ) ; }
215
218
}
216
219
217
220
/// <summary>
218
221
/// Gets the entropy of the truncated normal distribution.
219
222
/// </summary>
220
- public double Entropy
223
+ public double Entropy
221
224
{
222
- get
225
+ get
223
226
{
224
227
var firstTerm = Constants . LogSqrt2PiE + Math . Log ( _sigma + _cumulativeDensityWithinBounds ) ;
225
228
@@ -232,7 +235,7 @@ public double Entropy
232
235
233
236
public double Skewness
234
237
{
235
- get
238
+ get
236
239
{
237
240
throw new NotImplementedException ( ) ;
238
241
}
@@ -241,9 +244,9 @@ public double Skewness
241
244
/// <summary>
242
245
/// Gets the median of the truncated distribution.
243
246
/// </summary>
244
- public double Median
247
+ public double Median
245
248
{
246
- get
249
+ get
247
250
{
248
251
return InverseCumulativeDistribution ( 0.5 ) ;
249
252
}
@@ -252,7 +255,7 @@ public double Median
252
255
/// <summary>
253
256
/// Gets or sets the random number generator which is used to draw random samples.
254
257
/// </summary>
255
- public System . Random RandomSource
258
+ public System . Random RandomSource
256
259
{
257
260
get { return _random ; }
258
261
set { _random = value ?? SystemRandomSource . Default ; }
@@ -264,7 +267,7 @@ public System.Random RandomSource
264
267
/// <param name="x">The location at which to compute the density.</param>
265
268
/// <returns>the density at <paramref name="x"/>.</returns>
266
269
/// <seealso cref="PDF"/>
267
- public double Density ( double x )
270
+ public double Density ( double x )
268
271
{
269
272
if ( x < _lowerBound || _upperBound < x )
270
273
return 0d ;
@@ -278,29 +281,30 @@ public double Density(double x)
278
281
/// <param name="x">The location at which to compute the log density.</param>
279
282
/// <returns>the log density at <paramref name="x"/>.</returns>
280
283
/// <seealso cref="PDFLn"/>
281
- public double DensityLn ( double x )
284
+ public double DensityLn ( double x )
282
285
{
283
286
return _standardNormal . DensityLn ( ( x - _mu ) / _sigma ) - Math . Log ( _sigma ) - Math . Log ( _cumulativeDensityWithinBounds ) ;
284
- }
287
+ }
285
288
286
-
287
- public double Sample ( )
289
+ public double Sample ( )
288
290
{
289
291
//TODO: implement sampling more efficiently/accurately, use method described by Mazet here: http://miv.u-strasbg.fr/mazet/rtnorm/
290
292
// see implementations listed on that page for examples.
291
293
return InverseCumulativeDistribution ( RandomSource . NextDouble ( ) ) ;
292
294
}
293
295
294
- public void Samples ( double [ ] values )
296
+ public void Samples ( double [ ] values )
295
297
{
296
- for ( int i = 0 ; i < values . Length ; i ++ ) {
298
+ for ( int i = 0 ; i < values . Length ; i ++ )
299
+ {
297
300
values [ i ] = Sample ( ) ;
298
301
}
299
302
}
300
303
301
- public IEnumerable < double > Samples ( )
304
+ public IEnumerable < double > Samples ( )
302
305
{
303
- while ( true ) {
306
+ while ( true )
307
+ {
304
308
yield return Sample ( ) ;
305
309
}
306
310
}
@@ -311,7 +315,7 @@ public IEnumerable<double> Samples()
311
315
/// <param name="x">The location at which to compute the cumulative distribution function.</param>
312
316
/// <returns>the cumulative distribution at location <paramref name="x"/>.</returns>
313
317
/// <seealso cref="CDF"/>
314
- public double CumulativeDistribution ( double x )
318
+ public double CumulativeDistribution ( double x )
315
319
{
316
320
if ( x < _lowerBound )
317
321
return 0d ;
@@ -329,13 +333,12 @@ public double CumulativeDistribution(double x)
329
333
/// <param name="p">The location at which to compute the inverse cumulative density.</param>
330
334
/// <returns>the inverse cumulative density at <paramref name="p"/>.</returns>
331
335
/// <seealso cref="InvCDF"/>
332
- public double InverseCumulativeDistribution ( double p )
336
+ public double InverseCumulativeDistribution ( double p )
333
337
{
334
338
//TODO check that this is correct with someone.
335
339
var pUntruncated = p * _cumulativeDensityWithinBounds + _standardNormal . CumulativeDistribution ( _alpha ) ;
336
340
337
341
return _standardNormal . InverseCumulativeDistribution ( pUntruncated ) * _sigma + _mu ;
338
342
}
339
-
340
343
}
341
344
}
0 commit comments