[gnumeric] dnorm: further minor improvements.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] dnorm: further minor improvements.
- Date: Mon, 30 Dec 2013 18:35:51 +0000 (UTC)
commit bdcba232e6a31007b6fd715e008eb2875fe4f11d
Author: Morten Welinder <terra gnome org>
Date: Mon Dec 30 13:17:53 2013 -0500
dnorm: further minor improvements.
src/mathfunc.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
---
diff --git a/src/mathfunc.c b/src/mathfunc.c
index 9fd35a6..aea76f9 100644
--- a/src/mathfunc.c
+++ b/src/mathfunc.c
@@ -236,23 +236,25 @@ gnm_float dnorm(gnm_float x, gnm_float mu, gnm_float sigma, gboolean give_log)
x = (x - mu) / sigma;
x = gnm_abs (x);
+ if (x >= 2 * gnm_sqrt (GNM_MAX))
+ return R_D__0;
if (give_log)
return -(M_LN_SQRT_2PI + 0.5 * x * x + gnm_log(sigma));
else if (x < 5)
return M_1_SQRT_2PI * gnm_exp(-0.5 * x * x) / sigma;
- else if (x >= 256)
- return 0; /* Will underflow anyway. */
else {
/*
- * Split x into two parts, x=x1+x2, such that x2 is
- * small and x1 has less than 26 bits. That ensures
- * that x1*x1 is error free.
+ * Split x into two parts, x=x1+x2, such that |x2|<=2^-16.
+ * Assuming that we are using IEEE doubles, that means that
+ * x1*x1 is error free for x<1024 (above which we will underflow
+ * anyway). If we are not using IEEE doubles then this is
+ * still an improvement over the naive formula.
*/
gnm_float x1 = gnm_floor (x * 65536 + 0.5) / 65536;
gnm_float x2 = x - x1;
return M_1_SQRT_2PI / sigma *
(gnm_exp(-0.5 * x1 * x1) *
- gnm_exp(-(0.5 * x2 + x1) * x2));
+ gnm_exp((-0.5 * x2 - x1) * x2));
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]