[gnumeric] Funcs: add GAMMA.



commit 9902f7d7c334fc4a7b9e1933fdb15b00eab18e00
Author: Morten Welinder <terra gnome org>
Date:   Thu Aug 20 11:37:56 2009 -0400

    Funcs: add GAMMA.

 NEWS                          |    3 ++
 plugins/fn-math/ChangeLog     |    5 +++
 plugins/fn-math/functions.c   |   60 +++++++++++++++++++++++++++++++++++++++++
 plugins/fn-math/plugin.xml.in |   22 ++++++++-------
 plugins/fn-stat/functions.c   |   33 ----------------------
 plugins/fn-stat/plugin.xml.in |    1 -
 6 files changed, 80 insertions(+), 44 deletions(-)
---
diff --git a/NEWS b/NEWS
index a230305..54a71aa 100644
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,9 @@ Gnumeric 1.9.11
 Andreas:
 	* Add AVERAGEIF.
 
+Morten:
+	* Add GAMMA.
+
 --------------------------------------------------------------------------
 Gnumeric 1.9.10
 
diff --git a/plugins/fn-math/ChangeLog b/plugins/fn-math/ChangeLog
index 01e313d..3176044 100644
--- a/plugins/fn-math/ChangeLog
+++ b/plugins/fn-math/ChangeLog
@@ -1,3 +1,8 @@
+2009-08-20  Morten Welinder  <terra gnome org>
+
+	* functions.c (gnumeric_gammaln): Moved from fn-stat.  Fix domain.
+	(gnumeric_gamma): New function.
+
 2009-08-16  Andreas J. Guelzow <aguelzow pyrshep ca>
 
 	* functions.c (help_sumif): fix argument name
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 6e16154..9afdd61 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -940,6 +940,60 @@ gnumeric_fact (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 /***************************************************************************/
 
+static GnmFuncHelp const help_gamma[] = {
+        { GNM_FUNC_HELP_NAME, F_("GAMMA:the Gamma function")},
+        { GNM_FUNC_HELP_ARG, F_("x:number")},
+	{ GNM_FUNC_HELP_EXAMPLES, "=GAMMA(-1.8)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=GAMMA(2.4)" },
+	{ GNM_FUNC_HELP_SEEALSO, "LNGAMMA"},
+        { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_gamma (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	gnm_float x = value_get_as_float (argv[0]);
+	gboolean x_is_integer = (x == gnm_floor (x));
+
+	if (x < 0 && x_is_integer)
+		return value_new_error_NUM (ei->pos);
+
+	if (x_is_integer)
+		return value_new_float (fact (x - 1));
+	else {
+		gnm_float res = gnm_exp (gnm_lgamma (x));
+		if (x < 0 && gnm_fmod (gnm_floor (-x), 2.0) == 0.0)
+			res = 0 - res;
+		return value_new_float (res);
+	}
+}
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_gammaln[] = {
+	{ GNM_FUNC_HELP_NAME, F_("GAMMALN:natural logarithm of the Gamma function.")},
+	{ GNM_FUNC_HELP_ARG, F_("x:number")},
+	{ GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
+	{ GNM_FUNC_HELP_EXAMPLES, "=GAMMALN(23)" },
+	{ GNM_FUNC_HELP_SEEALSO, "GAMMA"},
+	{ GNM_FUNC_HELP_END }
+};
+
+static GnmValue *
+gnumeric_gammaln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+	gnm_float x = value_get_as_float (argv[0]);
+	gboolean x_is_integer = (x == gnm_floor (x));
+
+	if (x < 0 && (x_is_integer ||
+		      gnm_fmod (gnm_floor (-x), 2.0) == 0.0))
+		return value_new_error_NUM (ei->pos);
+	else
+		return value_new_float (gnm_lgamma (x));
+}
+
+/***************************************************************************/
+
 static GnmFuncHelp const help_beta[] = {
         { GNM_FUNC_HELP_NAME, F_("BETA:Euler beta function")},
         { GNM_FUNC_HELP_ARG, F_("x:number")},
@@ -2887,6 +2941,12 @@ GnmFuncDescriptor const math_functions[] = {
 	  gnumeric_floor, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE + GNM_FUNC_AUTO_FIRST,
 	  GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
+	{ "gamma",    "f",     help_gamma,
+	  gnumeric_gamma, NULL, NULL, NULL, NULL,
+	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
+	{ "gammaln",      "f",    
+	  help_gammaln, gnumeric_gammaln, NULL, NULL, NULL, NULL,
+	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
 	{ "gcd", NULL,  help_gcd,
 	  NULL, gnumeric_gcd, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
diff --git a/plugins/fn-math/plugin.xml.in b/plugins/fn-math/plugin.xml.in
index e9dc869..f4b0623 100644
--- a/plugins/fn-math/plugin.xml.in
+++ b/plugins/fn-math/plugin.xml.in
@@ -19,18 +19,19 @@
 				<function name="asin"/>
 				<function name="asinh"/>
 				<function name="atan"/>
-				<function name="atanh"/>
 				<function name="atan2"/>
+				<function name="atanh"/>
 				<function name="averageif"/>
 				<function name="beta"/>
 				<function name="betaln"/>
+				<function name="ceil"/>
+				<function name="ceiling"/>
+				<function name="combin"/>
 				<function name="cos"/>
 				<function name="cosh"/>
 				<function name="cot"/>
 				<function name="coth"/>
 				<function name="countif"/>
-				<function name="ceil"/>
-				<function name="ceiling"/>
 				<function name="csc"/>
 				<function name="csch"/>
 				<function name="degrees"/>
@@ -40,8 +41,10 @@
 				<function name="fact"/>
 				<function name="factdouble"/>
 				<function name="fib"/>
-				<function name="combin"/>
 				<function name="floor"/>
+				<function name="g_product"/>
+				<function name="gamma"/>
+				<function name="gammaln"/>
 				<function name="gcd"/>
 				<function name="gd"/>
 				<function name="hypot"/>
@@ -50,14 +53,17 @@
 				<function name="ln"/>
 				<function name="ln1p"/>
 				<function name="log"/>
-				<function name="log2"/>
 				<function name="log10"/>
+				<function name="log2"/>
+				<function name="mdeterm"/>
+				<function name="minverse"/>
+				<function name="mmult"/>
 				<function name="mod"/>
 				<function name="mround"/>
 				<function name="multinomial"/>
 				<function name="odd"/>
+				<function name="pi"/>
 				<function name="power"/>
-				<function name="g_product"/>
 				<function name="quotient"/>
 				<function name="radians"/>
 				<function name="roman"/>
@@ -82,10 +88,6 @@
 				<function name="tan"/>
 				<function name="tanh"/>
 				<function name="trunc"/>
-				<function name="pi"/>
-				<function name="mmult"/>
-				<function name="minverse"/>
-				<function name="mdeterm"/>
 				<!-- <function name="logmdeterm"/> -->
 			</functions>
 		</service>
diff --git a/plugins/fn-stat/functions.c b/plugins/fn-stat/functions.c
index e28bfd7..7e73e80 100644
--- a/plugins/fn-stat/functions.c
+++ b/plugins/fn-stat/functions.c
@@ -849,36 +849,6 @@ gnumeric_bernoulli (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 /***************************************************************************/
 
-static GnmFuncHelp const help_gammaln[] = {
-	{ GNM_FUNC_HELP_NAME, F_("GAMMALN:natural logarithm of the gamma function.")},
-	{ GNM_FUNC_HELP_ARG, F_("x:")},
-	{ GNM_FUNC_HELP_NOTE, F_("If @{x} is non-number then this function returns a #VALUE! error.")},
-	{ GNM_FUNC_HELP_NOTE, F_("If @{x} <= 0 then this function returns a #NUM! error.")},
-	{ GNM_FUNC_HELP_EXCEL, F_("This function is Excel compatible.") },
-	{ GNM_FUNC_HELP_EXAMPLES, F_("GAMMALN(23) equals 48.471181352.") },
-	{ GNM_FUNC_HELP_SEEALSO, "POISSON"},
-	{ GNM_FUNC_HELP_END }
-};
-
-static GnmValue *
-gnumeric_gammaln (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
-{
-	gnm_float x;
-
-	/* FIXME: the gamma function is defined for all real numbers except
-	 * the integers 0, -1, -2, ...  It is positive (and log(gamma(x)) is
-	 * thus defined) when x>0 or -2<x<-1 or -4<x<-3 ...  */
-
-	x = value_get_as_float (argv[0]);
-
-	if (x <= 0)
-		return value_new_error_NUM (ei->pos);
-
-	return value_new_float (gnm_lgamma (x));
-}
-
-/***************************************************************************/
-
 static GnmFuncHelp const help_gammadist[] = {
 	{ GNM_FUNC_HELP_NAME, F_("GAMMADIST:(cumulative) density function of the gamma distribution")},
 	{ GNM_FUNC_HELP_ARG, F_("x:")},
@@ -4892,9 +4862,6 @@ GnmFuncDescriptor const stat_functions[] = {
 	{ "gammainv",     "fff",   
 	  help_gammainv, gnumeric_gammainv, NULL, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
-	{ "gammaln",      "f",    
-	  help_gammaln, gnumeric_gammaln, NULL, NULL, NULL, NULL,
-	  GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_BASIC },
 	{ "geomean", NULL,      
 	  help_geomean, NULL, gnumeric_geomean, NULL, NULL, NULL,
 	  GNM_FUNC_SIMPLE + GNM_FUNC_AUTO_FIRST,
diff --git a/plugins/fn-stat/plugin.xml.in b/plugins/fn-stat/plugin.xml.in
index 25bb2bc..a4779c6 100644
--- a/plugins/fn-stat/plugin.xml.in
+++ b/plugins/fn-stat/plugin.xml.in
@@ -41,7 +41,6 @@
 				<function name="forecast"/>
 				<function name="frequency"/>
 				<function name="ftest"/>
-				<function name="gammaln"/>
 				<function name="gammadist"/>
 				<function name="gammainv"/>
 				<function name="geomean"/>



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