Esempio n. 1
0
        /// <summary>EP message to <c>func</c>.</summary>
        /// <param name="y">Incoming message from <c>y</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="func">Incoming message from <c>func</c>. Must be a proper distribution. If uniform, the result will be uniform.</param>
        /// <param name="x">Constant value for <c>x</c>.</param>
        /// <param name="result">Modified to contain the outgoing message.</param>
        /// <returns>
        ///   <paramref name="result" />
        /// </returns>
        /// <remarks>
        ///   <para>The outgoing message is a distribution matching the moments of <c>func</c> as the random arguments are varied. The formula is <c>proj[p(func) sum_(y) p(y) factor(y,func,x)]/p(func)</c>.</para>
        /// </remarks>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="y" /> is not a proper distribution.</exception>
        /// <exception cref="ImproperMessageException">
        ///   <paramref name="func" /> is not a proper distribution.</exception>
        public static SparseGP FuncAverageConditional([SkipIfUniform] Gaussian y, [SkipIfUniform] SparseGP func, Vector x, SparseGP result)
        {
            if (y.IsUniform() || func.IsUniform())
            {
                result.SetToUniform();
                return(result);
            }
            result.FixedParameters = func.FixedParameters;
            result.IncludePrior    = false;

            double vf = func.Variance(x);
            double my, vy;

            y.GetMeanAndVariance(out my, out vy);
            Vector kbx  = func.FixedParameters.KernelOf_X_B(x);
            Vector proj = func.FixedParameters.InvKernelOf_B_B * kbx;
            double prec = 1.0 / (vy + vf - func.Var_B_B.QuadraticForm(proj));

            result.InducingDist.Precision.SetToOuter(proj, proj);
            result.InducingDist.Precision.Scale(prec);
            result.InducingDist.MeanTimesPrecision.SetTo(proj);
            result.InducingDist.MeanTimesPrecision.Scale(prec * my);
            result.ClearCachedValues();
            return(result);
        }
Esempio n. 2
0
        /// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="SparseGPOp"]/message_doc[@name="FuncAverageConditional(Gaussian, SparseGP, Vector, SparseGP)"]/*'/>
        public static SparseGP FuncAverageConditional([SkipIfUniform] Gaussian y, [SkipIfUniform] SparseGP func, Vector x, SparseGP result)
        {
            if (y.IsUniform() || func.IsUniform())
            {
                result.SetToUniform();
                return(result);
            }
            result.FixedParameters = func.FixedParameters;
            result.IncludePrior    = false;

            Vector kbx  = func.FixedParameters.KernelOf_X_B(x);
            Vector proj = func.FixedParameters.InvKernelOf_B_B * kbx;
            // To avoid computing Var_B_B:
            // vf - func.Var_B_B.QuadraticForm(proj) = kxx - kbx'*beta*kbx - kbx'*inv(K)*Var_B_B*inv(K)*kbx
            // = kxx - kbx'*(beta + inv(K)*Var_B_B*inv(K))*kbx
            // = kxx - kbx'*(beta + inv(K)*(K - K*Beta*K)*inv(K))*kbx
            // = kxx - kbx'*inv(K)*kbx
            // Since Var_B_B = K - K*Beta*K
            double kxx = func.FixedParameters.Prior.Variance(x);

            if (y.Precision == 0)
            {
                result.InducingDist.Precision.SetAllElementsTo(0);
                result.InducingDist.MeanTimesPrecision.SetTo(proj);
                result.InducingDist.MeanTimesPrecision.Scale(y.MeanTimesPrecision);
            }
            else
            {
                double my, vy;
                y.GetMeanAndVariance(out my, out vy);
                double prec = 1.0 / (vy + kxx - kbx.Inner(proj));
                //Console.WriteLine($"{vf - func.Var_B_B.QuadraticForm(proj)} {func.FixedParameters.Prior.Variance(x) - func.FixedParameters.InvKernelOf_B_B.QuadraticForm(kbx)}");
                if (prec > double.MaxValue || prec < 0)
                {
                    int i = proj.IndexOfMaximum();
                    result.InducingDist.Precision.SetAllElementsTo(0);
                    result.InducingDist.Precision[i, i] = double.PositiveInfinity;
                    result.InducingDist.MeanTimesPrecision.SetAllElementsTo(0);
                    result.InducingDist.MeanTimesPrecision[i] = my;
                }
                else
                {
                    result.InducingDist.Precision.SetToOuter(proj, proj);
                    result.InducingDist.Precision.Scale(prec);
                    result.InducingDist.MeanTimesPrecision.SetTo(proj);
                    result.InducingDist.MeanTimesPrecision.Scale(prec * my);
                }
            }
            result.ClearCachedValues();
            return(result);
        }