/// <summary> /// Creates a multi-dimensional Wishart with given shape and with /// a rate matrix which is set to a scaled identity matrix /// </summary> /// <param name="dimension">The dimension</param> /// <param name="shape">The shape parameter</param> /// <param name="rate">Used to scale the identity matrix</param> /// <returns>A new Wishart distribution</returns> public static Wishart FromShapeAndRate(int dimension, double shape, double rate) { //return FromShapeAndRate(shape, PositiveDefiniteMatrix.IdentityScaledBy(dimension,rate)); Wishart result = new Wishart(dimension); result.Shape = shape; result.Rate.SetToIdentityScaledBy(rate); return(result); }
/// <summary> /// Override of the Equals method /// </summary> /// <param name="thatd">The instance to compare to</param> /// <returns>True if the two distributions are the same in value, false otherwise</returns> /// <exclude/> public override bool Equals(object thatd) { Wishart that = thatd as Wishart; if (that == null) { return(false); } return(MaxDiff(that) == 0.0); }
/// <summary> /// Sets this Wishart instance to have the parameter values of another Wishart instance /// </summary> /// <param name="that">The other Wishart</param> public void SetTo(Wishart that) { if (object.ReferenceEquals(that, null)) { SetToUniform(); } else { rate.SetTo(that.rate); shape = that.shape; } }
/// <summary> /// Sets the parameters to represent the product of two Wisharts. /// </summary> /// <param name="g1">The first Wishart. May refer to <c>this</c>.</param> /// <param name="g2">The second Wishart. May refer to <c>this</c>.</param> /// <remarks> /// The result may not be proper. No error is thrown in this case. /// </remarks> public void SetToProduct(Wishart g1, Wishart g2) { if (g1.IsPointMass) { Point = g1.Point; return; } if (g2.IsPointMass) { Point = g2.Point; return; } shape = g1.shape + g2.shape - 0.5 * (Dimension + 1); rate.SetToSum(g1.rate, g2.rate); }
/// <summary> /// The maximum difference between the parameters of this Wishart /// and that Wishart /// </summary> /// <param name="thatd">That Wishart</param> /// <returns>The maximum difference</returns> public double MaxDiff(object thatd) { Wishart that = thatd as Wishart; if (that == null) { return(Double.PositiveInfinity); } double max = rate.MaxDiff(that.rate); double diff = MMath.AbsDiff(shape, that.shape); if (diff > max) { max = diff; } return(max); }
/// <summary> /// Gets the log-integral of the product of this Wishart with another Wishart /// </summary> /// <param name="that">The other Wishart</param> /// <returns>The log inner product</returns> public double GetLogAverageOf(Wishart that) { if (IsPointMass) { return(that.GetLogProb(Point)); } else if (that.IsPointMass) { return(GetLogProb(that.Point)); } else { Wishart product = this * that; //if (!product.IsProper()) throw new ArgumentException("The product is improper."); return(product.GetLogNormalizer() - this.GetLogNormalizer() - that.GetLogNormalizer()); } }
/// <summary> /// Get the integral of this distribution times another distribution raised to a power. /// </summary> /// <param name="that"></param> /// <param name="power"></param> /// <returns></returns> public double GetLogAverageOfPower(Wishart that, double power) { if (IsPointMass) { return(power * that.GetLogProb(Point)); } else if (that.IsPointMass) { if (power < 0) { throw new DivideByZeroException("The exponent is negative and the distribution is a point mass"); } return(this.GetLogProb(that.Point)); } else { var product = this * (that ^ power); return(product.GetLogNormalizer() - this.GetLogNormalizer() - power * that.GetLogNormalizer()); } }
/// <summary> /// The expected logarithm of that distribution under this distribution. /// </summary> /// <param name="that">The distribution to take the logarithm of.</param> /// <returns><c>sum_x this.Evaluate(x)*Math.Log(that.Evaluate(x))</c></returns> /// <remarks>This is also known as the cross entropy.</remarks> public double GetAverageLog(Wishart that) { if (that.IsPointMass) { if (this.IsPointMass && (this.Point == that.Point)) { return(0.0); } else { return(Double.NegativeInfinity); } } else { // that is not a point mass. double result = (that.Shape - 0.5 * (that.Dimension + 1)) * this.GetMeanLogDeterminant(); result -= Matrix.TraceOfProduct(this.GetMean(), that.Rate); result -= that.GetLogNormalizer(); return(result); } }
public static double ProbEqualLn(IEnumerable <Wishart> dists) { // are any of them point masses? PositiveDefiniteMatrix point = null; foreach (Wishart dist in dists) { if (dist.IsPointMass) { point = dist.Point; break; } } if (point != null) { // one is a point mass double sum = 0.0; foreach (Wishart dist in dists) { sum += dist.EvaluateLn(point); } return(sum); } else { double sum = 0.0; int dimension = 0; foreach (Wishart dist in dists) { dimension = dist.Dimension; sum += dist.Normalizer(); } Wishart prod = new Wishart(dimension); Util.SetToProduct(prod, dists); sum -= prod.Normalizer(); return(sum); } }
/// <summary> /// Weighted mixture distribution for two Wisharts /// </summary> /// <param name="weight1">First weight</param> /// <param name="dist1">First Wishart</param> /// <param name="weight2">Second weight</param> /// <param name="dist2">Second Wishart</param> public void SetToSum(double weight1, Wishart dist1, double weight2, Wishart dist2) { SetTo(WeightedSum <Wishart>(this, Dimension, weight1, dist1, weight2, dist2)); }