[gnumeric] Non-linar solver: fix crash.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Non-linar solver: fix crash.
- Date: Fri, 27 Jul 2012 21:20:43 +0000 (UTC)
commit cbb505d7d91c6b690dcfaa0dae29a1f51a218af6
Author: Morten Welinder <terra gnome org>
Date: Fri Jul 27 17:20:20 2012 -0400
Non-linar solver: fix crash.
NEWS | 1 +
plugins/nlsolve/ChangeLog | 5 +++++
plugins/nlsolve/gnm-nlsolve.c | 14 ++++++++++----
src/rangefunc.c | 6 ++++++
4 files changed, 22 insertions(+), 4 deletions(-)
---
diff --git a/NEWS b/NEWS
index af2a9dd..49ae6f2 100644
--- a/NEWS
+++ b/NEWS
@@ -14,6 +14,7 @@ Morten:
* Fix xls read crash. [#679992]
* Reduce code duplication for dependents.
* Make cells regular dependents.
+ * Fix non-linear solver crash. [#680719]
--------------------------------------------------------------------------
Gnumeric 1.11.5
diff --git a/plugins/nlsolve/ChangeLog b/plugins/nlsolve/ChangeLog
index 3d25675..c1e4425 100644
--- a/plugins/nlsolve/ChangeLog
+++ b/plugins/nlsolve/ChangeLog
@@ -1,3 +1,8 @@
+2012-07-27 Morten Welinder <terra gnome org>
+
+ * gnm-nlsolve.c (rosenbrock_iter): Fix crash and marginally
+ improve precision.
+
2012-07-15 Morten Welinder <terra gnome org>
* Release 1.11.5
diff --git a/plugins/nlsolve/gnm-nlsolve.c b/plugins/nlsolve/gnm-nlsolve.c
index 5879bab..ac061ed 100644
--- a/plugins/nlsolve/gnm-nlsolve.c
+++ b/plugins/nlsolve/gnm-nlsolve.c
@@ -536,10 +536,16 @@ rosenbrock_iter (GnmNlsolve *nl)
}
}
- div = sqrt (t[0]);
- for (i = 0; i < n; i++) {
- nl->xi[0][i] = A[0][i] / div;
- g_assert (gnm_finite (nl->xi[0][i]));
+ gnm_range_hypot (dx, n, &div);
+ if (div != 0) {
+ for (i = 0; i < n; i++) {
+ nl->xi[0][i] = A[0][i] / div;
+ if (!gnm_finite (nl->xi[0][i])) {
+ g_printerr ("%g %g %g\n",
+ div, A[0][i], nl->xi[0][i]);
+ g_assert (gnm_finite (nl->xi[0][i]));
+ }
+ }
}
/* ---------------------------------------- */
diff --git a/src/rangefunc.c b/src/rangefunc.c
index 4d7e708..2a36a72 100644
--- a/src/rangefunc.c
+++ b/src/rangefunc.c
@@ -26,6 +26,12 @@ gnm_range_count (G_GNUC_UNUSED gnm_float const *xs, int n, gnm_float *res)
int
gnm_range_hypot (gnm_float const *xs, int n, gnm_float *res)
{
+ /* Drop outside zeros because the n<=2 cases are more accurate. */
+ while (n > 0 && xs[0] == 0)
+ xs++, n--;
+ while (n > 0 && xs[n - 1] == 0)
+ n--;
+
switch (n) {
case 0: *res = 0; return 0;
case 1: *res = gnm_abs (xs[0]); return 0;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]