예제 #1
0
        public void DistributionCentralMomentIntegral()
        {
            foreach (ContinuousDistribution distribution in distributions)
            {
                foreach (int n in TestUtilities.GenerateIntegerValues(2, 24, 8))
                {
                    // get the predicted central moment
                    double C = distribution.CentralMoment(n);

                    // don't try to integrate infinite moments
                    if (Double.IsInfinity(C) || Double.IsNaN(C))
                    {
                        continue;
                    }

                    if (C == 0.0)
                    {
                        continue;
                    }

                    IntegrationSettings settings = new IntegrationSettings();
                    if (C == 0.0)
                    {
                        // if moment is zero, use absolute precision
                        settings.AbsolutePrecision = TestUtilities.TargetPrecision;
                        settings.RelativePrecision = 0.0;
                    }
                    else
                    {
                        // if moment in non-zero, use relative precision
                        settings.AbsolutePrecision = 0.0;
                        settings.RelativePrecision = TestUtilities.TargetPrecision;
                    }

                    // do the integral
                    double m = distribution.Mean;
                    Func <double, double> f = delegate(double x) {
                        return(distribution.ProbabilityDensity(x) * MoreMath.Pow(x - m, n));
                    };
                    try {
                        double CI = FunctionMath.Integrate(f, distribution.Support, settings).Value;
                        Console.WriteLine("{0} {1} {2} {3}", distribution.GetType().Name, n, C, CI);
                        if (C == 0.0)
                        {
                            Assert.IsTrue(Math.Abs(CI) < TestUtilities.TargetPrecision);
                        }
                        else
                        {
                            double e = TestUtilities.TargetPrecision;
                            // reduce required precision, because some distributions (e.g. Kolmogorov, Weibull)
                            // have no analytic expressions for central moments, which must therefore be
                            // determined via raw moments and are thus subject to cancelation error
                            // can we revisit this later?
                            if (distribution is WeibullDistribution)
                            {
                                e = Math.Sqrt(Math.Sqrt(e));
                            }
                            if (distribution is KolmogorovDistribution)
                            {
                                e = Math.Sqrt(e);
                            }
                            if (distribution is KuiperDistribution)
                            {
                                e = Math.Sqrt(Math.Sqrt(e));
                            }
                            if (distribution is TriangularDistribution)
                            {
                                e = Math.Sqrt(e);
                            }
                            Assert.IsTrue(TestUtilities.IsNearlyEqual(C, CI, e));
                        }
                    } catch (NonconvergenceException) {
                        Console.WriteLine("{0} {1} {2} {3}", distribution.GetType().Name, n, C, "NC");
                        // deal with these later; they are integration problems, not distribution problems
                    }
                }
            }
        }