/// <summary> /// Computes the sum of a geometric series <c>1 + w + w^2 + w^3 + ...</c>, /// where <c>w</c> is a given weight. /// If the sum diverges, replaces the infinite sum by a finite sum with a lot of terms. /// </summary> /// <param name="weight">The weight.</param> /// <returns>The computed sum.</returns> public static Weight ApproximateClosure(Weight weight) { const double Eps = 1e-20; const double TermCount = 10000; if (weight.LogValue < -Eps) { // The series converges return(new Weight(-MMath.Log1MinusExp(weight.LogValue))); } if (weight.LogValue < Eps) { // The series diverges, geometric progression formula does not apply return(new Weight(Math.Log(TermCount))); } // Compute geometric progression with a lot of terms return(new Weight(MMath.LogExpMinus1(weight.LogValue * TermCount) - MMath.LogExpMinus1(weight.LogValue))); }