Index: minmax_source.c =================================================================== RCS file: /cvs/gsl/gsl/statistics/minmax_source.c,v retrieving revision 1.7 diff -u -r1.7 minmax_source.c --- minmax_source.c 26 Jun 2005 13:27:11 -0000 1.7 +++ minmax_source.c 23 Dec 2005 08:05:18 -0000 @@ -57,18 +57,68 @@ FUNCTION(gsl_stats,minmax) (BASE * min_out, BASE * max_out, const BASE data[], const size_t stride, const size_t n) { /* finds the smallest and largest members of a dataset */ + /* cf. Cormen et al. 2001, pp. 184--185 */ - BASE min = data[0 * stride]; - BASE max = data[0 * stride]; size_t i; + BASE min; + BASE max; - for (i = 0; i < n; i++) + if (n == 0) { - if (data[i * stride] < min) - min = data[i * stride]; - if (data[i * stride] > max) - max = data[i * stride]; + /* We could raise an error, e.g. */ + /* GSL_ERROR ("length n of dataset is zero", GSL_EINVAL); */ + /* but only if the return type of the function is changed. */ + return; + } + + if (n & 1) /* n is odd */ + { + /* assert (n >= 1) */ + i = 1; + min = data[0]; + max = data[0]; + } + else /* n is even */ + { + BASE x = data[0]; + BASE y = data[stride]; + + /* assert (n >= 2); */ + i = 2; + + if (x < y) + { + min = x; + max = y; + } + else + { + min = y; + max = x; + } + } + + for (/*empty*/; i < n; i+=2) + { + BASE x = data[i * stride]; + BASE y = data[(i+1) * stride]; + + if (x < y) + { + if (x < min) + min = x; + if (y > max) + max = y; + } + else + { + if (y < min) + min = y; + if (x > max) + max = x; + } } + /* assert (i == n); */ *min_out = min ; *max_out = max ;