public TruncatedDistribution(ITruncatableDistribution <double> distribution, double lowerBound, double upperBound) { if (lowerBound > upperBound) { throw new ArgumentOutOfRangeException($"lowerBound ({lowerBound}) > upperBound ({upperBound})"); } this.Distribution = distribution; this.LowerBound = lowerBound; this.UpperBound = upperBound; this.TotalProbability = distribution.GetProbBetween(lowerBound, upperBound); this.LowerProbability = distribution.GetProbLessThan(lowerBound); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="IntegralOp"]/message_doc[@name="UpperBoundAverageConditional(Gaussian, Gaussian, Func{double,double}, ITruncatableDistribution{double})"]/*'/> public static Gaussian UpperBoundAverageConditional(Gaussian integral, [RequiredArgument] Gaussian upperBound, Func <double, double> func, ITruncatableDistribution <double> distribution) { if (upperBound.IsPointMass) { return(UpperBoundAverageConditional(integral, upperBound.Point, func, distribution)); } else { throw new NotSupportedException(); } }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="IntegralOp"]/message_doc[@name="UpperBoundAverageConditional(Gaussian, double, Func{double,double}, ITruncatableDistribution{double})"]/*'/> public static Gaussian UpperBoundAverageConditional(Gaussian integral, double upperBound, Func <double, double> func, ITruncatableDistribution <double> distribution) { CanGetLogProb <double> canGetLogProb = (CanGetLogProb <double>)distribution; double dlogf = integral.MeanTimesPrecision * func(upperBound) * Math.Exp(canGetLogProb.GetLogProb(upperBound)); double ddlogf = 0; // approximation ignoring integral.Precision return(Gaussian.FromDerivatives(upperBound, dlogf, ddlogf, false)); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="IntegralOp"]/message_doc[@name="IntegralAverageConditional(Gaussian, Gaussian, Func{double,double}, ITruncatableDistribution{double})"]/*'/> public static Gaussian IntegralAverageConditional([RequiredArgument] Gaussian lowerBound, [RequiredArgument] Gaussian upperBound, Func <double, double> func, ITruncatableDistribution <double> distribution) { if (lowerBound.IsPointMass && upperBound.IsPointMass) { return(Gaussian.PointMass(Factor.Integral(lowerBound.Point, upperBound.Point, func, distribution))); } else { throw new NotSupportedException(); } }
/// <summary> /// Returns the integral from lowerBound to upperBound of func(x) times p(x). /// </summary> public static double Integral(double lowerBound, double upperBound, Func <double, double> func, ITruncatableDistribution <double> distribution) { var dist = new TruncatedDistribution(distribution, lowerBound, upperBound); // To approximate the average, we divide the region into intervals of equal probability. // We compute the function at the midpoint of each interval, and take an unweighted average. // The quantile ranks of the midpoints are 0.5/count, 1.5/count, ..., (count-0.5)/count const int count = 100; double increment = 1.0 / count; double start = increment / 2; double sum = 0; for (int i = 0; i < count; i++) { double quantileRank = start + i * increment; double input = dist.GetQuantile(quantileRank); sum += func(input); } return(sum * increment * distribution.GetProbBetween(lowerBound, upperBound)); }