Ejemplo n.º 1
0
 private static double[] LognormalLpdf(double x, double[] weights, double[] mus, double[] sigmas)
 {
     double[] ret = new double[weights.Length];
     for (int i = 0; i < ret.Length; i++)
     {
         double sigma = Math.Max(sigmas[i], eps);
         double z     = sigma * x * Math.Sqrt(2 * Math.PI);
         double e     = 0.5 * ArrayMath.Square((Math.Log(x) - mus[i]) / sigma);
         ret[i] = -e - Math.Log(z) + Math.Log(weights[i]);
     }
     return(ret);
 }
Ejemplo n.º 2
0
        private static (double[], double[], double[]) AdaptiveParzenNormal(double[] mus, double priorMu, double priorSigma)
        {
            int[]    order     = ArrayMath.ArgSort(mus);
            double[] sortedMus = ArrayMath.Index(mus, order);
            int      priorPos  = ArrayMath.SearchSorted(sortedMus, priorMu);

            sortedMus = ArrayMath.Insert(sortedMus, priorPos, priorMu);

            int length = mus.Length;

            double[] sigma = new double[length + 1];

            if (length == 0)
            {
                sigma[0] = priorSigma;
            }
            else if (length == 1)
            {
                sigma[priorPos]     = priorSigma;
                sigma[1 - priorPos] = priorSigma * 0.5;
            }
            else
            {
                sigma[0]      = sortedMus[1] - sortedMus[0];
                sigma[length] = sortedMus[length] - sortedMus[length - 1];
                for (int i = 1; i < length; i++)
                {
                    sigma[i] = Math.Max(sortedMus[i] - sortedMus[i - 1], sortedMus[i + 1] - sortedMus[i]);
                }
            }

            double maxSigma = priorSigma / 1.0;
            double minSigma = priorSigma / Math.Min(100.0, length + 2);

            sigma           = ArrayMath.Clip(sigma, minSigma, maxSigma);
            sigma[priorPos] = priorSigma;

            double[] sortedWeights;
            if (lf < length)
            {
                sortedWeights = ArrayMath.Index(LinearForgettingWeights(length), order);
            }
            else
            {
                sortedWeights = Enumerable.Repeat(1.0, length).ToArray();
            }
            sortedWeights = ArrayMath.Insert(sortedWeights, priorPos, priorWeight);
            sortedWeights = ArrayMath.DivSum(sortedWeights);

            return(sortedWeights, sortedMus, sigma);
        }
Ejemplo n.º 3
0
 private static double[] NormalLpdf(double x, double[] weights, double[] mus, double[] sigmas, double pAccept)
 {
     double[] ret = new double[weights.Length];
     for (int i = 0; i < ret.Length; i++)
     {
         double sigma = Math.Max(sigmas[i], eps);
         double dist  = x - mus[i];
         double mahal = ArrayMath.Square(dist / sigma);
         double z     = Math.Sqrt(2 * Math.PI) * sigmas[i];
         double coef  = weights[i] / z / pAccept;
         ret[i] = -0.5 * mahal + Math.Log(coef);
     }
     return(ret);
 }
Ejemplo n.º 4
0
        private static double[] Gmm1Lpdf(double[] samples, double[] weights, double[] mus, double[] sigmas, double low, double high, bool log, bool integer)
        {
            double pAccept = ArrayMath.Mul(weights, ArrayMath.Sub(NormalCdf(high, mus, sigmas), NormalCdf(low, mus, sigmas))).Sum();

            double[] ret = new double[samples.Length];
            for (int i = 0; i < samples.Length; i++)
            {
                if (!integer)
                {
                    if (log)
                    {
                        ret[i] = LogSum(LognormalLpdf(samples[i], weights, mus, sigmas));
                    }
                    else
                    {
                        ret[i] = LogSum(NormalLpdf(samples[i], weights, mus, sigmas, pAccept));
                    }
                }
                else
                {
                    double prob = 0;
                    double ubound;
                    double lbound;
                    if (log)
                    {
                        ubound = Math.Log(Math.Min(samples[i] + 0.5, Math.Exp(high)));
                        lbound = Math.Log(Math.Max(samples[i] - 0.5, Math.Exp(low)));
                    }
                    else
                    {
                        ubound = Math.Min(samples[i] + 0.5, high);
                        lbound = Math.Max(samples[i] - 0.5, low);
                    }
                    prob  += ArrayMath.Mul(weights, NormalCdf(ubound, mus, sigmas)).Sum();
                    prob  -= ArrayMath.Mul(weights, NormalCdf(lbound, mus, sigmas)).Sum();
                    ret[i] = Math.Log(prob) - Math.Log(pAccept);
                }
            }
            return(ret);
        }
Ejemplo n.º 5
0
        private static int SuggestCategorical(List <Result> history, string tag, int size)
        {
            if (history.Count < nStartupJobs)
            {
                return(rng.Integer(size));
            }

            var(obsBelow, obsAbove) = ApSplitTrials(history, tag);

            double[] weights   = LinearForgettingWeights(obsBelow.Length);
            double[] counts    = Bincount(obsBelow, weights, size);
            double[] p         = ArrayMath.DivSum(ArrayMath.Add(counts, priorWeight));
            int[]    sample    = rng.Categorical(p, nEiCandidates);
            double[] belowLLik = ArrayMath.Log(ArrayMath.Index(p, sample));

            weights = LinearForgettingWeights(obsAbove.Length);
            counts  = Bincount(obsAbove, weights, size);
            p       = ArrayMath.DivSum(ArrayMath.Add(counts, priorWeight));
            double[] aboveLLik = ArrayMath.Log(ArrayMath.Index(p, sample));

            return(FindBest(sample, belowLLik, aboveLLik));
        }
Ejemplo n.º 6
0
        private static double SuggestNumerical(List <Result> history, string tag, double low, double high, bool log, bool integer)
        {
            if (history.Count < nStartupJobs)
            {
                double x = rng.Uniform(low, high);
                if (log)
                {
                    x = Math.Exp(x);
                }
                if (integer)
                {
                    x = Math.Round(x);
                }
                return(x);
            }

            var(obsBelow, obsAbove) = ApSplitTrials(history, tag);

            if (log)
            {
                obsBelow = ArrayMath.Log(obsBelow);
                obsAbove = ArrayMath.Log(obsAbove);
            }

            double priorMu    = 0.5 * (high + low);
            double priorSigma = high - low;

            var(weights, mus, sigmas) = AdaptiveParzenNormal(obsBelow, priorMu, priorSigma);
            double[] samples   = Gmm1(weights, mus, sigmas, low, high, log, integer);
            double[] belowLLik = Gmm1Lpdf(samples, weights, mus, sigmas, low, high, log, integer);

            (weights, mus, sigmas) = AdaptiveParzenNormal(obsAbove, priorMu, priorSigma);
            double[] aboveLLik = Gmm1Lpdf(samples, weights, mus, sigmas, low, high, log, integer);

            return(FindBest(samples, belowLLik, aboveLLik));
        }
Ejemplo n.º 7
0
        private static T FindBest <T>(T[] samples, double[] belowLLik, double[] aboveLLik)
        {
            int best = ArrayMath.ArgMax(ArrayMath.Sub(belowLLik, aboveLLik));

            return(samples[best]);
        }