[gnumeric] POCHHAMMER: New function.



commit 0157e03abd479fb34ec40c4777e1ca733d7edc91
Author: Morten Welinder <terra gnome org>
Date:   Sun Apr 7 18:25:50 2013 -0400

    POCHHAMMER: New function.

 NEWS                          |    1 +
 doc/C/func.defs               |    9 ++++++++
 doc/C/functions.xml           |   29 ++++++++++++++++++++++++++
 plugins/fn-math/functions.c   |   26 +++++++++++++++++++++++
 plugins/fn-math/plugin.xml.in |    3 +-
 src/mathfunc.c                |   45 +++++++++++++++++++++++++++++++++++++++++
 src/mathfunc.h                |    1 +
 7 files changed, 113 insertions(+), 1 deletions(-)
---
diff --git a/NEWS b/NEWS
index 2b696a2..a8a2e8a 100644
--- a/NEWS
+++ b/NEWS
@@ -24,6 +24,7 @@ Morten:
        * Fix dependency tabulation.
        * Fix problems with R.PSNORM.  [#697293]
        * New function OWENT.
+       * New function POCHHAMMER.
 
 --------------------------------------------------------------------------
 Gnumeric 1.12.1
diff --git a/doc/C/func.defs b/doc/C/func.defs
index a295076..20dfb7e 100644
--- a/doc/C/func.defs
+++ b/doc/C/func.defs
@@ -3564,6 +3564,15 @@ The depreciation coefficient used is:
 @SEEALSO=SQRTPI
 
 @CATEGORY=Mathematics
+ FUNCTION=POCHHAMMER
+ SHORTDESC=the value of GAMMA(@{x}+ {n})/GAMMA(@{x})
+ SYNTAX=POCHHAMMER(x,n,give_log)
+ ARGUMENTDESCRIPTION=@{x}: number
+ {n}: number
+ {give_log}: if true, log of the result will be returned instead
+ SEEALSO=GAMMA
+
+ CATEGORY=Mathematics
 @FUNCTION=POWER
 @SHORTDESC=the value of @{x} raised to the power @{y} raised to the power of 1/@{z}
 @SYNTAX=POWER(x,y,z)
diff --git a/doc/C/functions.xml b/doc/C/functions.xml
index 3737fa8..461144c 100644
--- a/doc/C/functions.xml
+++ b/doc/C/functions.xml
@@ -12089,6 +12089,35 @@
       </para>
       </refsect1>
     </refentry>
+    <refentry id="gnumeric-function-POCHHAMMER">
+      <refmeta>
+        <refentrytitle>
+          <function>POCHHAMMER</function>
+        </refentrytitle>
+      </refmeta>
+      <refnamediv>
+        <refname>
+          <function>POCHHAMMER</function>
+        </refname>
+        <refpurpose>
+        the value of GAMMA(<parameter>x</parameter>+<parameter>n</parameter>)/GAMMA(<parameter>x</parameter>)
+      </refpurpose>
+      </refnamediv>
+      <refsynopsisdiv>
+        
<synopsis><function>POCHHAMMER</function>(<parameter>x</parameter>,<parameter>n</parameter>,<parameter>give_log</parameter>)</synopsis>
+      </refsynopsisdiv>
+      <refsect1>
+        <title>Arguments</title>
+        <para><parameter>x</parameter>: number</para>
+        <para><parameter>n</parameter>: number</para>
+        <para><parameter>give_log</parameter>: if true, log of the result will be returned instead</para>
+      </refsect1>
+      <refsect1>
+        <title>See also</title>
+        <para><link linkend="gnumeric-function-GAMMA"><function>GAMMA</function></link>.
+      </para>
+      </refsect1>
+    </refentry>
     <refentry id="gnumeric-function-POWER">
       <refmeta>
         <refentrytitle>
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index 205eb3c..5218758 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -1254,6 +1254,29 @@ gnumeric_power (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
 
 /***************************************************************************/
 
+static GnmFuncHelp const help_pochhammer[] = {
+        { GNM_FUNC_HELP_NAME, F_("POCHHAMMER:the value of GAMMA(@{x}+ {n})/GAMMA(@{x})")},
+        { GNM_FUNC_HELP_ARG, F_("x:number")},
+        { GNM_FUNC_HELP_ARG, F_("n:number")},
+       { GNM_FUNC_HELP_ARG, F_("give_log:if true, log of the result will be returned instead") },
+        { GNM_FUNC_HELP_EXAMPLES, "=POCHHAMMER(1,5)" },
+        { GNM_FUNC_HELP_EXAMPLES, "=POCHHAMMER(6,0.5)" },
+        { GNM_FUNC_HELP_SEEALSO, "GAMMA"},
+        { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_pochhammer (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+       gnm_float x = value_get_as_float (argv[0]);
+       gnm_float n = value_get_as_float (argv[1]);
+       gboolean give_log = argv[2] ? value_get_as_checked_bool (argv[2]) : FALSE;
+
+       return value_new_float (pochhammer (x, n, give_log));
+}
+
+/***************************************************************************/
+
 static GnmFuncHelp const help_log2[] = {
         { GNM_FUNC_HELP_NAME, F_("LOG2:the base-2 logarithm of @{x}")},
         { GNM_FUNC_HELP_ARG, F_("x:positive number")},
@@ -3289,6 +3312,9 @@ GnmFuncDescriptor const math_functions[] = {
        { "power",   "ff|f",       help_power,
          gnumeric_power, NULL, NULL, NULL,
          GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_SUPERSET, GNM_FUNC_TEST_STATUS_BASIC },
+       { "pochhammer",   "ff|b",       help_pochhammer,
+         gnumeric_pochhammer, NULL, NULL, NULL,
+         GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
        { "g_product", NULL,     help_g_product,
          NULL, gnumeric_g_product, 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 457df3e..3e69e2d 100644
--- a/plugins/fn-math/plugin.xml.in
+++ b/plugins/fn-math/plugin.xml.in
@@ -68,7 +68,9 @@
                                <function name="multinomial"/>
                                <function name="munit"/>
                                <function name="odd"/>
+                               <function name="odf.sumproduct"/>
                                <function name="pi"/>
+                               <function name="pochhammer"/>
                                <function name="power"/>
                                <function name="quotient"/>
                                <function name="radians"/>
@@ -87,7 +89,6 @@
                                <function name="suma"/>
                                <function name="sumif"/>
                                <function name="sumproduct"/>
-                               <function name="odf.sumproduct"/>
                                <function name="sumsq"/>
                                <function name="sumx2my2"/>
                                <function name="sumx2py2"/>
diff --git a/src/mathfunc.c b/src/mathfunc.c
index e0234f6..d82ad35 100644
--- a/src/mathfunc.c
+++ b/src/mathfunc.c
@@ -7104,3 +7104,48 @@ gnm_owent (gnm_float h, gnm_float a)
 }
 
 /* ------------------------------------------------------------------------- */
+
+/*
+ * Pochhammer's symbol: (x)_n = Gamma(x+n)/Gamma(x).
+ *
+ * While n is often an integer, that is not a requirement.
+ */
+
+gnm_float
+pochhammer (gnm_float x, gnm_float n, gboolean give_log)
+{
+       if (gnm_isnan (x) || gnm_isnan (n))
+               return gnm_nan;
+
+       /* This isn't a fundamental restriction, but one we impose.  */
+       if (x <= 0 || x + n <= 0)
+               return gnm_nan;
+
+       if (n == gnm_floor (n) && n >= 0 && n <= 40 && !give_log) {
+               gnm_float r;
+               for (r = 1; n-- > 0; x++)
+                       r *= x;
+               return r;
+       }
+
+       if (give_log) {
+               gnm_float lr;
+
+               if (x < 10 || x + n < 10) {
+                       int s;
+                       lr = gnm_lgamma_r (x + n, &s) - gnm_lgamma_r (x, &s);
+               } else {
+                       lr = ((x + n - 0.5) * gnm_log (x + n) -
+                             (x     - 0.5) * gnm_log (x) -
+                             n +
+                             lgammacor (x + n) -
+                             lgammacor (x));
+               }
+               return lr;
+       } else {
+               gnm_float lr = pochhammer (x, n, TRUE);
+               return gnm_exp (lr);
+       }
+}
+
+/* ------------------------------------------------------------------------- */
diff --git a/src/mathfunc.h b/src/mathfunc.h
index 0adca1d..038850e 100644
--- a/src/mathfunc.h
+++ b/src/mathfunc.h
@@ -36,6 +36,7 @@ gnm_float logspace_add (gnm_float logx, gnm_float logy);
 gnm_float logspace_sub (gnm_float logx, gnm_float logy);
 gnm_float stirlerr(gnm_float n);
 gnm_float gnm_owent (gnm_float h, gnm_float a);
+gnm_float pochhammer (gnm_float x, gnm_float n, gboolean give_log);
 
 gnm_float gnm_cot (gnm_float x);
 gnm_float gnm_acot (gnm_float x);


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