[gnumeric] Add RANDSNORM and RANDSTDIST. [#144717]
- From: Andreas J. Guelzow <guelzow src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gnumeric] Add RANDSNORM and RANDSTDIST. [#144717]
- Date: Sun, 11 Oct 2009 17:14:31 +0000 (UTC)
commit 9aa04633550e4e5a5317245986a3a3e86795264d
Author: Andreas J. Guelzow <aguelzow pyrshep ca>
Date: Sun Oct 11 11:13:50 2009 -0600
Add RANDSNORM and RANDSTDIST. [#144717]
2009-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
* plugin.xml.in: add randsnorm and randstdist
* functions.c (help_randtdist): use a more reasonable degrees
of freedom
(help_randsnorm): new
(gnumeric_randsnorm): new
(help_randstdist): new
(gnumeric_randstdist): new
(random_functions): add randsnorm and randstdist
2009-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
* src/mathfunc.c (random_skew_normal): new
(random_skew_tdist): new
* src/mathfunc.h (random_skew_normal): new
(random_skew_tdist): new
ChangeLog | 7 ++++
NEWS | 3 ++
plugins/fn-random/ChangeLog | 11 ++++++
plugins/fn-random/functions.c | 71 +++++++++++++++++++++++++++++++++++++-
plugins/fn-random/plugin.xml.in | 2 +
src/mathfunc.c | 48 ++++++++++++++++++++++++++
src/mathfunc.h | 2 +
7 files changed, 142 insertions(+), 2 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 2355748..45c0bb8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * src/mathfunc.c (random_skew_normal): new
+ (random_skew_tdist): new
+ * src/mathfunc.h (random_skew_normal): new
+ (random_skew_tdist): new
+
2009-10-11 Morten Welinder <terra gnome org>
* configure.in: Post-release bump.
diff --git a/NEWS b/NEWS
index 26dbe63..89e6455 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,8 @@
Gnumeric 1.9.15
+Andreas:
+ * Add RANDSNORM and RANDSTDIST. [#144717]
+
--------------------------------------------------------------------------
Gnumeric 1.9.14
diff --git a/plugins/fn-random/ChangeLog b/plugins/fn-random/ChangeLog
index 32a2d28..8f0d16c 100644
--- a/plugins/fn-random/ChangeLog
+++ b/plugins/fn-random/ChangeLog
@@ -1,3 +1,14 @@
+2009-10-11 Andreas J. Guelzow <aguelzow pyrshep ca>
+
+ * plugin.xml.in: add randsnorm and randstdist
+ * functions.c (help_randtdist): use a more reasonable degrees
+ of freedom
+ (help_randsnorm): new
+ (gnumeric_randsnorm): new
+ (help_randstdist): new
+ (gnumeric_randstdist): new
+ (random_functions): add randsnorm and randstdist
+
2009-10-11 Morten Welinder <terra gnome org>
* Release 1.9.14
diff --git a/plugins/fn-random/functions.c b/plugins/fn-random/functions.c
index 42b92ac..a21e29f 100644
--- a/plugins/fn-random/functions.c
+++ b/plugins/fn-random/functions.c
@@ -669,8 +669,8 @@ gnumeric_randchisq (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
static GnmFuncHelp const help_randtdist[] = {
{ GNM_FUNC_HELP_NAME, F_("RANDTDIST:random variate from a Student t distribution") },
{ GNM_FUNC_HELP_ARG, F_("df:degrees of freedom") },
- { GNM_FUNC_HELP_EXAMPLES, "=RANDTDIST(0.5)" },
- { GNM_FUNC_HELP_EXAMPLES, "=RANDTDIST(0.5)" },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDTDIST(5)" },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDTDIST(5)" },
{ GNM_FUNC_HELP_SEEALSO, "RAND" },
{ GNM_FUNC_HELP_END}
};
@@ -878,6 +878,67 @@ gnumeric_simtable (GnmFuncEvalInfo *ei, int argc, GnmExprConstPtr const *argv)
/***************************************************************************/
+static GnmFuncHelp const help_randsnorm[] = {
+ { GNM_FUNC_HELP_NAME, F_("RANDNORM:random variate from a skew normal distribution") },
+ { GNM_FUNC_HELP_ARG, F_("a: amount of skew, defaults to 0") },
+ { GNM_FUNC_HELP_ARG, F_("\xce\xbc:mean of the underlying normal distribution, defaults to 0") },
+ { GNM_FUNC_HELP_ARG, F_("\xcf\x83:standard deviation of the underlying normal distribution, defaults to 1") },
+ { GNM_FUNC_HELP_NOTE, F_("If @{\xcf\x83} < 0, RANDSNORM returns #NUM!") },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDSNORM(-3,0,1)" },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDSNORM(-3,0,1)" },
+ { GNM_FUNC_HELP_SEEALSO, "RANDNORM" },
+ { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_randsnorm (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+ gnm_float alpha = 0.;
+ gnm_float mean = 0.;
+ gnm_float stdev = 1.;
+ gnm_float result;
+
+ if (argv[0]) {
+ alpha = value_get_as_float (argv[0]);
+ if (argv[1]) {
+ mean = value_get_as_float (argv[1]);
+ if (argv[2])
+ stdev = value_get_as_float (argv[2]);
+ }
+ }
+
+ if (stdev < 0)
+ return value_new_error_NUM (ei->pos);
+
+ result = ((alpha == 0.) ? random_normal () : random_skew_normal (alpha));
+
+ return value_new_float (stdev * result + mean);
+}
+
+/***************************************************************************/
+
+static GnmFuncHelp const help_randstdist[] = {
+ { GNM_FUNC_HELP_NAME, F_("RANDSTDIST:random variate from a skew t distribution") },
+ { GNM_FUNC_HELP_ARG, F_("df:degrees of freedom") },
+ { GNM_FUNC_HELP_ARG, F_("a: amount of skew, defaults to 0") },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDSTDIST(5,-2)" },
+ { GNM_FUNC_HELP_EXAMPLES, "=RANDSTDIST(5,2)" },
+ { GNM_FUNC_HELP_SEEALSO, "RANDTDIST" },
+ { GNM_FUNC_HELP_END}
+};
+
+static GnmValue *
+gnumeric_randstdist (GnmFuncEvalInfo *ei, GnmValue const * const *argv)
+{
+ gnm_float nu = value_get_as_float (argv[0]);
+ gnm_float alpha = argv[1] ? value_get_as_float (argv[1]) : 0.;
+
+ return ((alpha == 0.) ? value_new_float (random_tdist (nu))
+ : value_new_float (random_skew_tdist (nu, alpha)));;
+}
+
+/***************************************************************************/
+
GnmFuncDescriptor const random_functions[] = {
{ "rand", "", help_rand,
gnumeric_rand, NULL, NULL, NULL, NULL,
@@ -963,6 +1024,12 @@ GnmFuncDescriptor const random_functions[] = {
{ "randrayleightail", "ff", help_randrayleightail,
gnumeric_randrayleightail, NULL, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
+ { "randsnorm", "|fff", help_randsnorm,
+ gnumeric_randsnorm, NULL, NULL, NULL, NULL,
+ GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
+ { "randstdist", "ff", help_randstdist,
+ gnumeric_randstdist, NULL, NULL, NULL, NULL,
+ GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
{ "randtdist", "f", help_randtdist,
gnumeric_randtdist, NULL, NULL, NULL, NULL,
GNM_FUNC_SIMPLE, GNM_FUNC_IMPL_STATUS_UNIQUE_TO_GNUMERIC, GNM_FUNC_TEST_STATUS_NO_TESTSUITE },
diff --git a/plugins/fn-random/plugin.xml.in b/plugins/fn-random/plugin.xml.in
index 36cf18d..5c1508c 100644
--- a/plugins/fn-random/plugin.xml.in
+++ b/plugins/fn-random/plugin.xml.in
@@ -39,6 +39,8 @@
<function name="randpoisson"/>
<function name="randrayleigh"/>
<function name="randrayleightail"/>
+ <function name="randsnorm"/>
+ <function name="randstdist"/>
<function name="randtdist"/>
<function name="randuniform"/>
<function name="randweibull"/>
diff --git a/src/mathfunc.c b/src/mathfunc.c
index d1b0a07..42bf902 100644
--- a/src/mathfunc.c
+++ b/src/mathfunc.c
@@ -7617,6 +7617,54 @@ random_landau (void)
/* ------------------------------------------------------------------------ */
+/*
+ * Generate a skew-normal distributed random number.
+ *
+ * based on the information provided at
+ * http://azzalini.stat.unipd.it/SN/faq.html
+ *
+ */
+
+gnm_float
+random_skew_normal (gnm_float a)
+{
+ gnm_float result;
+ gnm_float asq = a * a;
+ gnm_float delta = gnm_sqrt (asq / (1 + asq));
+ gnm_float u = random_normal ();
+ gnm_float v = random_normal ();
+
+ if (a < 0.)
+ delta *= -1.;
+ result = delta * u + gnm_sqrt (1-delta*delta) * v;
+
+ return ((u < 0.) ? -result : result);
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+/*
+ * Generate a skew-t distributed random number.
+ *
+ * based on the information provided at
+ * http://azzalini.stat.unipd.it/SN/faq.html
+ *
+ */
+
+gnm_float
+random_skew_tdist (gnm_float nu, gnm_float a)
+{
+ gnm_float chi = random_chisq (nu);
+ gnm_float z = random_skew_normal (a);;
+
+ return (z / gnm_sqrt(chi/nu));
+}
+
+
+/* ------------------------------------------------------------------------ */
+
+
gnm_float
combin (gnm_float n, gnm_float k)
diff --git a/src/mathfunc.h b/src/mathfunc.h
index 5179221..38796be 100644
--- a/src/mathfunc.h
+++ b/src/mathfunc.h
@@ -155,6 +155,8 @@ gnm_float random_levy_skew (gnm_float c, gnm_float alpha,
gnm_float random_exppow (gnm_float a, gnm_float b);
gnm_float random_landau (void);
gnm_float random_gaussian_tail (gnm_float a, gnm_float sigma);
+gnm_float random_skew_normal (gnm_float a);
+gnm_float random_skew_tdist (gnm_float nu, gnm_float a);
/* The probability density functions. */
gnm_float random_exppow_pdf (gnm_float x, gnm_float a, gnm_float b);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]