public LogNormalDistribution(double mean, double standardDeviation)
 {
     normalSampler = DistributionPool.Instance.GetDistribution(Statistics.Distribution.Normal, 0, 1);
     PeakX         = mean;
     Scale         = standardDeviation;
     Type          = Statistics.Distribution.LogNormal;
 }
Beispiel #2
0
        public LaplaceDistribution(double location, double diversity)
        {
            Scale = diversity;
            PeakX = location;
            Type  = Statistics.Distribution.Laplace;

            z = new UniformDistribution();
        }
Beispiel #3
0
        public LogisticDistribution(double location, double scale)
        {
            Scale = scale;
            PeakX = location;
            Type  = Statistics.Distribution.Logistic;

            z = new UniformDistribution();
        }
Beispiel #4
0
        /* This runs in O(O(forPdf) + O(inverseOfPdf)).
         * Call as few times as possible.
         */
        public Ziggurat(MathFunction forPdf,
                        double mean,
                        double bound,
                        ProbabilityDistribution randomNumberGenerator,
                        int resolution            = 1000000,
                        MathFunction inverseOfCdf = null,
                        MathFunction inverseOfPdf = null)
        {
            this.inverseOfCdf = inverseOfCdf;
            this.bound        = bound;
            random            = randomNumberGenerator;
            this.mean         = mean;
            pdf = x => forPdf(x + mean);

            if (inverseOfCdf == null)
            {
                this.inverseOfCdf = NumericalTools.Inverse(x => NumericalTools.Integrate(pdf, 0, x), 0, 1);
            }

            if (inverseOfPdf == null)
            {
                inverseOfPdf = NumericalTools.Inverse(pdf, 0, bound);
            }

            xLimits = new double[NUM_RECTS];
            yLimits = new double[NUM_RECTS];

            // Search for suitable area using numerical integration
            double goal       = pdf(0);
            double lowerBound = pdf(bound);

            double currentTailArea(double x) => NumericalTools.Integrate(pdf, x, bound);
            double currentR0Area(double x) => pdf(x) * x;

            double topY(double x)
            {
                xLimits[0] = x;
                yLimits[0] = pdf(x);

                double area = currentTailArea(x) + currentR0Area(x);

                for (var i = 1; i < NUM_RECTS; i++)
                {
                    yLimits[i] = yLimits[i - 1] + (area / xLimits[i - 1]);
                    xLimits[i] = inverseOfPdf(yLimits[i]);
                }

                return(yLimits[NUM_RECTS - 1]);
            }

            double x0 = bound;

            if (topY(x0) > goal + 0.000001)
            {
                double top = topY(x0);
                throw new ArgumentException("Bound too small");
            }

            while (topY(x0) < goal)
            {
                x0 -= bound / 100;
            }

            x0 += bound / 100;

            while (topY(x0) < goal)
            {
                x0 -= bound / 1000;
            }

            x0 += bound / 1000;

            while (topY(x0) < goal)
            {
                var top = topY(x0);
                x0 -= bound / resolution;
            }

            x0 += bound / (2 * resolution);
            topY(x0);

            r0Area = currentR0Area(x0);
        }