[gnumeric] regression: produce results when we get GO_REG_near_singular_good.



commit f3daae036ce9155bf1afba8e0678e4ab3dea3282
Author: Morten Welinder <terra gnome org>
Date:   Fri Apr 16 14:43:51 2010 -0400

    regression: produce results when we get GO_REG_near_singular_good.

 NEWS                        |    2 +
 plugins/fn-stat/ChangeLog   |    6 +++
 plugins/fn-stat/functions.c |   87 ++++++++++++++++++++++++++++++++++--------
 3 files changed, 78 insertions(+), 17 deletions(-)
---
diff --git a/NEWS b/NEWS
index 391fbd6..b838b3b 100644
--- a/NEWS
+++ b/NEWS
@@ -33,6 +33,8 @@ Morten:
 	* Fix xls export of cell comments.  [#615845]
 	* Fix error propagation problem.  [#615772]
 	* Partially clean up INDEX implementation.
+	* Make regression functions return a result when goffice reports
+	  that the problem is near singular, but still good.
 
 --------------------------------------------------------------------------
 Gnumeric 1.10.1
diff --git a/plugins/fn-stat/ChangeLog b/plugins/fn-stat/ChangeLog
index 77e910d..7ee1b72 100644
--- a/plugins/fn-stat/ChangeLog
+++ b/plugins/fn-stat/ChangeLog
@@ -1,3 +1,9 @@
+2010-04-16  Morten Welinder  <terra gnome org>
+
+	* functions.c (gnumeric_linest, gnumeric_trend, gnumeric_forecast,
+	range_slope, range_intercept, gnumeric_logreg, gnumeric_logest,
+	gnumeric_growth): Handle near-singular case.
+
 2010-04-04  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* functions.c (help_ztest): fix description. [#614746]
diff --git a/plugins/fn-stat/functions.c b/plugins/fn-stat/functions.c
index 2e8930b..5435bf4 100644
--- a/plugins/fn-stat/functions.c
+++ b/plugins/fn-stat/functions.c
@@ -3296,6 +3296,7 @@ gnumeric_linest (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 		OTHER      = 4
 	}                 ytype;
 	gnm_regression_stat_t *extra_stat;
+	GORegressionResult regres;
 
 	extra_stat = gnm_regression_stat_new ();
 	dim = 0;
@@ -3453,8 +3454,13 @@ gnumeric_linest (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 	linres = g_new (gnm_float, dim + 1);
 
-	if (gnm_linear_regression (xss, dim, ys, nx, affine,
-			       linres, extra_stat) != GO_REG_ok) {
+	regres = gnm_linear_regression (xss, dim, ys, nx, affine,
+					linres, extra_stat);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
 		result = value_new_error_NUM (ei->pos);
 		goto out;
 	}
@@ -3558,6 +3564,7 @@ gnumeric_logreg (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 	int               xarg = 1;
 	gnm_float        *logreg_res = NULL;
 	gboolean          affine, stat, err;
+	GORegressionResult regres;
 	enum {
 		ARRAY      = 1,
 		SINGLE_COL = 2,
@@ -3713,8 +3720,13 @@ gnumeric_logreg (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 	logreg_res = g_new (gnm_float, dim + 1);
 
-	if (gnm_logarithmic_regression (xss, dim, ys, nx, affine,
-				    logreg_res, extra_stat) != GO_REG_ok) {
+	regres = gnm_logarithmic_regression (xss, dim, ys, nx, affine,
+					     logreg_res, extra_stat);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
 		result = value_new_error_NUM (ei->pos);
 		goto out;
 	}
@@ -3881,6 +3893,7 @@ gnumeric_trend (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 	int      nx, ny, nnx, i, dim;
 	gboolean affine, err;
 	gnm_float  linres[2];
+	GORegressionResult regres;
 
 	ys = collect_floats_value (argv[0], ei->pos,
 				   COLLECT_IGNORE_STRINGS |
@@ -3944,8 +3957,12 @@ gnumeric_trend (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 	dim = 1;
 
-	if (gnm_linear_regression (&xs, dim, ys, nx, affine, linres, NULL) !=
-	    GO_REG_ok) {
+	regres = gnm_linear_regression (&xs, dim, ys, nx, 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;
 	}
@@ -3999,6 +4016,7 @@ gnumeric_logest (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 	gnm_float        *expres = NULL;
 	gboolean          stat, err;
 	gnm_regression_stat_t *extra_stat;
+	GORegressionResult regres;
 	enum {
 		ARRAY      = 1,
 		SINGLE_COL = 2,
@@ -4150,8 +4168,13 @@ gnumeric_logest (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 		stat = FALSE;
 
 	expres = g_new (gnm_float, dim + 1);
-	if (gnm_exponential_regression (xss, dim, ys, nx, affine,
-				    expres, extra_stat) != GO_REG_ok) {
+	regres = gnm_exponential_regression (xss, dim, ys, nx, affine,
+					     expres, extra_stat);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
 		result = value_new_error_NUM (ei->pos);
 		goto out;
 	}
@@ -4223,6 +4246,7 @@ gnumeric_growth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 	gboolean affine, err;
 	int      nx, ny, nnx, i, dim;
 	gnm_float  expres[2];
+	GORegressionResult regres;
 
 	affine = TRUE;
 
@@ -4288,8 +4312,13 @@ gnumeric_growth (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 	dim = 1;
 
-	if (gnm_exponential_regression (&xs, dim,
-				    ys, nx, affine, expres, NULL) != GO_REG_ok) {
+	regres = gnm_exponential_regression (&xs, dim,
+					     ys, nx, affine, expres, NULL);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
 		result = value_new_error_NUM (ei->pos);
 		goto out;
 	}
@@ -4338,6 +4367,7 @@ gnumeric_forecast (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 	GnmValue *result = NULL;
 	int nx, ny, dim;
 	gnm_float linres[2];
+	GORegressionResult regres;
 
 	x = value_get_as_float (argv[0]);
 
@@ -4362,7 +4392,12 @@ gnumeric_forecast (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 	dim = 1;
 
-	if (gnm_linear_regression (&xs, dim, ys, nx, 1, linres, NULL) != GO_REG_ok) {
+	regres = gnm_linear_regression (&xs, dim, ys, nx, 1, 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;
 	}
@@ -4399,11 +4434,20 @@ range_intercept (gnm_float const *xs, gnm_float const *ys, int n, gnm_float *res
 {
 	gnm_float linres[2];
 	int dim = 1;
+	GORegressionResult regres;
+
+	if (n <= 0)
+		return 1;
 
-	if (n <= 0 ||
-	    gnm_linear_regression ((gnm_float **)&xs, dim,
-				   ys, n, 1, linres, NULL) != GO_REG_ok)
+	regres = gnm_linear_regression ((gnm_float **)&xs, dim,
+					ys, n, 1, linres, NULL);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
 		return 1;
+	}
 
 	*res = linres[0];
 	return 0;
@@ -4445,12 +4489,21 @@ range_slope (gnm_float const *xs, gnm_float const *ys, int n, gnm_float *res)
 {
 	gnm_float linres[2];
 	int dim = 1;
+	GORegressionResult regres;
 
-	if (n <= 0 ||
-	    gnm_linear_regression ((gnm_float **)&xs, dim,
-				   ys, n, 1, linres, NULL) != GO_REG_ok)
+	if (n <= 0)
 		return 1;
 
+	regres = gnm_linear_regression ((gnm_float **)&xs, dim,
+					ys, n, 1, linres, NULL);
+	switch (regres) {
+	case GO_REG_ok:
+	case GO_REG_near_singular_good:
+		break;
+	default:
+		return 1;
+	}
+
 	*res = linres[1];
 	return 0;
 }



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