public static WrappedGaussian AngleAverageLogarithm([SkipIfUniform] VectorGaussian rotate, double x, double y) { if (rotate.Dimension != 2) { throw new ArgumentException("rotate.Dimension (" + rotate.Dimension + ") != 2"); } double rPrec = rotate.Precision[0, 0]; if (rotate.Precision[0, 1] != 0) { throw new ArgumentException("rotate.Precision is not diagonal"); } if (rotate.Precision[1, 1] != rPrec) { throw new ArgumentException("rotate.Precision is not spherical"); } #if false Vector rotateMean = rotate.GetMean(); double a = x * rotateMean[0] + y * rotateMean[1]; double b = x * rotateMean[1] - y * rotateMean[0]; #else double rotateMean0 = rotate.MeanTimesPrecision[0] / rotate.Precision[0, 0]; double rotateMean1 = rotate.MeanTimesPrecision[1] / rotate.Precision[1, 1]; double a = x * rotateMean0 + y * rotateMean1; double b = x * rotateMean1 - y * rotateMean0; #endif double c = Math.Sqrt(a * a + b * b) * rPrec; double angle0 = Math.Atan2(b, a); // the exact conditional is exp(c*cos(angle - angle0)) which is a von Mises distribution. // we will approximate this with a Gaussian lower bound that makes contact at the mode. WrappedGaussian result = WrappedGaussian.Uniform(); result.Gaussian = Gaussian.FromMeanAndPrecision(angle0, c); return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="DoublePlusOp"]/message_doc[@name="AAverageConditional(WrappedGaussian, double)"]/*'/> public static WrappedGaussian AAverageConditional([SkipIfUniform] WrappedGaussian sum, double b) { WrappedGaussian result = WrappedGaussian.Uniform(sum.Period); result.Gaussian = AAverageConditional(sum.Gaussian, b); result.Normalize(); return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="DoublePlusOp"]/message_doc[@name="SumAverageConditional(WrappedGaussian, double)"]/*'/> public static WrappedGaussian SumAverageConditional([SkipIfUniform] WrappedGaussian a, double b) { WrappedGaussian result = WrappedGaussian.Uniform(a.Period); result.Gaussian = SumAverageConditional(a.Gaussian, b); result.Normalize(); return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="PlusWrappedGaussianOp"]/message_doc[@name="AAverageLogarithm(WrappedGaussian, double)"]/*'/> public static WrappedGaussian AAverageLogarithm([SkipIfUniform] WrappedGaussian sum, double b) { WrappedGaussian result = WrappedGaussian.Uniform(sum.Period); result.Gaussian = DoublePlusVmpOp.AAverageLogarithm(sum.Gaussian, b); result.Normalize(); return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="DoublePlusOp"]/message_doc[@name="AAverageConditional(WrappedGaussian, WrappedGaussian)"]/*'/> public static WrappedGaussian AAverageConditional([SkipIfUniform] WrappedGaussian sum, [SkipIfUniform] WrappedGaussian b) { if (sum.Period != b.Period) { throw new ArgumentException("sum.Period (" + sum.Period + ") != b.Period (" + b.Period + ")"); } WrappedGaussian result = WrappedGaussian.Uniform(sum.Period); result.Gaussian = AAverageConditional(sum.Gaussian, b.Gaussian); result.Normalize(); return(result); }
/// <include file='FactorDocs.xml' path='factor_docs/message_op_class[@name="PlusWrappedGaussianOp"]/message_doc[@name="SumAverageConditional(WrappedGaussian, WrappedGaussian)"]/*'/> public static WrappedGaussian SumAverageConditional([SkipIfUniform] WrappedGaussian a, [SkipIfUniform] WrappedGaussian b) { if (a.Period != b.Period) { throw new ArgumentException("a.Period (" + a.Period + ") != b.Period (" + b.Period + ")"); } WrappedGaussian result = WrappedGaussian.Uniform(a.Period); result.Gaussian = DoublePlusOp.SumAverageConditional(a.Gaussian, b.Gaussian); result.Normalize(); return(result); }
public static WrappedGaussian AngleAverageLogarithm([SkipIfUniform] VectorGaussian rotate, double x, double y, [Proper] WrappedGaussian angle) { if (rotate.Dimension != 2) { throw new ArgumentException("rotate.Dimension (" + rotate.Dimension + ") != 2"); } double rPrec = rotate.Precision[0, 0]; if (rotate.Precision[0, 1] != 0) { throw new ArgumentException("rotate.Precision is not diagonal"); } if (rotate.Precision[1, 1] != rPrec) { throw new ArgumentException("rotate.Precision is not spherical"); } Vector rotateMean = rotate.GetMean(); double a = x * rotateMean[0] + y * rotateMean[1]; double b = x * rotateMean[1] - y * rotateMean[0]; double c = Math.Sqrt(a * a + b * b) * rPrec; double angle0 = Math.Atan2(b, a); // the exact conditional is exp(c*cos(angle - angle0)) which is a von Mises distribution. // we will approximate this with a Gaussian lower bound that makes contact at the current angleMean. if (angle.Period != 2 * Math.PI) { throw new ArgumentException("angle.Period (" + angle.Period + ") != 2*PI (" + 2 * Math.PI + ")"); } double angleMean = angle.Gaussian.GetMean(); double angleDiff = angleMean - angle0; double df = -c *Math.Sin(angleDiff); double precision = c * Math.Abs(Math.Cos(angleDiff * 0.5)); // ensures a lower bound double meanTimesPrecision = angleMean * precision + df; if (double.IsNaN(meanTimesPrecision)) { throw new ApplicationException("result is nan"); } WrappedGaussian result = WrappedGaussian.Uniform(angle.Period); result.Gaussian = Gaussian.FromNatural(meanTimesPrecision, precision); return(result); }