gnumeric r16838 - in trunk: . plugins/fn-math



Author: mortenw
Date: Thu Oct  2 00:29:14 2008
New Revision: 16838
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16838&view=rev

Log:
2008-10-01  Morten Welinder  <terra gnome org>

	* functions.c (gnumeric_sumx2my2, gnumeric_sumx2py2,
	gnumeric_sumxmy2): Use float_range_function2.  Fixes #554040.



Modified:
   trunk/NEWS
   trunk/plugins/fn-math/ChangeLog
   trunk/plugins/fn-math/functions.c

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Thu Oct  2 00:29:14 2008
@@ -40,6 +40,7 @@
 	* Fix error check for printing to file.
 	* Fix SUMIF crash.  [#552006]
 	* Fix NETWORKDAYS problem.  [#553047]
+	* Bring SUMX2MY2, SUMX2PY2, and SUMXMY2 into 21st century.  [#554040]
 
 Nakai:
 	* Enable Perl plugin again. [#553939]

Modified: trunk/plugins/fn-math/functions.c
==============================================================================
--- trunk/plugins/fn-math/functions.c	(original)
+++ trunk/plugins/fn-math/functions.c	Thu Oct  2 00:29:14 2008
@@ -43,33 +43,6 @@
 
 GNM_PLUGIN_MODULE_HEADER;
 
-typedef struct {
-        GSList *list;
-        int    num;
-} math_sums_t;
-
-static GnmValue *
-callback_function_sumxy (GnmCellIter const *iter, gpointer user)
-{
-	GnmCell *cell;
-	if (NULL == (cell = iter->cell))
-	        return NULL;
-	gnm_cell_eval (cell);
-
-	if (VALUE_IS_NUMBER (cell->value)) {
-		math_sums_t *mm = user;
-		gnm_float *p = g_new (gnm_float, 1);
-		*p = value_get_as_float (cell->value);
-		mm->list = g_slist_append (mm->list, p);
-		mm->num++;
-
-		return NULL;
-	} else if (VALUE_IS_ERROR (cell->value))
-		return VALUE_TERMINATE;  /* FIXME: This is probably wrong.  */
-	else
-		return NULL;
-}
-
 /***************************************************************************/
 
 static GnmFuncHelp const help_gcd[] = {
@@ -2524,91 +2497,31 @@
 	{ GNM_FUNC_HELP_END }
 };
 
-static GnmValue *
-gnumeric_sumx2my2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+static int
+gnm_range_sumx2my2 (gnm_float const *xs, const gnm_float *ys,
+		    int n, gnm_float *res)
 {
-        GnmValue const *values_x = argv[0];
-        GnmValue const *values_y = argv[1];
-	math_sums_t items_x, items_y;
-	GnmValue      *ret;
-	gnm_float  sum;
-	GSList     *list1, *list2;
-
-	items_x.num  = 0;
-	items_x.list = NULL;
-	items_y.num  = 0;
-	items_y.list = NULL;
-
-        if (values_x->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL,
-			values_x->v_range.cell.a.col,
-			values_x->v_range.cell.a.row,
-			values_x->v_range.cell.b.col,
-			values_x->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_x);
-
-		if (ret != NULL) {
-		        ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-        if (values_y->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL,
-			values_y->v_range.cell.a.col,
-			values_y->v_range.cell.a.row,
-			values_y->v_range.cell.b.col,
-			values_y->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_y);
-		if (ret != NULL) {
-		        ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-	if (items_x.num != items_y.num) {
-		ret = value_new_error_NA (ei->pos);
-		goto out;
-	}
+	gnm_float s = 0;
+	int i;
 
-	list1 = items_x.list;
-	list2 = items_y.list;
-	sum = 0;
-	while (list1 != NULL) {
-	        gnm_float x, y;
+	for (i = 0; i < n; i++)
+		s += xs[i] * xs[i] - ys[i] * ys[i];
 
-		x = *((gnm_float *) list1->data);
-		y = *((gnm_float *) list2->data);
-		sum += x * x - y * y;
-		list1 = list1->next;
-		list2 = list2->next;
-	}
-	ret = value_new_float (sum);
-
- out:
-	for (list1 = items_x.list; list1; list1 = list1->next)
-		g_free (list1->data);
-	g_slist_free (items_x.list);
+	*res = s;
+	return 0;
+}
 
-	for (list2 = items_y.list; list2; list2 = list2->next)
-		g_free (list2->data);
-	g_slist_free (items_y.list);
 
-	return ret;
+static GnmValue *
+gnumeric_sumx2my2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	return float_range_function2 (argv[0], argv[1],
+				      ei,
+				      gnm_range_sumx2my2,
+				      COLLECT_IGNORE_BLANKS |
+				      COLLECT_IGNORE_STRINGS |
+				      COLLECT_IGNORE_BOOLS,
+				      GNM_ERROR_VALUE);
 }
 
 /***************************************************************************/
@@ -2641,92 +2554,34 @@
 	{ GNM_FUNC_HELP_END }
 };
 
-static GnmValue *
-gnumeric_sumx2py2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+static int
+gnm_range_sumx2py2 (gnm_float const *xs, const gnm_float *ys,
+		    int n, gnm_float *res)
 {
-        GnmValue const *values_x = argv[0];
-        GnmValue const *values_y = argv[1];
-	math_sums_t items_x, items_y;
-	GnmValue      *ret;
-	gnm_float  sum;
-	GSList     *list1, *list2;
-
-	items_x.num  = 0;
-	items_x.list = NULL;
-	items_y.num  = 0;
-	items_y.list = NULL;
-
-        if (values_x->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL, /* include empties so that the lists align */
-			values_x->v_range.cell.a.col,
-			values_x->v_range.cell.a.row,
-			values_x->v_range.cell.b.col,
-			values_x->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_x);
-		if (ret != NULL) {
-		        ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-        if (values_y->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL, /* include empties so that the lists align */
-			values_y->v_range.cell.a.col,
-			values_y->v_range.cell.a.row,
-			values_y->v_range.cell.b.col,
-			values_y->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_y);
-		if (ret != NULL) {
-			ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-	if (items_x.num != items_y.num) {
-		ret = value_new_error_NA (ei->pos);
-		goto out;
-	}
-
-	list1 = items_x.list;
-	list2 = items_y.list;
-	sum = 0;
-	while (list1 != NULL) {
-	        gnm_float x, y;
-
-		x = *((gnm_float *) list1->data);
-		y = *((gnm_float *) list2->data);
-		sum += x * x + y * y;
-		list1 = list1->next;
-		list2 = list2->next;
-	}
-	ret = value_new_float (sum);
+	gnm_float s = 0;
+	int i;
 
- out:
-	for (list1 = items_x.list; list1; list1 = list1->next)
-		g_free (list1->data);
-	g_slist_free (items_x.list);
+	for (i = 0; i < n; i++)
+		s += xs[i] * xs[i] + ys[i] * ys[i];
 
-	for (list2 = items_y.list; list2; list2 = list2->next)
-		g_free (list2->data);
-	g_slist_free (items_y.list);
+	*res = s;
+	return 0;
+}
 
-	return ret;
+static GnmValue *
+gnumeric_sumx2py2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	return float_range_function2 (argv[0], argv[1],
+				      ei,
+				      gnm_range_sumx2py2,
+				      COLLECT_IGNORE_BLANKS |
+				      COLLECT_IGNORE_STRINGS |
+				      COLLECT_IGNORE_BOOLS,
+				      GNM_ERROR_VALUE);
 }
 
+/***************************************************************************/
+
 static GnmFuncHelp const help_sumxmy2[] = {
 	{ GNM_FUNC_HELP_OLD,
 	F_("@FUNCTION=SUMXMY2\n"
@@ -2755,90 +2610,32 @@
 	{ GNM_FUNC_HELP_END }
 };
 
-static GnmValue *
-gnumeric_sumxmy2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+static int
+gnm_range_sumxmy2 (gnm_float const *xs, const gnm_float *ys,
+		   int n, gnm_float *res)
 {
-        GnmValue const *values_x = argv[0];
-        GnmValue const *values_y = argv[1];
-	math_sums_t items_x, items_y;
-	GnmValue      *ret;
-	gnm_float  sum;
-	GSList     *list1, *list2;
-
-	items_x.num  = 0;
-	items_x.list = NULL;
-	items_y.num  = 0;
-	items_y.list = NULL;
-
-        if (values_x->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL, /* include empties so that the lists align */
-			values_x->v_range.cell.a.col,
-			values_x->v_range.cell.a.row,
-			values_x->v_range.cell.b.col,
-			values_x->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_x);
-		if (ret != NULL) {
-		        ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-        if (values_y->type == VALUE_CELLRANGE) {
-		ret = sheet_foreach_cell_in_range (
-			eval_sheet (ei->pos->sheet, ei->pos->sheet),
-			CELL_ITER_ALL, /* include empties so that the lists align */
-			values_y->v_range.cell.a.col,
-			values_y->v_range.cell.a.row,
-			values_y->v_range.cell.b.col,
-			values_y->v_range.cell.b.row,
-			callback_function_sumxy,
-			&items_y);
-		if (ret != NULL) {
-		        ret = value_new_error_VALUE (ei->pos);
-			goto out;
-		}
-	} else {
-		ret = value_new_error (ei->pos,
-				       _("Array version not implemented!"));
-		goto out;
-	}
-
-	if (items_x.num != items_y.num) {
-	        ret = value_new_error_NA (ei->pos);
-		goto out;
-	}
-
-	list1 = items_x.list;
-	list2 = items_y.list;
-	sum = 0;
-	while (list1 != NULL) {
-	        gnm_float x, y;
+	gnm_float s = 0;
+	int i;
 
-		x = *((gnm_float *) list1->data);
-		y = *((gnm_float *) list2->data);
-		sum += (x - y) * (x - y);
-		list1 = list1->next;
-		list2 = list2->next;
+	for (i = 0; i < n; i++) {
+		gnm_float d = (xs[i] - ys[i]);
+		s += d * d;
 	}
-	ret = value_new_float (sum);
-
- out:
-	for (list1 = items_x.list; list1; list1 = list1->next)
-		g_free (list1->data);
-	g_slist_free (items_x.list);
 
-	for (list2 = items_y.list; list2; list2 = list2->next)
-		g_free (list2->data);
-	g_slist_free (items_y.list);
+	*res = s;
+	return 0;
+}
 
-	return ret;
+static GnmValue *
+gnumeric_sumxmy2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	return float_range_function2 (argv[0], argv[1],
+				      ei,
+				      gnm_range_sumxmy2,
+				      COLLECT_IGNORE_BLANKS |
+				      COLLECT_IGNORE_STRINGS |
+				      COLLECT_IGNORE_BOOLS,
+				      GNM_ERROR_VALUE);
 }
 
 /***************************************************************************/



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