Commit 3c2b4775 authored by Morten Welinder's avatar Morten Welinder Committed by Morten Welinder

New function.

2001-07-12  Morten Welinder  <terra@diku.dk>

	* src/mathfunc.c (range_multinomial): New function.

	* configure.in (evolution): Fix check, but see BUGS.

2001-07-12  Morten Welinder  <terra@diku.dk>

	* fn-math.c (gnumeric_multinomial): Cleanup.
parent 576036c1
...@@ -25,6 +25,11 @@ Release Critical ...@@ -25,6 +25,11 @@ Release Critical
- 57372 - 57372
- The evolution check is broken. We should check for "idl/Evolution-Composer.h"
because we use it in workbook-control-gui.c. Moreover, the idl check currently
in configure.in should be run-time, not compile time.
Pending Patches Pending Patches
--------------- ---------------
......
2001-07-12 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (range_multinomial): New function.
* configure.in (evolution): Fix check, but see BUGS.
2001-07-12 Almer S. Tigelaar <almer@gnome.org> 2001-07-12 Almer S. Tigelaar <almer@gnome.org>
* src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning. * src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning.
......
...@@ -18,6 +18,7 @@ Jody: ...@@ -18,6 +18,7 @@ Jody:
Morten: Morten:
* Improve bsd support. * Improve bsd support.
* Fix CONCATENATE. * Fix CONCATENATE.
* Fix MULTINOMIAL.
Rodrigo: Rodrigo:
* Update gda support. * Update gda support.
......
2001-07-12 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (range_multinomial): New function.
* configure.in (evolution): Fix check, but see BUGS.
2001-07-12 Almer S. Tigelaar <almer@gnome.org> 2001-07-12 Almer S. Tigelaar <almer@gnome.org>
* src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning. * src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning.
......
2001-07-12 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (range_multinomial): New function.
* configure.in (evolution): Fix check, but see BUGS.
2001-07-12 Almer S. Tigelaar <almer@gnome.org> 2001-07-12 Almer S. Tigelaar <almer@gnome.org>
* src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning. * src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning.
......
2001-07-12 Morten Welinder <terra@diku.dk>
* src/mathfunc.c (range_multinomial): New function.
* configure.in (evolution): Fix check, but see BUGS.
2001-07-12 Almer S. Tigelaar <almer@gnome.org> 2001-07-12 Almer S. Tigelaar <almer@gnome.org>
* src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning. * src/gnumeric-pane.c (gnumeric_pane_set_bounds): Kill warning.
......
...@@ -523,9 +523,6 @@ AC_ARG_WITH(evolution, ...@@ -523,9 +523,6 @@ AC_ARG_WITH(evolution,
if $try_evolution; then if $try_evolution; then
path_to_composer_idl=`gnome-config --datadir`/idl/Evolution-Composer.idl path_to_composer_idl=`gnome-config --datadir`/idl/Evolution-Composer.idl
AC_CHECK_FILE($path_to_composer_idl, evolution=yes, evolution=no) AC_CHECK_FILE($path_to_composer_idl, evolution=yes, evolution=no)
if test x$evolution=xyes; then
AC_DEFINE(ENABLE_EVOLUTION)
fi
fi fi
AM_CONDITIONAL(ENABLE_EVOLUTION, test x"$evolution" = "xyes") AM_CONDITIONAL(ENABLE_EVOLUTION, test x"$evolution" = "xyes")
......
...@@ -1551,47 +1551,16 @@ static char *help_multinomial = { ...@@ -1551,47 +1551,16 @@ static char *help_multinomial = {
"@SEEALSO=SUM") "@SEEALSO=SUM")
}; };
typedef struct {
guint32 num;
int sum;
int product;
} math_multinomial_t;
static Value *
callback_function_multinomial (const EvalPos *ep, Value *value,
void *closure)
{
math_multinomial_t *mm = closure;
switch (value->type){
case VALUE_INTEGER:
mm->product *= fact(value->v_int.val);
mm->sum += value->v_int.val;
mm->num++;
break;
case VALUE_EMPTY:
default:
return value_terminate();
}
return NULL;
}
static Value * static Value *
gnumeric_multinomial (FunctionEvalInfo *ei, GList *nodes) gnumeric_multinomial (FunctionEvalInfo *ei, GList *nodes)
{ {
math_multinomial_t p; return float_range_function (nodes, ei,
range_multinomial,
p.num = 0; COLLECT_IGNORE_STRINGS |
p.sum = 0; COLLECT_IGNORE_BOOLS |
p.product = 1; COLLECT_IGNORE_BLANKS,
gnumeric_err_NUM);
if (function_iterate_argument_values (ei->pos,
callback_function_multinomial,
&p, nodes,
TRUE, TRUE) != NULL)
return value_new_error (ei->pos, gnumeric_err_VALUE);
return value_new_float (fact(p.sum) / p.product);
} }
/***************************************************************************/ /***************************************************************************/
...@@ -1641,7 +1610,7 @@ static char *help_g_product = { ...@@ -1641,7 +1610,7 @@ static char *help_g_product = {
"@DESCRIPTION=" "@DESCRIPTION="
"PRODUCT returns the product of all the values and cells " "PRODUCT returns the product of all the values and cells "
"referenced in the argument list. Empty cells are ignored " "referenced in the argument list. Empty cells are ignored "
"and the empty product in 1." "and the empty product is 1."
"\n" "\n"
"@EXAMPLES=\n" "@EXAMPLES=\n"
"G_PRODUCT(2,5,9) equals 90.\n" "G_PRODUCT(2,5,9) equals 90.\n"
......
2001-07-12 Morten Welinder <terra@diku.dk>
* fn-math.c (gnumeric_multinomial): Cleanup.
2001-07-07 Morten Welinder <terra@diku.dk> 2001-07-07 Morten Welinder <terra@diku.dk>
* fn-information.c (gnumeric_expression, help_expression): Moved * fn-information.c (gnumeric_expression, help_expression): Moved
......
...@@ -1551,47 +1551,16 @@ static char *help_multinomial = { ...@@ -1551,47 +1551,16 @@ static char *help_multinomial = {
"@SEEALSO=SUM") "@SEEALSO=SUM")
}; };
typedef struct {
guint32 num;
int sum;
int product;
} math_multinomial_t;
static Value *
callback_function_multinomial (const EvalPos *ep, Value *value,
void *closure)
{
math_multinomial_t *mm = closure;
switch (value->type){
case VALUE_INTEGER:
mm->product *= fact(value->v_int.val);
mm->sum += value->v_int.val;
mm->num++;
break;
case VALUE_EMPTY:
default:
return value_terminate();
}
return NULL;
}
static Value * static Value *
gnumeric_multinomial (FunctionEvalInfo *ei, GList *nodes) gnumeric_multinomial (FunctionEvalInfo *ei, GList *nodes)
{ {
math_multinomial_t p; return float_range_function (nodes, ei,
range_multinomial,
p.num = 0; COLLECT_IGNORE_STRINGS |
p.sum = 0; COLLECT_IGNORE_BOOLS |
p.product = 1; COLLECT_IGNORE_BLANKS,
gnumeric_err_NUM);
if (function_iterate_argument_values (ei->pos,
callback_function_multinomial,
&p, nodes,
TRUE, TRUE) != NULL)
return value_new_error (ei->pos, gnumeric_err_VALUE);
return value_new_float (fact(p.sum) / p.product);
} }
/***************************************************************************/ /***************************************************************************/
...@@ -1641,7 +1610,7 @@ static char *help_g_product = { ...@@ -1641,7 +1610,7 @@ static char *help_g_product = {
"@DESCRIPTION=" "@DESCRIPTION="
"PRODUCT returns the product of all the values and cells " "PRODUCT returns the product of all the values and cells "
"referenced in the argument list. Empty cells are ignored " "referenced in the argument list. Empty cells are ignored "
"and the empty product in 1." "and the empty product is 1."
"\n" "\n"
"@EXAMPLES=\n" "@EXAMPLES=\n"
"G_PRODUCT(2,5,9) equals 90.\n" "G_PRODUCT(2,5,9) equals 90.\n"
......
...@@ -393,43 +393,78 @@ range_harmonic_mean (const gnum_float *xs, int n, gnum_float *res) ...@@ -393,43 +393,78 @@ range_harmonic_mean (const gnum_float *xs, int n, gnum_float *res)
return 1; return 1;
} }
/* Product. */ /* Geometric mean of positive numbers. */
int int
range_product (const gnum_float *xs, int n, gnum_float *res) range_geometric_mean (const gnum_float *xs, int n, gnum_float *res)
{ {
if (n > 0) {
gnum_float product = 1; gnum_float product = 1;
int i; int i;
/* FIXME: we should work harder at avoiding /* FIXME: we should work harder at avoiding
overflow here. */ overflow here. */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (xs[i] <= 0)
return 1;
product *= xs[i]; product *= xs[i];
} }
*res = product; *res = pow (product, 1.0 / n);
return 0; return 0;
} else
return 1;
} }
/* Geometric mean of positive numbers. */
/* Product. */
int int
range_geometric_mean (const gnum_float *xs, int n, gnum_float *res) range_product (const gnum_float *xs, int n, gnum_float *res)
{ {
if (n > 0) {
gnum_float product = 1; gnum_float product = 1;
int i; int i;
/* FIXME: we should work harder at avoiding /* FIXME: we should work harder at avoiding overflow here. */
overflow here. */
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (xs[i] <= 0)
return 1;
product *= xs[i]; product *= xs[i];
} }
*res = pow (product, 1.0 / n); *res = product;
return 0; return 0;
} else
return 1;
} }
int
range_multinomial (const gnum_float *xs, int n, gnum_float *res)
{
gnum_float result = 1;
int sum = 0;
int i;
for (i = 0; i < n; i++) {
gnum_float x = xs[i];
int xi;
if (x < 0)
return 1;
xi = (int)x;
if (sum == 0 || xi == 0)
; /* Nothing. */
else if (xi < 20) {
int j;
int f = sum + xi;
result *= f--;
for (j = 2; j <= xi; j++)
result = result * f-- / j;
} else {
/* Same as above, only faster. */
result *= combin (sum + xi, xi);
}
sum += xi;
}
*res = result;
return 0;
}
int int
range_covar (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res) range_covar (const gnum_float *xs, const gnum_float *ys, int n, gnum_float *res)
......
...@@ -40,6 +40,7 @@ double gnumeric_fake_trunc (double x); ...@@ -40,6 +40,7 @@ double gnumeric_fake_trunc (double x);
int range_sum (const gnum_float *xs, int n, gnum_float *res); int range_sum (const gnum_float *xs, int n, gnum_float *res);
int range_product (const gnum_float *xs, int n, gnum_float *res); int range_product (const gnum_float *xs, int n, gnum_float *res);
int range_multinomial (const gnum_float *xs, int n, gnum_float *res);
int range_sumsq (const gnum_float *xs, int n, gnum_float *res); int range_sumsq (const gnum_float *xs, int n, gnum_float *res);
int range_avedev (const gnum_float *xs, int n, gnum_float *res); int range_avedev (const gnum_float *xs, int n, gnum_float *res);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment