Commit 57977759 authored by Morten Welinder's avatar Morten Welinder

AGM: New function.

parent 851e3863
......@@ -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
......
......@@ -3207,6 +3207,15 @@ The depreciation coefficient used is:
@ARGUMENTDESCRIPTION=@{x}: number
@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
......
......@@ -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>
......
......@@ -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 },
......
......@@ -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"/>
......
......@@ -4964,6 +4964,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
......
......@@ -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. */
......
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>
......
......@@ -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 \
......
......@@ -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 });
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
......
......@@ -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 )
......
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