gnumeric r16577 - in branches/gnumeric-1-8: . src
- From: mortenw svn gnome org
- To: svn-commits-list gnome org
- Subject: gnumeric r16577 - in branches/gnumeric-1-8: . src
- Date: Sat, 17 May 2008 22:20:08 +0000 (UTC)
Author: mortenw
Date: Sat May 17 22:20:08 2008
New Revision: 16577
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16577&view=rev
Log:
2008-05-17 Morten Welinder <terra gnome org>
* src/mathfunc.c (qpois): Return nan on invalid lambda. Fixes
#533515.
(discpfuncinverter): Handle overflow when searching for missing
side better. Also fixes #533515.
2
Modified:
branches/gnumeric-1-8/ChangeLog
branches/gnumeric-1-8/NEWS
branches/gnumeric-1-8/src/mathfunc.c
Modified: branches/gnumeric-1-8/NEWS
==============================================================================
--- branches/gnumeric-1-8/NEWS (original)
+++ branches/gnumeric-1-8/NEWS Sat May 17 22:20:08 2008
@@ -30,6 +30,7 @@
* Fix hang. [#533288]
* Fix AREAS crash. [#533370]
* Fix translation of function description. [#533193]
+ * Fix R.QPOIS (and related functions) hang. [#533515]
--------------------------------------------------------------------------
Gnumeric 1.8.2
Modified: branches/gnumeric-1-8/src/mathfunc.c
==============================================================================
--- branches/gnumeric-1-8/src/mathfunc.c (original)
+++ branches/gnumeric-1-8/src/mathfunc.c Sat May 17 22:20:08 2008
@@ -5834,7 +5834,7 @@
}
#ifdef DEBUG_pfuncinverter
- printf ("p=%.15g\n", p);
+ g_printerr ("p=%.15g\n", p);
#endif
for (i = 0; i < 100; i++) {
@@ -5902,8 +5902,8 @@
if (!lower_tail) e = -e;
#ifdef DEBUG_pfuncinverter
- printf ("%3d: x=%.15g e=%.15g l=%.15g h=%.15g\n",
- i, x, e, xlow, xhigh);
+ g_printerr ("%3d: x=%.15g e=%.15g l=%.15g h=%.15g\n",
+ i, x, e, xlow, xhigh);
#endif
if (e == 0)
@@ -5934,7 +5934,7 @@
gnm_float d = dpfunc_dx (x, shape, log_p);
if (log_p) d = gnm_exp (d - px);
#ifdef DEBUG_pfuncinverter
- g_print ("Newton: d=%-.14g\n", d);
+ g_printerr ("Newton: d=%-.14g\n", d);
#endif
if (d) {
/*
@@ -5945,14 +5945,14 @@
x = x - e / d * 1.000001;
if (x > xlow && x < xhigh) {
#ifdef DEBUG_pfuncinverter
- printf ("Newton ok\n");
+ g_printerr ("Newton ok\n");
#endif
i++;
goto newton_retry;
}
} else {
#ifdef DEBUG_pfuncinverter
- printf ("Newton d=0\n");
+ g_printerr ("Newton d=0\n");
#endif
}
}
@@ -5969,7 +5969,7 @@
e = exlow, x = xlow;
#ifdef DEBUG_pfuncinverter
- printf ("--> %.15g\n\n", x);
+ g_printerr ("--> %.15g\n\n", x);
#endif
return x;
}
@@ -6005,10 +6005,14 @@
x0 = gnm_floor (x0 + 0.5);
step = 1 + gnm_floor (gnm_abs (x0) * GNM_EPSILON);
+#if 0
+ g_printerr ("step=%.20g\n", step);
+#endif
+
for (i = 1; 1; i++) {
gnm_float ex0 = pfunc (x0, shape, lower_tail, log_p) - p;
#if 0
- g_print ("x=%.20g e=%.20g\n", x0, ex0);
+ g_printerr ("x=%.20g e=%.20g\n", x0, ex0);
#endif
if (!lower_tail) ex0 = -ex0;
if (ex0 <= 0)
@@ -6025,7 +6029,10 @@
} else {
gnm_float x1 = x0 + step;
- if (x1 >= xlow && x1 <= xhigh) {
+ if (x1 == x0) {
+ /* Probably infinite. */
+ return gnm_nan;
+ } else if (x1 >= xlow && x1 <= xhigh) {
x0 = x1;
step *= 2 * i;
} else {
@@ -6047,6 +6054,7 @@
g_assert_not_reached ();
}
+
/* ------------------------------------------------------------------------ */
static gnm_float
@@ -6059,13 +6067,18 @@
gnm_float
qpois (gnm_float p, gnm_float lambda, gboolean lower_tail, gboolean log_p)
{
- gnm_float mu = lambda;
- gnm_float sigma = gnm_sqrt (lambda);
- gnm_float gamma = 1 / sigma;
+ gnm_float mu, sigma, gamma, y, z;
+
+ if (!(lambda >= 0))
+ return gnm_nan;
+
+ mu = lambda;
+ sigma = gnm_sqrt (lambda);
+ gamma = 1 / sigma;
/* Cornish-Fisher expansion: */
- gnm_float z = qnorm (p, 0., 1., lower_tail, log_p);
- gnm_float y = mu + sigma * (z + gamma * (z * z - 1) / 6);
+ z = qnorm (p, 0., 1., lower_tail, log_p);
+ y = mu + sigma * (z + gamma * (z * z - 1) / 6);
return discpfuncinverter (p, &lambda, lower_tail, log_p,
0, gnm_pinf, y,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]