public static double Log1p(double x)
{
if (x <= -1.0)
return Double.NaN;
if (Math.Abs(x) > 1e-4)
return Math.Log(1.0 + x);
// Use Taylor approx. log(1 + x) = x - x^2/2 with error roughly x^3/3
// Since |x| < 10^-4, |x|^3 < 10^-12, relative error less than 10^-8
return (-0.5 * x + 1.0) * x;
}
public static double LogSum(float lnx, float lny) { if (lnx == Single.NegativeInfinity) { return(lny); } if (lny == Single.NegativeInfinity) { return(lnx); } if (lnx > lny) { return(lnx + Special.Log1p(Math.Exp(lny - lnx))); } return(lny + Special.Log1p(Math.Exp(lnx - lny))); }