Example #1
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ExpOp_Laplace"]/message_doc[@name="DAverageConditional(Gamma, Gaussian, Gaussian)"]/*'/>
        public static Gaussian DAverageConditional([SkipIfUniform] Gamma exp, [Proper] Gaussian d, Gaussian to_d)
        {
            if (exp.IsPointMass)
            {
                return(ExpOp.DAverageConditional(exp.Point));
            }
            Gaussian dPost  = d * to_d;
            double   dhat   = dPost.GetMean();
            double   ehat   = Math.Exp(dhat);
            double   a      = exp.Shape;
            double   b      = exp.Rate;
            double   dlogf  = (a - 1) - b * ehat;
            double   ddlogf = -b * ehat;
            double   r      = -ddlogf;

            if (ForceProper && r < 0)
            {
                r = 0;
            }
            return(Gaussian.FromNatural(r * dhat + dlogf, r));
        }
Example #2
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ExpOp_Laplace2"]/message_doc[@name="DAverageConditional(Gamma, Gaussian, double)"]/*'/>
        public static Gaussian DAverageConditional([SkipIfUniform] Gamma exp, [Proper] Gaussian d, double x)
        {
            if (exp.IsPointMass)
            {
                return(ExpOp.DAverageConditional(exp.Point));
            }
            double expx    = Math.Exp(x);
            double a       = exp.Shape;
            double b       = exp.Rate;
            double ddlogf  = -b * expx;
            double dddlogf = ddlogf;
            double d4logf  = ddlogf;
            double dlogf   = (a - 1) + ddlogf;
            double v       = 1 / (d.Precision - ddlogf);
            // this is Laplace's estimate of the posterior mean and variance
            double mpost = x + 0.5 * dddlogf * v * v;
            double vpost = v + 0.5 * d4logf * v * v * v + dddlogf * dddlogf * v * v * v * v;
            //double vpost = v + 0.25 * dddlogf * dddlogf * v * v * v * v;
            Gaussian result = Gaussian.FromMeanAndVariance(mpost, vpost);

            result.SetToRatio(result, d, ExpOp.ForceProper);
            return(result);
        }
Example #3
0
File: Log.cs Project: 0xCM/arrows
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="LogOp_EP"]/message_doc[@name="LogAverageConditional(Gaussian, Gamma, Gaussian)"]/*'/>
        public static Gaussian LogAverageConditional([Proper] Gaussian log, [SkipIfUniform] Gamma d, Gaussian result)
        {
            var g = Gamma.FromShapeAndRate(d.Shape + 1, d.Rate);

            return(ExpOp.DAverageConditional(g, log, result));
        }
Example #4
0
File: Log.cs Project: 0xCM/arrows
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="LogOp_EP"]/message_doc[@name="DAverageConditional(Gaussian, Gamma, Gaussian)"]/*'/>
        public static Gamma DAverageConditional([Proper] Gaussian log, Gamma d, Gaussian to_log)
        {
            var g = Gamma.FromShapeAndRate(d.Shape + 1, d.Rate);

            return(ExpOp.ExpAverageConditional(g, log, to_log));
        }
Example #5
0
File: Log.cs Project: 0xCM/arrows
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="LogOp_EP"]/message_doc[@name="LogAverageFactor(Gaussian, Gamma, Gaussian)"]/*'/>
        public static double LogAverageFactor(Gaussian log, Gamma d, [Fresh] Gaussian to_log)
        {
            Gamma g = Gamma.FromShapeAndRate(d.Shape + 1, d.Rate);

            return(d.Shape / d.Rate * ExpOp.LogAverageFactor(g, log, to_log));
        }
Example #6
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="ExpOp_BFGS"]/message_doc[@name="DAverageLogarithm(Gamma, Gaussian, Gaussian)"]/*'/>
        public static Gaussian DAverageLogarithm([Proper] Gamma exp, [Proper, Stochastic] Gaussian d, Gaussian to_d)
        {
            if (exp.IsPointMass)
            {
                return(ExpOp.DAverageLogarithm(exp.Point));
            }

            double m, v;

            d.GetMeanAndVariance(out m, out v);
            double mu, s2;
            var    prior = d / to_d;

            prior.GetMeanAndVariance(out mu, out s2);
            var z = Vector.Zero(2);

            z[0] = m;
            z[1] = Math.Log(v);
            double startingValue = GradientAndValueAtPoint(mu, s2, z, exp.Shape, exp.Rate, null);
            var    s             = new BFGS();
            int    evalCounter   = 0;

            s.MaximumStep         = 1e3;
            s.MaximumIterations   = 100;
            s.Epsilon             = 1e-5;
            s.convergenceCriteria = BFGS.ConvergenceCriteria.Objective;
            z = s.Run(z, 1.0, delegate(Vector y, ref Vector grad)
            {
                evalCounter++;
                return(GradientAndValueAtPoint(mu, s2, y, exp.Shape, exp.Rate, grad));
            });
            m = z[0];
            v = Math.Exp(z[1]);
            to_d.SetMeanAndVariance(m, v);
            to_d.SetToRatio(to_d, prior);
            double endValue = GradientAndValueAtPoint(mu, s2, z, exp.Shape, exp.Rate, null);

            //Console.WriteLine("Went from {0} to {1} in {2} steps, {3} evals", startingValue, endValue, s.IterationsPerformed, evalCounter);
            if (startingValue < endValue)
            {
                Console.WriteLine("Warning: BFGS resulted in an increased objective function");
            }
            return(to_d);

            /* ---------------- NEWTON ITERATION VERSION 1 -------------------
             * double meanTimesPrec, prec;
             * d.GetNatural(out meanTimesPrec, out prec);
             * Matrix K = new Matrix(2, 2);
             * K[0, 0]=1/prec; // d2K by dmu^2
             * K[1, 0]=K[0, 1]=-meanTimesPrec/(prec*prec);
             * K[1, 1]=meanTimesPrec*meanTimesPrec/Math.Pow(prec, 3)+1/(2*prec*prec);
             * double[,,] Kprime = new double[2, 2, 2];
             * Kprime[0, 0, 0]=0;
             * Kprime[0, 0, 1]=Kprime[0, 1, 0]=Kprime[1, 0, 0]=-1/(prec*prec);
             * Kprime[0, 1, 1]=Kprime[1, 1, 0]=Kprime[1, 0, 1]=2*meanTimesPrec/Math.Pow(prec, 3);
             * Kprime[1, 1, 1]=-3*meanTimesPrec*meanTimesPrec/Math.Pow(prec, 4)-1/Math.Pow(prec, 3);
             * Vector gradS = new Vector(2);
             * gradS[0]=(exp.Shape-1)/prec-exp.Rate/prec*Math.Exp((meanTimesPrec+.5)/prec);
             * gradS[1]=-(exp.Shape-1)*meanTimesPrec/(prec*prec)+exp.Rate*(meanTimesPrec+.5)/(prec*prec)*Math.Exp((meanTimesPrec+.5)/prec);
             * Matrix grad2S = new Matrix(2, 2);
             * grad2S[0, 0]=-exp.Rate/(prec*prec)*Math.Exp((meanTimesPrec+.5)/prec);
             * grad2S[0, 1]=grad2S[1, 0]=-(exp.Shape-1)/(prec*prec)+exp.Rate*(1/(prec*prec)+(meanTimesPrec+.5)/Math.Pow(prec, 3))*Math.Exp((meanTimesPrec+.5)/prec);
             * grad2S[1, 1]=2*(exp.Shape-1)*meanTimesPrec/Math.Pow(prec, 3)-exp.Rate*(meanTimesPrec+.5)/(prec*prec)*(2/prec+(meanTimesPrec+.5)/(prec*prec))*Math.Exp((meanTimesPrec+.5)/prec);
             * Vector phi = new Vector(new double[] { result.MeanTimesPrecision, result.Precision });
             * Vector gradKL = K*phi-gradS;
             * Matrix hessianKL = K - grad2S;
             * for (int i=0; i<2; i++)
             *              for (int j=0; j<2; j++)
             *                              for (int k=0; k<2; k++)
             *                                              hessianKL[i, j]+=Kprime[i, j, k]*phi[k];
             * double step = 1;
             * Vector direction = GammaFromShapeAndRate.twoByTwoInverse(hessianKL)*gradKL;
             * Vector newPhi = phi - step * direction;
             * result.SetNatural(newPhi[0], newPhi[1]);
             * return result;
             *
             * ---------------- NEWTON ITERATION VERSION 2 -------------------
             * double mean, variance;
             * d.GetMeanAndVariance(out mean, out variance);
             * Gaussian prior = d / result;
             * double mean1, variance1;
             * prior.GetMeanAndVariance(out mean1, out variance1);
             * Vector gradKL = new Vector(2);
             * gradKL[0]=-(exp.Shape-1)+exp.Rate*Math.Exp(mean+variance/2)+mean/variance1-mean1/variance1;
             * gradKL[1]=-1/(2*variance)+exp.Rate*Math.Exp(mean+variance/2)+1/(2*variance1);
             * Matrix hessianKL = new Matrix(2, 2);
             * hessianKL[0, 0]=exp.Rate*Math.Exp(mean+variance/2)+1/variance1;
             * hessianKL[0, 1]=hessianKL[1, 0]=.5*exp.Rate*Math.Exp(mean+variance/2);
             * hessianKL[1, 1]=1/(2*variance*variance)+exp.Rate*Math.Exp(mean+variance/2)/4;
             * result.GetMeanAndVariance(out mean, out variance);
             * if (double.IsInfinity(variance))
             *              variance=1000;
             * Vector theta = new Vector(new double[] { mean, variance });
             * theta -= GammaFromShapeAndRate.twoByTwoInverse(hessianKL)*gradKL;
             * result.SetMeanAndVariance(theta[0], theta[1]);
             * return result;
             * ----------------------------------------------------------------- */
        }
Example #7
0
        public static Gaussian DAverageConditional([SkipIfUniform] Gamma exp, [Proper] Gaussian d)
        {
            // as a function of d, the factor is Ga(exp(d); shape, rate) = exp(d*(shape-1) -rate*exp(d))
            if (exp.IsUniform())
            {
                return(Gaussian.Uniform());
            }
            if (exp.IsPointMass)
            {
                return(ExpOp.DAverageConditional(exp.Point));
            }
            if (exp.Rate < 0)
            {
                throw new ImproperMessageException(exp);
            }
            if (exp.Rate == 0)
            {
                return(Gaussian.FromNatural(exp.Shape - 1, 0));
            }
            if (d.IsUniform())
            {
                if (exp.Shape <= 1)
                {
                    throw new ArgumentException("The posterior has infinite variance due to input of Exp distributed as " + d + " and output of Exp distributed as " + exp +
                                                " (shape <= 1)");
                }
                // posterior for d is a shifted log-Gamma distribution:
                // exp((a-1)*d - b*exp(d)) =propto exp(a*(d+log(b)) - exp(d+log(b)))
                // we find the Gaussian with same moments.
                // u = d+log(b)
                // E[u] = digamma(a-1)
                // E[d] = E[u]-log(b) = digamma(a-1)-log(b)
                // var(d) = var(u) = trigamma(a-1)
                double lnRate = Math.Log(exp.Rate);
                return(new Gaussian(MMath.Digamma(exp.Shape - 1) - lnRate, MMath.Trigamma(exp.Shape - 1)));
            }
            double aMinus1 = exp.Shape - 1;
            double b       = exp.Rate;

            if (d.IsPointMass)
            {
                double x      = d.Point;
                double expx   = Math.Exp(x);
                double dlogf  = aMinus1 - b * expx;
                double ddlogf = -b * expx;
                return(Gaussian.FromDerivatives(x, dlogf, ddlogf, true));
            }
            double dmode, dmin, dmax;

            GetIntegrationBounds(exp, d, out dmode, out dmin, out dmax);
            double expmode = Math.Exp(dmode);
            int    n       = QuadratureNodeCount;
            double inc     = (dmax - dmin) / (n - 1);
            MeanVarianceAccumulator mva = new MeanVarianceAccumulator();

            for (int i = 0; i < n; i++)
            {
                double x          = dmin + i * inc;
                double xMinusMode = x - dmode;
                double diff       = aMinus1 * xMinusMode - b * (Math.Exp(x) - expmode)
                                    - 0.5 * ((x * x - dmode * dmode) * d.Precision - 2 * xMinusMode * d.MeanTimesPrecision);
                double p = Math.Exp(diff);
                mva.Add(x, p);
                if (double.IsNaN(mva.Variance))
                {
                    throw new Exception();
                }
            }
            double   dMean     = mva.Mean;
            double   dVariance = mva.Variance;
            Gaussian result    = Gaussian.FromMeanAndVariance(dMean, dVariance);

            result.SetToRatio(result, d, true);
            return(result);
        }