[gnumeric] FORECAST: handle missing data properly.



commit 3a7b5d6b23cbb833d20938707f3b1306672b27b8
Author: Morten Welinder <terra gnome org>
Date:   Mon Jun 14 08:49:23 2010 -0400

    FORECAST: handle missing data properly.

 NEWS                        |    1 +
 plugins/fn-stat/ChangeLog   |    5 +++
 plugins/fn-stat/functions.c |   62 ++++++++++++++++++-------------------------
 3 files changed, 32 insertions(+), 36 deletions(-)
---
diff --git a/NEWS b/NEWS
index bd8721e..2409b33 100644
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,7 @@ Morten:
 	* Fix hidden-sheet problem.  [#621463]
 	* Improve help text sanity checks.
 	* Fix minor parsing problem.
+	* Handle missing data in FORECAST properly.  [#621417]
 
 --------------------------------------------------------------------------
 Gnumeric 1.10.5
diff --git a/plugins/fn-stat/ChangeLog b/plugins/fn-stat/ChangeLog
index ff68b45..023f8ca 100644
--- a/plugins/fn-stat/ChangeLog
+++ b/plugins/fn-stat/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-14  Morten Welinder  <terra gnome org>
+
+	* functions.c (gnumeric_forecast): Handle missing data properly.
+	Fixes #621417.
+
 2010-06-13  Morten Welinder  <terra gnome org>
 
 	* functions.c (gnumeric_growth): Simplify.
diff --git a/plugins/fn-stat/functions.c b/plugins/fn-stat/functions.c
index 8d76346..f50ac3d 100644
--- a/plugins/fn-stat/functions.c
+++ b/plugins/fn-stat/functions.c
@@ -4022,55 +4022,45 @@ static GnmFuncHelp const help_forecast[] = {
 	{ GNM_FUNC_HELP_END }
 };
 
-
-static GnmValue *
-gnumeric_forecast (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+static int
+range_forecast (gnm_float const *xs, gnm_float const *ys, int n, gnm_float *res, gpointer user)
 {
-	gnm_float x, *xs = NULL, *ys = NULL;
-	GnmValue *result = NULL;
-	int nx, ny, dim;
+	gnm_float const *px = user;
 	gnm_float linres[2];
+	int dim = 1;
+	gboolean affine = TRUE;
 	GORegressionResult regres;
 
-	x = value_get_as_float (argv[0]);
-
-	ys = collect_floats_value (argv[1], ei->pos,
-				   COLLECT_IGNORE_STRINGS |
-				   COLLECT_IGNORE_BOOLS,
-				   &ny, &result);
-	if (result)
-		goto out;
-
-	xs = collect_floats_value (argv[2], ei->pos,
-				   COLLECT_IGNORE_STRINGS |
-				   COLLECT_IGNORE_BOOLS,
-				   &nx, &result);
-	if (result)
-		goto out;
-
-	if (nx != ny) {
-		result = value_new_error_NUM (ei->pos);
-		goto out;
-	}
-
-	dim = 1;
+	if (n <= 0)
+		return 1;
 
-	regres = gnm_linear_regression (&xs, dim, ys, nx, 1, linres, NULL);
+	regres = gnm_linear_regression ((gnm_float **)&xs, dim,
+					ys, n, affine, linres, NULL);
 	switch (regres) {
 	case GO_REG_ok:
 	case GO_REG_near_singular_good:
 		break;
 	default:
-		result = value_new_error_NUM (ei->pos);
-		goto out;
+		return 1;
 	}
 
-	result = value_new_float (linres[0] + x * linres[1]);
+	*res = linres[0] + (*px) * linres[1];
+	return 0;
+}
 
- out:
-	g_free (xs);
-	g_free (ys);
-	return result;
+static GnmValue *
+gnumeric_forecast (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	gnm_float x = value_get_as_float (argv[0]);
+
+	return float_range_function2d (argv[2], argv[1],
+				       ei,
+				       range_forecast,
+				       COLLECT_IGNORE_BLANKS |
+				       COLLECT_IGNORE_STRINGS |
+				       COLLECT_IGNORE_BOOLS,
+				       GNM_ERROR_VALUE,
+				       &x);
 }
 
 /***************************************************************************/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]