[gnumeric] AGM: New function.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] AGM: New function.
- Date: Sat, 9 Jan 2016 19:02:48 +0000 (UTC)
commit 57977759be3136f2e9a2026b5c673ed2fc00fc64
Author: Morten Welinder <terra gnome org>
Date: Sat Jan 9 14:01:49 2016 -0500
AGM: New function.
NEWS | 1 +
doc/C/func.defs | 9 +++++
doc/C/functions.xml | 33 +++++++++++++++++
plugins/fn-math/functions.c | 28 +++++++++++++-
plugins/fn-math/plugin.xml.in | 1 +
samples/burkardt.gnumeric | Bin 0 -> 31314 bytes
samples/burkhardt.gnumeric | Bin 30093 -> 0 bytes
src/mathfunc.c | 47 ++++++++++++++++++++++++
src/mathfunc.h | 1 +
test/ChangeLog | 7 +++-
test/Makefile.am | 2 +-
test/{t1012-burkhardt.pl => t1012-burkardt.pl} | 2 +-
tools/ChangeLog | 4 ++
tools/process-burkardt.c | 14 ++++++--
14 files changed, 141 insertions(+), 8 deletions(-)
---
diff --git a/NEWS b/NEWS
index 1d51e25..55b7db8 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,7 @@ Morten:
[#760043] [#760103] [#760102] [#760101] [#760105] [#760106]
[#760104] [#760229] [#760231] [#760232]
* Fix R.DBINOM extreme-value case. [#760230]
+ * New function AGM.
--------------------------------------------------------------------------
Gnumeric 1.12.26
diff --git a/doc/C/func.defs b/doc/C/func.defs
index 92dc7a5..18d6b88 100644
--- a/doc/C/func.defs
+++ b/doc/C/func.defs
@@ -3208,6 +3208,15 @@ The depreciation coefficient used is:
@SEEALSO=COTH,TANH
@CATEGORY=Mathematics
+ FUNCTION=AGM
+ SHORTDESC=the arithmetic-geometric mean
+ SYNTAX=AGM(a,b)
+ ARGUMENTDESCRIPTION=@{a}: value
+ {b}: value
+ DESCRIPTION=AGM computes the arithmetic-geometric mean of the two values.
+ SEEALSO=AVERAGE,GEOMEAN
+
+ CATEGORY=Mathematics
@FUNCTION=ARABIC
@SHORTDESC=the Roman numeral @{roman} as number
@SYNTAX=ARABIC(roman)
diff --git a/doc/C/functions.xml b/doc/C/functions.xml
index a92939a..45263b2 100644
--- a/doc/C/functions.xml
+++ b/doc/C/functions.xml
@@ -10367,6 +10367,39 @@
</para>
</refsect1>
</refentry>
+ <refentry id="gnumeric-function-AGM">
+ <refmeta>
+ <refentrytitle>
+ <function>AGM</function>
+ </refentrytitle>
+ </refmeta>
+ <refnamediv>
+ <refname>
+ <function>AGM</function>
+ </refname>
+ <refpurpose>
+ the arithmetic-geometric mean
+ </refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <synopsis><function>AGM</function>(<parameter>a</parameter>,<parameter>b</parameter>)</synopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>Arguments</title>
+ <para><parameter>a</parameter>: value</para>
+ <para><parameter>b</parameter>: value</para>
+ </refsect1>
+ <refsect1>
+ <title>Description</title>
+ <para><function>AGM</function> computes the arithmetic-geometric mean of the two values.</para>
+ </refsect1>
+ <refsect1>
+ <title>See also</title>
+ <para><link linkend="gnumeric-function-AVERAGE"><function>AVERAGE</function></link>,
+ <link linkend="gnumeric-function-GEOMEAN"><function>GEOMEAN</function></link>.
+ </para>
+ </refsect1>
+ </refentry>
<refentry id="gnumeric-function-ARABIC">
<refmeta>
<refentrytitle>
diff --git a/plugins/fn-math/functions.c b/plugins/fn-math/functions.c
index cf0a83a..7533739 100644
--- a/plugins/fn-math/functions.c
+++ b/plugins/fn-math/functions.c
@@ -450,6 +450,27 @@ gnumeric_atan2 (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
return value_new_float (gnm_atan2 (y, x));
}
+/***************************************************************************/
+
+static GnmFuncHelp const help_agm[] = {
+ { GNM_FUNC_HELP_NAME, F_("AGM:the arithmetic-geometric mean") },
+ { GNM_FUNC_HELP_ARG, F_("a:value")},
+ { GNM_FUNC_HELP_ARG, F_("b:value")},
+ { GNM_FUNC_HELP_DESCRIPTION, F_("AGM computes the arithmetic-geometric mean of the two values.")},
+ { GNM_FUNC_HELP_EXAMPLES, "=AGM(1,4)" },
+ { GNM_FUNC_HELP_EXAMPLES, "=AGM(0.5,1)" },
+ { GNM_FUNC_HELP_SEEALSO, "AVERAGE,GEOMEAN"},
+ { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_agm (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+ gnm_float a = value_get_as_float (argv[0]);
+ gnm_float b = value_get_as_float (argv[1]);
+
+ return value_new_float (agm (a, b));
+}
/***************************************************************************/
@@ -3288,12 +3309,15 @@ GnmFuncDescriptor const math_functions[] = {
{ "acosh", "f", help_acosh,
gnumeric_acosh, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_EXHAUSTIVE },
- { "acot", "f", help_acot,
+ { "acot", "f", help_acot,
gnumeric_acot, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
- { "acoth", "f", help_acoth,
+ { "acoth", "f", help_acoth,
gnumeric_acoth, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
+ { "agm", "ff", help_agm,
+ gnumeric_agm, NULL, NULL, NULL,
+ GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
{ "arabic", "S", help_arabic,
gnumeric_arabic, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_COMPLETE, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
diff --git a/plugins/fn-math/plugin.xml.in b/plugins/fn-math/plugin.xml.in
index 4180f9b..50f3075 100644
--- a/plugins/fn-math/plugin.xml.in
+++ b/plugins/fn-math/plugin.xml.in
@@ -16,6 +16,7 @@
<function name="acosh"/>
<function name="acot"/>
<function name="acoth"/>
+ <function name="agm"/>
<function name="arabic"/>
<function name="asin"/>
<function name="asinh"/>
diff --git a/samples/burkardt.gnumeric b/samples/burkardt.gnumeric
new file mode 100644
index 0000000..c3fd4f4
Binary files /dev/null and b/samples/burkardt.gnumeric differ
diff --git a/src/mathfunc.c b/src/mathfunc.c
index bb7c598..50fabe8 100644
--- a/src/mathfunc.c
+++ b/src/mathfunc.c
@@ -4965,6 +4965,53 @@ expmx2h (gnm_float x)
/* ------------------------------------------------------------------------- */
/**
+ * agm:
+ * @a: a number
+ * @b: a number
+ *
+ * Returns: The arithmetic-geometric mean of @a and @b.
+ */
+gnm_float
+agm (gnm_float a, gnm_float b)
+{
+ gnm_float ab = a * b;
+ gnm_float scale = 1;
+ int i;
+
+ if (a < 0 || b < 0 || gnm_isnan (ab))
+ return gnm_nan;
+
+ if (a == gnm_pinf || b == gnm_pinf)
+ return gnm_pinf;
+ if (a == 0 || b == 0)
+ return 0;
+
+ if (ab == 0 || ab == gnm_pinf) {
+ // Underflow or overflow
+ int ea, eb;
+ (void)gnm_frexp (a, &ea);
+ (void)gnm_frexp (b, &eb);
+ scale = gnm_ldexp (1, -(ea + eb) / 2);
+ a *= scale;
+ b *= scale;
+ }
+
+ for (i = 1; i < 20; i++) {
+ gnm_float am = (a + b) / 2;
+ gnm_float gm = gnm_sqrt (a * b);
+ a = am;
+ b = gm;
+ if (gnm_abs (a - b) < a * GNM_EPSILON)
+ break;
+ }
+ if (i == 20)
+ g_warning ("AGM failed to converge.");
+
+ return a / scale;
+}
+
+
+/**
* pow1p:
* @x: a number
* @y: a number
diff --git a/src/mathfunc.h b/src/mathfunc.h
index b1122f8..173cc0d 100644
--- a/src/mathfunc.h
+++ b/src/mathfunc.h
@@ -37,6 +37,7 @@ gnm_float logspace_sub (gnm_float logx, gnm_float logy);
gnm_float gnm_owent (gnm_float h, gnm_float a);
gnm_float gnm_logcf (gnm_float x, gnm_float i, gnm_float d);
gnm_float expmx2h (gnm_float x);
+gnm_float agm(gnm_float a, gnm_float b);
/* "d": density. */
/* "p": distribution function. */
diff --git a/test/ChangeLog b/test/ChangeLog
index 77dd6e1..91bb2ef 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,6 +1,11 @@
+2016-01-09 Morten Welinder <terra gnome org>
+
+ * t1012-burkardt.pl: Rename from t1012-burkhardt.pl
+
2015-04-12 Andreas J. Guelzow <aguelzow pyrshep ca>
- * ods-ext-schema.patch: replace gnm:style with gnm:am-suffix and gnm:pm-suffix
+ * ods-ext-schema.patch: replace gnm:style with gnm:am-suffix and
+ gnm:pm-suffix
2015-12-28 Morten Welinder <terra gnome org>
diff --git a/test/Makefile.am b/test/Makefile.am
index 9efafd1..4301d03 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -38,7 +38,7 @@ TESTS = t1000-statfuns.pl \
t1009-lookfuns.pl \
t1010-bitwise.pl \
t1011-yalta2008.pl \
- t1012-burkhardt.pl \
+ t1012-burkardt.pl \
t1013-crlibm.pl \
t1100-chitest.pl \
t1101-ftest.pl \
diff --git a/test/t1012-burkhardt.pl b/test/t1012-burkardt.pl
similarity index 89%
rename from test/t1012-burkhardt.pl
rename to test/t1012-burkardt.pl
index 12eb1f7..a7248c4 100755
--- a/test/t1012-burkhardt.pl
+++ b/test/t1012-burkardt.pl
@@ -5,6 +5,6 @@ use strict;
use lib ($0 =~ m|^(.*/)| ? $1 : ".");
use GnumericTest;
-my $file = "burkhardt.gnumeric";
+my $file = "burkardt.gnumeric";
&message ("Check that $file evaluates correctly.");
&test_sheet_calc ("$samples/$file", "D1", sub { $_ > 11.5 });
diff --git a/tools/ChangeLog b/tools/ChangeLog
index 956bca3..d31d3b3 100644
--- a/tools/ChangeLog
+++ b/tools/ChangeLog
@@ -1,3 +1,7 @@
+2016-01-09 Morten Welinder <terra gnome org>
+
+ * process-burkardt.c: Add agm. Fix bit-rot.
+
2015-12-28 Morten Welinder <terra gnome org>
* Release 1.12.26
diff --git a/tools/process-burkardt.c b/tools/process-burkardt.c
index bf56c9d..e79951b 100644
--- a/tools/process-burkardt.c
+++ b/tools/process-burkardt.c
@@ -18,6 +18,7 @@ typedef enum {
GT_DD_D,
GT_DDD_D,
GT_DI_D,
+ GT_I_D,
GT_ID_D,
GT_IDI_D,
GT_IID_D,
@@ -63,6 +64,10 @@ test_func (const char *func_name,
generator (&n_data, &xd[0], &xi[1], &yd);
types = "DI:D";
break;
+ case GT_I_D:
+ generator (&n_data, &xi[0], &yd);
+ types = "I:D";
+ break;
case GT_ID_D:
generator (&n_data, &xi[0], &xd[1], &yd);
types = "ID:D";
@@ -192,6 +197,7 @@ main (int argc, char **argv)
test_func ("acos", arccos_values, GT_D_D, NULL);
test_func ("acosh", arccosh_values, GT_D_D, NULL);
+ test_func ("agm", agm_values, GT_DD_D, NULL);
test_func ("asin", arcsin_values, GT_D_D, NULL);
test_func ("asinh", arcsinh_values, GT_D_D, NULL);
test_func ("atan", arctan_values, GT_D_D, NULL);
@@ -233,8 +239,9 @@ main (int argc, char **argv)
test_func ("r.pf", f_cdf_values, GT_IID_D, "312");
// f_noncentral_cdf_values ( int *n_data, int *n1, int *n2, double *lambda,
- test_func ("fact", factorial_values, GT_I_I, NULL);
- test_func ("factdouble", factorial2_values, GT_I_I, NULL);
+ test_func ("fact", i4_factorial_values, GT_I_I, NULL);
+ test_func ("fact", r8_factorial_values, GT_I_D, NULL);
+ test_func ("factdouble", i4_factorial2_values, GT_I_I, NULL);
// factorial_rising_values ( int *n_data, int *m, int *n, int *fmn )
// fresnel_cos_values ( int *n_data, double *x, double *fx )
// fresnel_sin_values ( int *n_data, double *x, double *fx )
@@ -305,7 +312,8 @@ main (int argc, char **argv)
// partition_distinct_count_values ( int *n_data, int *n, int *c )
test_func ("nt_phi", phi_values, GT_I_I, NULL);
if (do_slow) test_func ("nt_pi", pi_values, GT_I_I, NULL);
- test_func ("pochhammer", pochhammer_values, GT_DD_D, NULL);
+ test_func ("pochhammer", i4_rise_values, GT_II_I, NULL);
+ test_func ("pochhammer", r8_rise_values, GT_DI_D, NULL);
test_func ("r.ppois", poisson_cdf_values, GT_DI_D, "21");
// polylogarithm_values ( int *n_data, int *n, double *z, double *fx )
// prandtl_values ( int *n_data, double *tc, double *p, double *pr )
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]