? autogen_output ? make_output ? stamp-h1 ? update_output ? gnumeric-multidim-reg.diff Index: plugins/fn-stat/ChangeLog =================================================================== RCS file: /cvs/gnome/gnumeric/plugins/fn-stat/ChangeLog,v retrieving revision 1.28 diff -u -3 -p -r1.28 ChangeLog --- plugins/fn-stat/ChangeLog 8 Nov 2002 04:51:05 -0000 1.28 +++ plugins/fn-stat/ChangeLog 12 Nov 2002 16:52:45 -0000 @@ -1,3 +1,9 @@ +2002-11-07 Olaf Till + + * functions.c: Move most code of gnumeric_linest into a helper + function multidim_linear_regression, called by gnumeric_linest, + gnumeric_logest, and gnumeric_logreg. + 2002-11-07 Jody Goldberg * functions.c (gnumeric_logreg, gnumeric_logfit): correct status. Index: plugins/fn-stat/functions.c =================================================================== RCS file: /cvs/gnome/gnumeric/plugins/fn-stat/functions.c,v retrieving revision 1.199 diff -u -3 -p -r1.199 functions.c --- plugins/fn-stat/functions.c 8 Nov 2002 04:51:06 -0000 1.199 +++ plugins/fn-stat/functions.c 12 Nov 2002 16:52:46 -0000 @@ -3794,64 +3794,26 @@ gnumeric_frequency (FunctionEvalInfo *ei /***************************************************************************/ -static const char *help_linest = { - N_("@FUNCTION=LINEST\n" - "@SYNTAX=LINEST(known_y's[,known_x's[,const[,stat]]])\n" - - "@DESCRIPTION=" - "LINEST function calculates the ``least squares'' line that best " - "fit to your data in @known_y's. @known_x's contains the " - "corresponding x's where y=mx+b.\n" - "\n" - "LINEST returns an array having two columns and one row. The " - "slope (m) of the regression line y=mx+b is given in the first " - "column and the y-intercept (b) in the second.\n" - "\n" - "If @stat is TRUE, extra statistical information will be returned. " - "Extra statistical information is written bellow the regression " - "line coefficients in the result array. Extra statistical " - "information consists of four rows of data. In the first row " - "the standard error values for the coefficients m1, (m2, ...), b " - "are represented. The second row contains the square of R and " - "the standard error for the y estimate. The third row contains " - "the F-observed value and the degrees of freedom. The last row " - "contains the regression sum of squares and the residual sum " - "of squares.\n" - "\n" - "* If @known_x's is omitted, an array {1, 2, 3, ...} is used.\n" - "If @known_y's and @known_x's have unequal number of data points, " - "LINEST returns #NUM! error." - "\n" - "* If @const is FALSE, the line will be forced to go through the " - "origin, i.e., b will be zero. The default is TRUE.\n" - "* The default of @stat is FALSE.\n" - "\n" - "@EXAMPLES=\n" - "\n" - "@SEEALSO=LOGEST,TREND") -}; - -/* Notes for now, to be incorporated into help when it actually works: - * - * Entered as linest(Yrange, [Xrange, [Intercept, [Stat]]]). Intercept and Stat - * work as above. According to playing with Excel, if Yrange is an array, Xrange - * must be an array. They claim that you can use semicolons to separate rows in - * an array, but I've never gotten that to work. If Yrange is a single column, - * every column in the Xrange (which must be a cell range) is interpreted as a - * separate variable. Similar for a single row. If Y is a blob, X is interpreted - * as a single variable blob. Experiments suggest that multivariable blobs don't work. - * Currently everything should be implemented except for inputting arrays. X's must - * be contiguous so far as I can tell. - */ - -static Value * -gnumeric_linest (FunctionEvalInfo *ei, Value *argv[]) +typedef RegressionResult (* linear_regression_func) (gnum_float **xss, int dim, + const gnum_float *ys, + int n, gboolean affine, + gnum_float *res, + regression_stat_t *stat); + +/* The code of this function was originally a part of gnumeric_linest, + * please see also the comment there. + * It has been taken out from there to be called by any gnumeric function + * which performs a transformation of data and otherwise works the same way + * as gnumeric_linest. */ + +static void +multidim_linear_regression (FunctionEvalInfo *ei, Value *argv[], + Value **result, linear_regression_func reg_func) { gnum_float **xss = NULL, *ys = NULL; - Value *result = NULL; int nx, ny, dim, i; int xarg = 0; - gnum_float *linres = NULL; + gnum_float *reg_res = NULL; gboolean affine, stat, err; enum { ARRAY = 1, @@ -3880,14 +3842,14 @@ gnumeric_linest (FunctionEvalInfo *ei, V ys = collect_floats_value (argv[0], ei->pos, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS, - &ny, &result); + &ny, result); else if (argv[0]->type == VALUE_ARRAY){ /* * Get ys from array argument argv[0] */ } - if (result) + if (*result) goto out; /* TODO Better error-checking in next statement */ @@ -3926,8 +3888,8 @@ gnumeric_linest (FunctionEvalInfo *ei, V xss[i - firstcol] = collect_floats_value (copy, ei->pos, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ + &nx, result); + if (*result){ value_release (copy); dim = i - firstcol; /* How many got allocated before failure*/ goto out; @@ -3935,7 +3897,7 @@ gnumeric_linest (FunctionEvalInfo *ei, V if (nx != ny){ value_release (copy); dim = i - firstcol + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); + *result = value_new_error (ei->pos, gnumeric_err_NUM); goto out; } } @@ -3963,8 +3925,8 @@ gnumeric_linest (FunctionEvalInfo *ei, V xss[i - firstrow] = collect_floats_value (copy, ei->pos, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ + &nx, result); + if (*result){ value_release (copy); dim = i - firstrow; /*How many got allocated before failure*/ goto out; @@ -3972,7 +3934,7 @@ gnumeric_linest (FunctionEvalInfo *ei, V if (nx != ny){ value_release (copy); dim = i - firstrow + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); + *result = value_new_error (ei->pos, gnumeric_err_NUM); goto out; } } @@ -3985,14 +3947,14 @@ gnumeric_linest (FunctionEvalInfo *ei, V xss[0] = collect_floats_value (argv[1], ei->pos, COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ + &nx, result); + if (*result){ dim = 0; goto out; } if (nx != ny){ dim = 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); + *result = value_new_error (ei->pos, gnumeric_err_NUM); goto out; } } @@ -4000,7 +3962,8 @@ gnumeric_linest (FunctionEvalInfo *ei, V if (argv[1 + xarg]) { affine = value_get_as_bool (argv[1 + xarg], &err); if (err) { - result = value_new_error (ei->pos, gnumeric_err_VALUE); + *result = value_new_error (ei->pos, + gnumeric_err_VALUE); goto out; } } else @@ -4009,48 +3972,48 @@ gnumeric_linest (FunctionEvalInfo *ei, V if (argv[2 + xarg]) { stat = value_get_as_bool (argv[2 + xarg], &err); if (err) { - result = value_new_error (ei->pos, - gnumeric_err_VALUE); + *result = value_new_error (ei->pos, + gnumeric_err_VALUE); goto out; } } else stat = FALSE; - linres = g_new (gnum_float, dim + 1); + reg_res = g_new (gnum_float, dim + 1); - if (linear_regression (xss, dim, ys, nx, affine, - linres, extra_stat) != REG_ok) { - result = value_new_error (ei->pos, gnumeric_err_NUM); + if (reg_func (xss, dim, ys, nx, affine, + reg_res, extra_stat) != REG_ok) { + *result = value_new_error (ei->pos, gnumeric_err_NUM); goto out; } if (stat) { - result = value_new_array (dim + 1, 5); + *result = value_new_array (dim + 1, 5); - value_array_set (result, 0, 2, + value_array_set (*result, 0, 2, value_new_float (extra_stat->sqr_r)); - value_array_set (result, 1, 2, + value_array_set (*result, 1, 2, value_new_float (sqrtgnum (extra_stat->var))); - value_array_set (result, 0, 3, + value_array_set (*result, 0, 3, value_new_float (extra_stat->F)); - value_array_set (result, 1, 3, + value_array_set (*result, 1, 3, value_new_float (extra_stat->df_resid)); - value_array_set (result, 0, 4, + value_array_set (*result, 0, 4, value_new_float (extra_stat->ss_reg)); - value_array_set (result, 1, 4, + value_array_set (*result, 1, 4, value_new_float (extra_stat->ss_resid)); for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 1, + value_array_set (*result, dim - i - 1, 1, value_new_float (extra_stat->se[i+affine])); - value_array_set (result, dim, 1, + value_array_set (*result, dim, 1, value_new_float (extra_stat->se[0])); } else - result = value_new_array (dim + 1, 1); + *result = value_new_array (dim + 1, 1); - value_array_set (result, dim, 0, value_new_float (linres[0])); + value_array_set (*result, dim, 0, value_new_float (reg_res[0])); for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 0, - value_new_float (linres[i + 1])); + value_array_set (*result, dim - i - 1, 0, + value_new_float (reg_res[i + 1])); out: if (xss) { @@ -4059,9 +4022,67 @@ gnumeric_linest (FunctionEvalInfo *ei, V g_free (xss); } g_free (ys); - g_free (linres); + g_free (reg_res); regression_stat_destroy (extra_stat); + return; +} + +static const char *help_linest = { + N_("@FUNCTION=LINEST\n" + "@SYNTAX=LINEST(known_y's[,known_x's[,const[,stat]]])\n" + + "@DESCRIPTION=" + "LINEST function calculates the ``least squares'' line that best " + "fit to your data in @known_y's. @known_x's contains the " + "corresponding x's where y=mx+b.\n" + "\n" + "LINEST returns an array having two columns and one row. The " + "slope (m) of the regression line y=mx+b is given in the first " + "column and the y-intercept (b) in the second.\n" + "\n" + "If @stat is TRUE, extra statistical information will be returned. " + "Extra statistical information is written bellow the regression " + "line coefficients in the result array. Extra statistical " + "information consists of four rows of data. In the first row " + "the standard error values for the coefficients m1, (m2, ...), b " + "are represented. The second row contains the square of R and " + "the standard error for the y estimate. The third row contains " + "the F-observed value and the degrees of freedom. The last row " + "contains the regression sum of squares and the residual sum " + "of squares.\n" + "\n" + "* If @known_x's is omitted, an array {1, 2, 3, ...} is used.\n" + "If @known_y's and @known_x's have unequal number of data points, " + "LINEST returns #NUM! error." + "\n" + "* If @const is FALSE, the line will be forced to go through the " + "origin, i.e., b will be zero. The default is TRUE.\n" + "* The default of @stat is FALSE.\n" + "\n" + "@EXAMPLES=\n" + "\n" + "@SEEALSO=LOGEST,TREND") +}; + +/* Notes for now, to be incorporated into help when it actually works: + * + * Entered as linest(Yrange, [Xrange, [Intercept, [Stat]]]). Intercept and Stat + * work as above. According to playing with Excel, if Yrange is an array, Xrange + * must be an array. They claim that you can use semicolons to separate rows in + * an array, but I've never gotten that to work. If Yrange is a single column, + * every column in the Xrange (which must be a cell range) is interpreted as a + * separate variable. Similar for a single row. If Y is a blob, X is interpreted + * as a single variable blob. Experiments suggest that multivariable blobs don't work. + * Currently everything should be implemented except for inputting arrays. X's must + * be contiguous so far as I can tell. + */ + +static Value * +gnumeric_linest (FunctionEvalInfo *ei, Value *argv[]) +{ + Value *result = NULL; + multidim_linear_regression (ei, argv, &result, linear_regression); return result; } @@ -4105,11 +4126,9 @@ static const char *help_logreg = { "\n" "@SEEALSO=LOGFIT,LINEST,LOGEST") }; -/* The following is a copy of "gnumeric_linest" of Gnumeric version 1.1.9 - * with "linear_regression" replaced by "logarithmic_regression". - * - * In Excel, this functionality is not available as a function, but only - * as a "trend curve" within graphs. + +/* In Excel, the functionality of LOGREG is not available as a function, + * but only as a "trend curve" within graphs. * * The function "logarithmic_regression" transforms x's logarithmically * before calling "general_linear_regression" written by others. @@ -4125,221 +4144,8 @@ static const char *help_logreg = { static Value * gnumeric_logreg (FunctionEvalInfo *ei, Value *argv[]) { - gnum_float **xss = NULL, *ys = NULL; - Value *result = NULL; - int nx, ny, dim, i; - int xarg = 0; - gnum_float *logreg_res = NULL; - gboolean affine, stat, err; - enum { - ARRAY = 1, - SINGLE_COL = 2, - SINGLE_ROW = 3, - OTHER = 4 - } ytype; - regression_stat_t *extra_stat; - - extra_stat = regression_stat_new (); - dim = 0; - - if (argv[0] == NULL || (argv[0]->type != VALUE_ARRAY && argv[0]->type != VALUE_CELLRANGE)){ - goto out; /* Not a valid input for ys */ - } - - if (argv[0]->type == VALUE_ARRAY) - ytype = ARRAY; - else if (argv[0]->v_range.cell.a.col == argv[0]->v_range.cell.b.col) - ytype = SINGLE_COL; - else if (argv[0]->v_range.cell.a.row == argv[0]->v_range.cell.b.row) - ytype = SINGLE_ROW; - else ytype = OTHER; - - if (argv[0]->type == VALUE_CELLRANGE) - ys = collect_floats_value (argv[0], ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &ny, &result); - else if (argv[0]->type == VALUE_ARRAY){ - /* - * Get ys from array argument argv[0] - */ - } - - if (result) - goto out; - - /* TODO Better error-checking in next statement */ - - if (argv[1] == NULL || (ytype == ARRAY && argv[1]->type != VALUE_ARRAY) || - (ytype != ARRAY && argv[1]->type != VALUE_CELLRANGE)){ - dim = 1; - xss = g_new (gnum_float *, 1); - xss[0] = g_new (gnum_float, ny); - for (nx = 0; nx < ny; nx++) - xss[0][nx] = nx + 1; - } - else if (ytype == ARRAY){ - xarg = 1; - /* Get xss from array argument argv[1] */ - } - else if (ytype == SINGLE_COL){ - int firstcol, lastcol; - Value *copy; - xarg = 1; - firstcol = argv[1]->v_range.cell.a.col; - lastcol = argv[1]->v_range.cell.b.col; - - if (firstcol < lastcol) { - int tmp = firstcol; - firstcol = lastcol; - lastcol = tmp; - } - - dim = lastcol - firstcol + 1; - copy = value_duplicate (argv[1]); - xss = g_new (gnum_float *, dim); - for (i = firstcol; i <= lastcol; i++){ - copy->v_range.cell.a.col = i; - copy->v_range.cell.b.col = i; - xss[i - firstcol] = collect_floats_value (copy, ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - value_release (copy); - dim = i - firstcol; /* How many got allocated before failure*/ - goto out; - } - if (nx != ny){ - value_release (copy); - dim = i - firstcol + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - value_release (copy); - } - else if (ytype == SINGLE_ROW){ - int firstrow, lastrow; - Value *copy; - xarg = 1; - firstrow = argv[1]->v_range.cell.a.row; - lastrow = argv[1]->v_range.cell.b.row; - - if (firstrow < lastrow) { - int tmp = firstrow; - firstrow = lastrow; - lastrow = tmp; - } - - dim = lastrow - firstrow + 1; - copy = value_duplicate (argv[1]); - xss = g_new (gnum_float *, dim); - for (i = firstrow; i <= lastrow; i++){ - copy->v_range.cell.a.row = i; - copy->v_range.cell.b.row = i; - xss[i - firstrow] = collect_floats_value (copy, ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - value_release (copy); - dim = i - firstrow; /*How many got allocated before failure*/ - goto out; - } - if (nx != ny){ - value_release (copy); - dim = i - firstrow + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - value_release (copy); - } - else { /*Y is none of the above */ - xarg = 1; - dim = 1; - xss = g_new (gnum_float *, dim); - xss[0] = collect_floats_value (argv[1], ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - dim = 0; - goto out; - } - if (nx != ny){ - dim = 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - - if (argv[1 + xarg]) { - affine = value_get_as_bool (argv[1 + xarg], &err); - if (err) { - result = value_new_error (ei->pos, gnumeric_err_VALUE); - goto out; - } - } else - affine = TRUE; - - if (argv[2 + xarg]) { - stat = value_get_as_bool (argv[2 + xarg], &err); - if (err) { - result = value_new_error (ei->pos, - gnumeric_err_VALUE); - goto out; - } - } else - stat = FALSE; - - logreg_res = g_new (gnum_float, dim + 1); - - if (logarithmic_regression (xss, dim, ys, nx, affine, - logreg_res, extra_stat) != REG_ok) { - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - - if (stat) { - result = value_new_array (dim + 1, 5); - - value_array_set (result, 0, 2, - value_new_float (extra_stat->sqr_r)); - value_array_set (result, 1, 2, - value_new_float (sqrtgnum (extra_stat->var))); - value_array_set (result, 0, 3, - value_new_float (extra_stat->F)); - value_array_set (result, 1, 3, - value_new_float (extra_stat->df_resid)); - value_array_set (result, 0, 4, - value_new_float (extra_stat->ss_reg)); - value_array_set (result, 1, 4, - value_new_float (extra_stat->ss_resid)); - for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 1, - value_new_float (extra_stat->se[i+affine])); - value_array_set (result, dim, 1, - value_new_float (extra_stat->se[0])); - } else - result = value_new_array (dim + 1, 1); - - value_array_set (result, dim, 0, value_new_float (logreg_res[0])); - for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 0, - value_new_float (logreg_res[i + 1])); - - out: - if (xss) { - for (i = 0; i < dim; i++) - g_free (xss[i]); - g_free (xss); - } - g_free (ys); - g_free (logreg_res); - regression_stat_destroy (extra_stat); - + Value *result = NULL; + multidim_linear_regression (ei, argv, &result, logarithmic_regression); return result; } @@ -4594,219 +4400,21 @@ static const char *help_logest = { static Value * gnumeric_logest (FunctionEvalInfo *ei, Value *argv[]) { - gnum_float **xss = NULL, *ys = NULL; - Value *result = NULL; - int affine, nx, ny, dim, i; - int xarg = 0; - gnum_float *expres = NULL; - gboolean stat, err; - regression_stat_t *extra_stat; - enum { - ARRAY = 1, - SINGLE_COL = 2, - SINGLE_ROW = 3, - OTHER = 4 - } ytype; - - extra_stat = regression_stat_new (); - dim = 0; - - if (argv[0] == NULL || (argv[0]->type != VALUE_ARRAY && argv[0]->type != VALUE_CELLRANGE)){ - goto out; /* Not a valid input for ys */ - } - - if (argv[0]->type == VALUE_ARRAY) - ytype = ARRAY; - else if (argv[0]->v_range.cell.a.col == argv[0]->v_range.cell.b.col) - ytype = SINGLE_COL; - else if (argv[0]->v_range.cell.a.row == argv[0]->v_range.cell.b.row) - ytype = SINGLE_ROW; - else ytype = OTHER; - - if (argv[0]->type == VALUE_CELLRANGE) - ys = collect_floats_value (argv[0], ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &ny, &result); - else if (argv[0]->type == VALUE_ARRAY){ - /* - * Get ys from array argument argv[0] - */ - } - - if (result) - goto out; - - /* TODO Better error-checking in next statement */ - - if (argv[1] == NULL || (ytype == ARRAY && argv[1]->type != VALUE_ARRAY) || - (ytype != ARRAY && argv[1]->type != VALUE_CELLRANGE)){ - dim = 1; - xss = g_new (gnum_float *, 1); - xss[0] = g_new (gnum_float, ny); - for (nx = 0; nx < ny; nx++) - xss[0][nx] = nx + 1; - } - else if (ytype == ARRAY){ - xarg = 1; - /* Get xss from array argument argv[1] */ - } - else if (ytype == SINGLE_COL){ - int firstcol, lastcol; - Value *copy; - xarg = 1; - firstcol = argv[1]->v_range.cell.a.col; - lastcol = argv[1]->v_range.cell.b.col; - if (firstcol < lastcol) { - int tmp = firstcol; - firstcol = lastcol; - lastcol = tmp; - } - - dim = lastcol - firstcol + 1; - copy = value_duplicate (argv[1]); - xss = g_new (gnum_float *, dim); - for (i = firstcol; i <= lastcol; i++){ - copy->v_range.cell.a.col = i; - copy->v_range.cell.b.col = i; - xss[i - firstcol] = collect_floats_value (copy, ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - value_release (copy); - dim = i - firstcol; /*How many got allocated before failure*/ - goto out; - } - if (nx != ny){ - value_release (copy); - dim = i - firstcol + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - value_release (copy); - } - else if (ytype == SINGLE_ROW){ - int firstrow, lastrow; - Value *copy; - xarg = 1; - firstrow = argv[1]->v_range.cell.a.row; - lastrow = argv[1]->v_range.cell.b.row; - - if (firstrow < lastrow) { - int tmp = firstrow; - firstrow = lastrow; - lastrow = tmp; - } - - dim = lastrow - firstrow + 1; - copy = value_duplicate (argv[1]); - xss = g_new (gnum_float *, dim); - for (i = firstrow; i <= lastrow; i++){ - copy->v_range.cell.a.row = i; - copy->v_range.cell.b.row = i; - xss[i - firstrow] = collect_floats_value (copy, ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - value_release (copy); - dim = i - firstrow; /*How many got allocated before failure*/ - goto out; - } - if (nx != ny){ - value_release (copy); - dim = i - firstrow + 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - value_release (copy); - } - else { /*Y is none of the above */ - xarg = 1; - dim = 1; - xss = g_new (gnum_float *, dim); - xss[0] = collect_floats_value (argv[1], ei->pos, - COLLECT_IGNORE_STRINGS | - COLLECT_IGNORE_BOOLS, - &nx, &result); - if (result){ - dim = 0; - goto out; - } - if (nx != ny){ - dim = 1; - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - } - - if (argv[1 + xarg]) { - affine = value_get_as_bool (argv[1 + xarg], &err) ? 1 : 0; - if (err) { - result = value_new_error (ei->pos, gnumeric_err_VALUE); - goto out; - } - } else - affine = 1; - - if (argv[2 + xarg]) { - stat = value_get_as_bool (argv[2 + xarg], &err); - if (err) { - result = value_new_error (ei->pos, - gnumeric_err_VALUE); - goto out; - } - } else - stat = FALSE; - - expres = g_new (gnum_float, dim + 1); - if (exponential_regression (xss, dim, ys, nx, affine, - expres, extra_stat) != REG_ok) { - result = value_new_error (ei->pos, gnumeric_err_NUM); - goto out; - } - - if (stat) { - result = value_new_array (dim + 1, 5); - - value_array_set (result, 0, 2, - value_new_float (extra_stat->sqr_r)); - value_array_set (result, 1, 2, - value_new_float (sqrtgnum (extra_stat->var))); /* Still wrong ! */ - value_array_set (result, 0, 3, - value_new_float (extra_stat->F)); - value_array_set (result, 1, 3, - value_new_float (extra_stat->df_resid)); - value_array_set (result, 0, 4, - value_new_float (extra_stat->ss_reg)); - value_array_set (result, 1, 4, - value_new_float (extra_stat->ss_resid)); - for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 1, - value_new_float (extra_stat->se[i + affine])); - value_array_set (result, dim, 1, - value_new_float (extra_stat->se[0])); - } else - result = value_new_array (dim + 1, 1); - - value_array_set (result, dim, 0, value_new_float (expres[0])); - for (i = 0; i < dim; i++) - value_array_set (result, dim - i - 1, 0, value_new_float (expres[i + 1])); - - out: - if (xss) { - for (i = 0; i < dim; i++) - g_free (xss[i]); - g_free (xss); - } - g_free (ys); - g_free (expres); - regression_stat_destroy (extra_stat); - + Value *result = NULL; + multidim_linear_regression (ei, argv, &result, exponential_regression); return result; + /* By reorganizing the code I killed the following comment, + * which I do not understand: + * + * Still wrong ! + * + * which was before the following source line: + * + * value_array_set (result, 0, 3, + * value_new_float (extra_stat->F)); + * + * The respective code is now in multidim_linear_regression () + * Olaf */ } /***************************************************************************/ Index: src/regression.c =================================================================== RCS file: /cvs/gnome/gnumeric/src/regression.c,v retrieving revision 1.40 diff -u -3 -p -r1.40 regression.c --- src/regression.c 5 Nov 2002 22:27:11 -0000 1.40 +++ src/regression.c 12 Nov 2002 16:52:49 -0000 @@ -510,7 +510,7 @@ log_fitting (gnum_float *xs, const gnum_ gnum_float *res, point_cloud_measure_type *point_cloud) { int result = REG_ok; - gboolean sign_plus_ok = 1, sign_minus_ok = 1; + gboolean sign_plus_ok = TRUE, sign_minus_ok = TRUE; gnum_float x_range, c_step, c_accuracy_int, c_offset, c_accuracy; gnum_float c_range, c_start, c_end, c_dist; gnum_float *temp_res; @@ -548,7 +548,7 @@ log_fitting (gnum_float *xs, const gnum_ transform_x_and_linear_regression_log_fitting (xs, transf_xs, ys, n, temp_res, point_cloud); if (temp_res[4] <= res[4]) - sign_plus_ok = 0; + sign_plus_ok = FALSE; /* check again with new sign */ res[0] = -1; /* sign */ res[3] = point_cloud->max_x + c_range; @@ -559,7 +559,7 @@ log_fitting (gnum_float *xs, const gnum_ transform_x_and_linear_regression_log_fitting (xs, transf_xs, ys, n, temp_res, point_cloud); if (temp_res[4] <= res[4]) - sign_minus_ok = 0; + sign_minus_ok = FALSE; /* If not exactly one of plus or minus works, give up. * This happens in point clouds which are very weakly bent. */ @@ -780,7 +780,7 @@ logarithmic_fit (gnum_float *xs, const g { point_cloud_measure_type point_cloud_measures; int i, result; - gboolean more_2_y = 0, more_2_x = 0; + gboolean more_2_y = FALSE, more_2_x = FALSE; /* Store useful measures for using them here and in subfunctions. * The checking of n is paranoid -- the calling function should @@ -802,7 +802,7 @@ logarithmic_fit (gnum_float *xs, const g for (i=0; i