gnumeric r16723 - in trunk: . plugins/fn-stat src



Author: mortenw
Date: Thu Jul 24 00:25:19 2008
New Revision: 16723
URL: http://svn.gnome.org/viewvc/gnumeric?rev=16723&view=rev

Log:
2008-07-23  Morten Welinder  <terra gnome org>

	* src/collect.c (collect_floats): When requested, sort.

2008-07-23  Morten Welinder  <terra gnome org>

	* functions.c: (gnumeric_small, gnumeric_large,
	gnumeric_percentile, gnumeric_quartile, gnumeric_trimmean): Use
	new COLLECT_SORT and simplify.
	(gnumeric_trimmean): Change to an argv function and simplify
	greatly.
	(gnumeric_rank, gnumeric_min, gnumeric_max, gnumeric_maxa,
	gnumeric_mina, gnumeric_percentrank): Use new
	COLLECT_ORDER_IRRELEVANT.



Modified:
   trunk/ChangeLog
   trunk/NEWS
   trunk/plugins/fn-stat/ChangeLog
   trunk/plugins/fn-stat/functions.c
   trunk/src/collect.c
   trunk/src/collect.h
   trunk/src/rangefunc.c
   trunk/src/rangefunc.h

Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS	(original)
+++ trunk/NEWS	Thu Jul 24 00:25:19 2008
@@ -17,6 +17,7 @@
 	* Fix MATCH problem with singletons.  [#540996]
 	* Fix DDB problems.  [#541158]
 	* Make ssgrep a lot more grep-like.
+	* Unify functions that work on sorted ranges.
 
 --------------------------------------------------------------------------
 Gnumeric 1.9.1

Modified: trunk/plugins/fn-stat/functions.c
==============================================================================
--- trunk/plugins/fn-stat/functions.c	(original)
+++ trunk/plugins/fn-stat/functions.c	Thu Jul 24 00:25:19 2008
@@ -237,7 +237,8 @@
 	xs = collect_floats_value (argv[1], ei->pos,
 				   COLLECT_IGNORE_STRINGS |
 				   COLLECT_IGNORE_BOOLS |
-				   COLLECT_IGNORE_BLANKS,
+				   COLLECT_IGNORE_BLANKS |
+				   COLLECT_ORDER_IRRELEVANT,
 				   &n, &result);
 	order = argv[2] ? value_get_as_int (argv[2]) : 0;
 
@@ -281,39 +282,32 @@
 	{ GNM_FUNC_HELP_END }
 };
 
-static int
-range_trimmean (gnm_float const *xs, int n, gnm_float *res)
+static GnmValue *
+gnumeric_trimmean (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 {
-	gnm_float p;
-	int tc, c;
+	int c, tc, n;
+	GnmValue *result = NULL;
+	gnm_float *xs = collect_floats_value (argv[0], ei->pos,
+					      COLLECT_IGNORE_STRINGS |
+					      COLLECT_IGNORE_BOOLS |
+					      COLLECT_IGNORE_BLANKS |
+					      COLLECT_SORT,
+					      &n, &result);
+	gnm_float p = value_get_as_float (argv[1]);
+	gnm_float res;
 
-	if (n < 2)
-		return 1;
+	if (result)
+		return result;
 
-	p = xs[--n];
 	if (p < 0 || p > 1)
-		return 1;
+		return value_new_error_VALUE (ei->pos);
 
-	tc = gnm_fake_floor ((n * p) / 2);
+	tc = (int)gnm_fake_floor ((n * p) / 2);
 	c = n - 2 * tc;
-	if (c == 0)
-		return 1;
-
-	/* OK, so we ignore the constness here.  Tough.  */
-	qsort ((gnm_float *) xs, n, sizeof (xs[0]), (void *) &float_compare);
+	if (gnm_range_average (xs + tc, c, &res))
+		return value_new_error_VALUE (ei->pos);
 
-	return gnm_range_average (xs + tc, c, res);
-}
-
-static GnmValue *
-gnumeric_trimmean (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
-{
-	return float_range_function (argc, argv, ei,
-				     range_trimmean,
-				     COLLECT_IGNORE_STRINGS |
-				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
-				     GNM_ERROR_VALUE);
+	return value_new_float (res);
 }
 
 /***************************************************************************/
@@ -869,7 +863,8 @@
 				     range_min0,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_ORDER_IRRELEVANT,
 				     GNM_ERROR_VALUE);
 }
 
@@ -913,7 +908,8 @@
 				     range_max0,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_ORDER_IRRELEVANT,
 				     GNM_ERROR_VALUE);
 }
 
@@ -2481,10 +2477,11 @@
 gnumeric_median (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
 {
 	return float_range_function (argc, argv, ei,
-				     (float_range_function_t)gnm_range_median_inter_nonconst,
+				     gnm_range_median_inter_sorted,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_SORT,
 				     GNM_ERROR_NUM);
 }
 
@@ -2628,20 +2625,25 @@
 static GnmValue *
 gnumeric_large (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 {
-	int	   n_vals;
-	gnm_float  val, k;
-	GnmValue  *res = NULL;
-	gnm_float *vals = collect_floats_value (argv[0], ei->pos,
-		COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS | COLLECT_IGNORE_BLANKS,
-		&n_vals, &res);
+	int n;
+	GnmValue *res = NULL;
+	gnm_float *xs = collect_floats_value (argv[0], ei->pos,
+					      COLLECT_IGNORE_STRINGS |
+					      COLLECT_IGNORE_BOOLS |
+					      COLLECT_IGNORE_BLANKS |
+					      COLLECT_SORT,
+					      &n, &res);
+	gnm_float k = value_get_as_float (argv[1]);
 	if (res)
 		return res;
-	if (1. <= (k = value_get_as_float (argv[1])) &&
-	    0 == gnm_range_min_k_nonconst (vals, n_vals, &val, n_vals - gnm_fake_ceil (k)))
-		res = value_new_float (val);
+
+	k = gnm_fake_ceil (k);
+	if (k >= 1 && k <= n)
+		res = value_new_float (xs[n - (int)k]);
 	else
 		res = value_new_error_NUM (ei->pos);
-	g_free (vals);
+
+	g_free (xs);
 	return res;
 }
 
@@ -2680,20 +2682,25 @@
 static GnmValue *
 gnumeric_small (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 {
-	int	   n_vals;
-	gnm_float  val, k;
-	GnmValue  *res = NULL;
-	gnm_float *vals = collect_floats_value (argv[0], ei->pos,
-		COLLECT_IGNORE_STRINGS | COLLECT_IGNORE_BOOLS | COLLECT_IGNORE_BLANKS,
-		&n_vals, &res);
+	int n;
+	GnmValue *res = NULL;
+	gnm_float *xs = collect_floats_value (argv[0], ei->pos,
+					      COLLECT_IGNORE_STRINGS |
+					      COLLECT_IGNORE_BOOLS |
+					      COLLECT_IGNORE_BLANKS |
+					      COLLECT_SORT,
+					      &n, &res);
+	gnm_float k = value_get_as_float (argv[1]);
 	if (res)
 		return res;
-	if (1. <= (k = value_get_as_float (argv[1])) &&
-	    0 == gnm_range_min_k_nonconst (vals, n_vals, &val, gnm_fake_ceil (k) - 1))
-		res = value_new_float (val);
+
+	k = gnm_fake_ceil (k);
+	if (k >= 1 && k <= n)
+		res = value_new_float (xs[(int)k - 1]);
 	else
 		res = value_new_error_NUM (ei->pos);
-	g_free (vals);
+
+	g_free (xs);
 	return res;
 }
 
@@ -3118,7 +3125,8 @@
 				     gnm_range_max,
 				     COLLECT_ZERO_STRINGS |
 				     COLLECT_ZEROONE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_ORDER_IRRELEVANT,
 				     GNM_ERROR_VALUE);
 }
 
@@ -3156,7 +3164,8 @@
 				     gnm_range_min,
 				     COLLECT_ZERO_STRINGS |
 				     COLLECT_ZEROONE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_ORDER_IRRELEVANT,
 				     GNM_ERROR_VALUE);
 }
 
@@ -3371,7 +3380,8 @@
 	data = collect_floats_value (argv[0], ei->pos,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_ORDER_IRRELEVANT,
 				     &n, &result);
 	x = value_get_as_float (argv[1]);
 	significance = argv[2] ? value_get_as_float (argv[2]) : 3;
@@ -3472,13 +3482,14 @@
 	data = collect_floats_value (argv[0], ei->pos,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_SORT,
 				     &n, &result);
 	if (!result) {
 		gnm_float p = value_get_as_float (argv[1]);
 		gnm_float res;
 
-		if (gnm_range_fractile_inter_nonconst (data, n, &res, p))
+		if (gnm_range_fractile_inter_sorted (data, n, &res, p))
 			result = value_new_error_NUM (ei->pos);
 		else
 			result = value_new_float (res);
@@ -3531,13 +3542,14 @@
 	data = collect_floats_value (argv[0], ei->pos,
 				     COLLECT_IGNORE_STRINGS |
 				     COLLECT_IGNORE_BOOLS |
-				     COLLECT_IGNORE_BLANKS,
+				     COLLECT_IGNORE_BLANKS |
+				     COLLECT_SORT,
 				     &n, &result);
 	if (!result) {
-		int q = value_get_as_int (argv[1]);
+		gnm_float q = gnm_fake_floor (value_get_as_float (argv[1]));
 		gnm_float res;
 
-		if (gnm_range_fractile_inter_nonconst (data, n, &res, q / 4.0))
+		if (gnm_range_fractile_inter_sorted (data, n, &res, q / 4.0))
 			result = value_new_error_NUM (ei->pos);
 		else
 			result = value_new_float (res);
@@ -5935,8 +5947,8 @@
 	{ "trend",        "A|AAb", N_("known_y's,known_x's,new_x's,const"),
 	  help_trend, gnumeric_trend, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
-	{ "trimmean", NULL,      N_("ref,fraction"),
-	  help_trimmean, NULL, gnumeric_trimmean, NULL, NULL, NULL,
+	{ "trimmean",     "rf",    N_("ref,fraction"),
+	  help_trimmean, gnumeric_trimmean, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE + GNM_FUNC_AUTO_FIRST,
 	  GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
 	{ "ttest",        "rrff",   N_("array1,array2,tails,type"),

Modified: trunk/src/collect.c
==============================================================================
--- trunk/src/collect.c	(original)
+++ trunk/src/collect.c	Thu Jul 24 00:25:19 2008
@@ -19,9 +19,24 @@
 #include "sheet.h"
 #include "number-match.h"
 #include <goffice/utils/go-glib-extras.h>
+#include <stdlib.h>
 
 /* ------------------------------------------------------------------------- */
 
+static int
+float_compare (const void *a_, const void *b_)
+{
+	gnm_float const *a = a_;
+	gnm_float const *b = b_;
+
+        if (*a < *b)
+                return -1;
+	else if (*a == *b)
+		return 0;
+	else
+		return 1;
+}
+
 typedef struct {
 	guint alloc_count;
 	gnm_float *data;
@@ -148,6 +163,7 @@
 	CellIterFlags iter_flags = CELL_ITER_ALL;
 
 	if (info) {
+		g_return_val_if_fail (!(flags & COLLECT_SORT), NULL);
 		flags |= COLLECT_INFO;
 		*info = NULL;
 	} else {
@@ -182,9 +198,14 @@
 		cl.data = g_new (gnm_float, cl.alloc_count);
 	}
 
+	if (flags & COLLECT_SORT) {
+		qsort (cl.data, cl.count, sizeof (cl.data[0]), float_compare);
+	}
+
 	if (info)
 		*info = cl.info;
 	*n = cl.count;
+
 	return cl.data;
 }
 

Modified: trunk/src/collect.h
==============================================================================
--- trunk/src/collect.h	(original)
+++ trunk/src/collect.h	Thu Jul 24 00:25:19 2008
@@ -20,6 +20,9 @@
 	COLLECT_IGNORE_BLANKS	= 0x1000,
 	COLLECT_IGNORE_SUBTOTAL	= 0x2000,
 
+	COLLECT_SORT            = 0x10000,
+	COLLECT_ORDER_IRRELEVANT = 0x20000,
+
 	/* Not for general usage.  */
 	COLLECT_INFO		= 0x1000000
 } CollectFlags;

Modified: trunk/src/rangefunc.c
==============================================================================
--- trunk/src/rangefunc.c	(original)
+++ trunk/src/rangefunc.c	Thu Jul 24 00:25:19 2008
@@ -474,32 +474,3 @@
 	*res = mode;
 	return 0;
 }
-
-
-static gint
-float_compare (gnm_float const *a, const gnm_float *b)
-{
-        if (*a < *b)
-                return -1;
-	else if (*a == *b)
-	        return 0;
-	else
-	        return 1;
-}
-
-/* k-th smallest.  Note: k is zero-based.  */
-/* This version may reorder data points.  */
-int
-gnm_range_min_k_nonconst (gnm_float *xs, int n, gnm_float *res, int k)
-{
-	if (k < 0 || k >= n)
-		return 1;
-	if (k == 0)
-		return gnm_range_min (xs, n, res);
-	if (k == n - 1)
-		return gnm_range_max (xs, n, res);
-
-	qsort (xs, n, sizeof (xs[0]), (int (*) (const void *, const void *))&float_compare);
-	*res = xs[k];
-	return 0;
-}

Modified: trunk/src/rangefunc.h
==============================================================================
--- trunk/src/rangefunc.h	(original)
+++ trunk/src/rangefunc.h	Thu Jul 24 00:25:19 2008
@@ -15,10 +15,9 @@
 #	define gnm_range_max go_range_maxl
 #	define gnm_range_maxabs go_range_maxabsl
 #	define gnm_range_devsq go_range_devsql
-#	define gnm_range_fractile_inter go_range_fractile_interl
-#	define gnm_range_fractile_inter_nonconst go_range_fractile_inter_nonconstl
+#	define gnm_range_fractile_inter_sorted go_range_fractile_inter_sortedl
 #	define gnm_range_median_inter go_range_median_interl
-#	define gnm_range_median_inter_nonconst go_range_median_inter_nonconstl
+#	define gnm_range_median_inter_sorted go_range_median_inter_sortedl
 #else
 #	define gnm_range_sum go_range_sum
 #	define gnm_range_sumsq go_range_sumsq
@@ -27,10 +26,9 @@
 #	define gnm_range_max go_range_max
 #	define gnm_range_maxabs go_range_maxabs
 #	define gnm_range_devsq go_range_devsq
-#	define gnm_range_fractile_inter go_range_fractile_inter
-#	define gnm_range_fractile_inter_nonconst go_range_fractile_inter_nonconst
+#	define gnm_range_fractile_inter_sorted go_range_fractile_inter_sorted
 #	define gnm_range_median_inter go_range_median_inter
-#	define gnm_range_median_inter_nonconst go_range_median_inter_nonconst
+#	define gnm_range_median_inter_sorted go_range_median_inter_sorted
 #endif
 
 int gnm_range_count		(gnm_float const *xs, int n, gnm_float *res);
@@ -63,8 +61,6 @@
 
 int gnm_range_mode	(gnm_float const *xs, int n, gnm_float *res);
 
-int gnm_range_min_k_nonconst (gnm_float       *xs, int n, gnm_float *res, int k);
-
 G_END_DECLS
 
 #endif /* _GNM_RANGEFUNC_H_ */



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