diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2014-01-11 20:45:37 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2014-01-11 20:45:37 -0800 |
commit | c1535145101cf8758f3716c2e4fd3ddaa722f21c (patch) | |
tree | 1d6883ffff0ba1ca3c03c4fbbf1d5aa79008b511 | |
parent | 5ee9c6e95736d9ae925fedab4caa0c615d115fb2 (diff) | |
download | txr-c1535145101cf8758f3716c2e4fd3ddaa722f21c.tar.gz txr-c1535145101cf8758f3716c2e4fd3ddaa722f21c.tar.bz2 txr-c1535145101cf8758f3716c2e4fd3ddaa722f21c.zip |
* arith.c (to_float): Print function name as ~a rather than ~s,
so it doesn't have quotes around it.
(cum_norm_dist): New function.
* arith.h (cum_norm_dist): Declared.
* eval.c: Include arith.h.
(eval_init): Register cum_norm_dist as intrinsic.
* txr.1: Documented cum-norm-dist.
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | arith.c | 56 | ||||
-rw-r--r-- | arith.h | 1 | ||||
-rw-r--r-- | eval.c | 2 | ||||
-rw-r--r-- | txr.1 | 14 |
5 files changed, 85 insertions, 1 deletions
@@ -1,3 +1,16 @@ +2014-01-11 Kaz Kylheku <kaz@kylheku.com> + + * arith.c (to_float): Print function name as ~a rather than ~s, + so it doesn't have quotes around it. + (cum_norm_dist): New function. + + * arith.h (cum_norm_dist): Declared. + + * eval.c: Include arith.h. + (eval_init): Register cum_norm_dist as intrinsic. + + * txr.1: Documented cum-norm-dist. + 2014-01-10 Kaz Kylheku <kaz@kylheku.com> * configure: Detect platforms which don't reveal declarations @@ -927,7 +927,7 @@ static val to_float(val func, val num) case FLNUM: return num; default: - uw_throwf(error_s, lit("~s: invalid operand ~s"), func, num, nao); + uw_throwf(error_s, lit("~a: invalid operand ~s"), func, num, nao); } } @@ -1815,6 +1815,60 @@ val maskv(val bits) return accum; } +/* + * Source: + * Better Approximations to Cumulative Normal Functions + * Graeme West + * 2009 + */ +val cum_norm_dist(val arg) +{ + val arg_flo = to_float(lit("cum-norm-dist"), arg); + double x = c_flo(arg_flo); + double xabs = fabs(x); + + if (xabs > 37.0) { + return flo(1.0); + } else { + double ex = exp(-(xabs * xabs) / 2.0); + double retval, accum; + + if (xabs < 7.07106781186547) { + accum = 3.52624965998911E-02 * xabs + 0.700383064443688; + accum = accum * xabs + 6.37396220353165; + accum = accum * xabs + 33.912866078383; + accum = accum * xabs + 112.079291497871; + accum = accum * xabs + 221.213596169931; + accum = accum * xabs + 220.206867912376; + + retval = ex * accum; + + accum = 8.83883476483184E-02 * xabs + 1.75566716318264; + accum = accum * xabs + 16.064177579207; + accum = accum * xabs + 86.7807322029461; + accum = accum * xabs + 296.564248779674; + accum = accum * xabs + 637.333633378831; + accum = accum * xabs + 793.826512519948; + accum = accum * xabs + 440.413735824752; + + retval /= accum; + } else { + accum = xabs + 0.65; + accum = xabs + 4.0 / accum; + accum = xabs + 3.0 / accum; + accum = xabs + 2.0 / accum; + accum = xabs + 1.0 / accum; + + retval = ex / accum / 2.506628274631; + } + + if (x > 0) + retval = 1.0 - retval; + + return flo(retval); + } +} + void arith_init(void) { mp_init(&NUM_MAX_MP); @@ -30,4 +30,5 @@ val bignum_from_long(long l); int highest_bit(int_ptr_t n); val normalize(val bignum); val in_int_ptr_range(val bignum); +val cum_norm_dist(val x); void arith_init(void); @@ -46,6 +46,7 @@ #endif #include "lib.h" #include "gc.h" +#include "arith.h" #include "signal.h" #include "unwind.h" #include "regex.h" @@ -2351,6 +2352,7 @@ void eval_init(void) reg_fun(intern(lit("log"), user_package), func_n1(loga)); reg_fun(intern(lit("exp"), user_package), func_n1(expo)); reg_fun(intern(lit("sqrt"), user_package), func_n1(sqroot)); + reg_fun(intern(lit("cum-norm-dist"), user_package), func_n1(cum_norm_dist)); reg_fun(intern(lit("fixnump"), user_package), func_n1(fixnump)); reg_fun(intern(lit("bignump"), user_package), func_n1(bignump)); reg_fun(intern(lit("floatp"), user_package), func_n1(floatp)); @@ -8982,6 +8982,20 @@ must be positive. The return value is <base> raised to <exponent>, and reduced to the least positive residue modulo <modulus>. +.SS Function cum-norm-dist + +.TP +Syntax: + + (cum-norm-dist <argument>) + +.TP +Description: + +The cum-norm-dist function calculates an approximation to the cumulative normal +distribution function: the integral, of the normal distribution function, from +negative infinity to the <argument>. + .SS Functions fixnump, bignump, integerp, floatp, numberp .TP |