public static VectorGaussianWishart CombinationAverageConditional(
     [Proper] Gaussian positionX, [Proper] Gaussian positionY, [Proper] Wishart orientation, VectorGaussianWishart combination, VectorGaussianWishart result)
 {
     VectorGaussian position = VectorGaussian.FromMeanAndPrecision(
         Vector.FromArray(positionX.GetMean(), positionY.GetMean()),
         new PositiveDefiniteMatrix(new[,] { { positionX.Precision, 0 }, { 0, positionY.Precision } }));
     return CombineOps.Combine(position, orientation, result);
 }
        public static VectorGaussianWishart Combine(VectorGaussian position, Wishart orientation, VectorGaussianWishart result)
        {
            if (orientation.IsUniform())
            {
                result.SetToUniform();
            }
            else if (position.IsUniform())
            {
                result.SetTo(orientation.Shape, orientation.Rate, Vector.Zero(2), 0);
            }
            else
            {
                PositiveDefiniteMatrix rateTimesPrecision = new PositiveDefiniteMatrix(2, 2);
                rateTimesPrecision.SetToProduct(orientation.Rate, position.Precision);
                double trace = MathHelpers.Invert(rateTimesPrecision).Trace();
                Vector positionMean = position.MeanTimesPrecision * MathHelpers.Invert(position.Precision);
                result.SetTo(orientation.Shape, orientation.Rate, positionMean, orientation.Dimension / (orientation.Shape * trace));
            }

            return result;
        }
        public static VectorGaussian ExtractVectorPart(VectorGaussianWishart gaussianWishart, VectorGaussian result)
        {
            if (gaussianWishart.IsVectorMarginalUniform())
            {
                return VectorGaussian.Uniform(2);
            }

            double firstShape, secondPrecisionScale;
            PositiveDefiniteMatrix firstRate;
            Vector secondLocation;
            gaussianWishart.ExtractParameters(out firstShape, out firstRate, out secondLocation, out secondPrecisionScale);

            result.SetMeanAndPrecision(secondLocation, MathHelpers.Invert(firstRate) * (firstShape * secondPrecisionScale));

            return result;
        }
 public static Wishart ExtractMatrixPart(VectorGaussianWishart gaussianWishart, Wishart result)
 {
     result.SetTo(gaussianWishart.GetMatrixMarginal());
     return result;
 }
 public static VectorGaussianWishart CombinationAverageConditional(
     VectorGaussian position, Wishart orientation, VectorGaussianWishart combination, VectorGaussianWishart result)
 {
     return Combine(position, orientation, result);
 }
 private static VectorGaussianWishart DistributionTimesFactor(Vector point, VectorGaussianWishart shapeParamsDistr)
 {
     var factorAsDistr = VectorGaussianWishart.FromNaturalParameters(0, new PositiveDefiniteMatrix(point.Outer(point) * (-0.5)), point, -0.5);
     VectorGaussianWishart result = new VectorGaussianWishart(2);
     result.SetToProduct(factorAsDistr, shapeParamsDistr);
     return result;
 }
        public static VectorGaussianWishart ShapeParamsAverageConditional(
            Vector point, Bernoulli label, [Proper] VectorGaussianWishart shapeParams, VectorGaussianWishart result)
        {
            VectorGaussianWishart shapeParamsTimesFactor = DistributionTimesFactor(point, shapeParams);

            double labelProbFalse = label.GetProbFalse();
            double shapeParamsWeight = labelProbFalse;
            double shapeParamsTimesFactorWeight =
                Math.Exp(shapeParamsTimesFactor.GetLogNormalizer() - shapeParams.GetLogNormalizer()) *
                (1 - 2 * labelProbFalse);

            var projectionOfSum = new VectorGaussianWishart(2);
            projectionOfSum.SetToSum(shapeParamsWeight, shapeParams, shapeParamsTimesFactorWeight, shapeParamsTimesFactor);
            Debug.Assert(projectionOfSum.IsProper()); // TODO: remove me
            result.SetToRatio(projectionOfSum, shapeParams);

            return result;
        }