00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
#include <plearn/base/general.h>
00037
00038
00039
00040
namespace PLearn {
00041
using namespace std;
00042
00043 #define ITMAX 100
00044 #define EPS 3.0e-7
00045 #define FPMIN 1.0e-30
00046 #define Pi 3.141592653589793
00047 #define Log2Pi 1.837877066409
00048 #define Sqrt2Pi 2.506628274631
00049
00050 static double pl_gammln_cof[7]={ 1.000000000190015 ,
00051 76.18009172947146 ,
00052 -86.50532032941677 ,
00053 24.01409824083091 ,
00054 -1.231739572450155 ,
00055 0.1208650973866179e-2,
00056 -0.5395239384953e-5 };
00057
00058
00059
00060 real pl_gammln(
real z)
00061 {
00062
double gz,tmp;
00063
static double gamma = 5.0;
00064 gz = (z+0.5)*
log(z+gamma+0.5);
00065 gz -= z+gamma+0.5;
00066 gz += 0.5*
log(2*
Pi);
00067 tmp =
pl_gammln_cof[0];
00068
for(
int i=1;i<7;i++) tmp +=
pl_gammln_cof[i]/(z+i);
00069 gz +=
log(tmp/z);
00070
return(gz);
00071 }
00072
00073
00074 real pl_dgammlndz(
real z)
00075 {
00076
real tmp0=
pl_gammln_cof[0],
00077 tmp1= 0.0;
00078
for(
int i= 1; i<7; ++i)
00079 {
00080 tmp0+=
pl_gammln_cof[i]/(z+i);
00081 tmp1-=
pl_gammln_cof[i]/((z+i)*(z+i));
00082 }
00083
return (0.5+z)/(5.5+z)-1 + z*(-tmp0/(z*z) + tmp1/z)/tmp0 +
log(5.5+z);
00084 }
00085
00086
00087
00088
00089 real pl_gser(
real a,
real x) {
00090
real EPSILON = 1e-7;
00091
real g =
pl_gammln(a);
00092
real sum,term;
00093
if (
x<0 || a<0)
00094
PLERROR(
"Error in function pl_gser. Bad argument.");
00095
else if (
x==0)
00096
return 0;
00097
00098
sum = term = 1/a;
00099
for(
int i=1;i<
ITMAX;i++) {
00100 term *=
x/(a+i);
00101
sum += term;
00102
if (term <
sum*EPSILON)
break;
00103 }
00104
return exp(-
x+a*
log(
x)-g)*
sum;
00105 }
00106
00107
00108
00109
00110 real pl_gcf(
real a,
real x)
00111 {
00112
int i;
00113
real an,b,c,d,del,h;
00114
00115
real gln=
pl_gammln(a);
00116 b=
x+1.0-a;
00117 c=1.0/
FPMIN;
00118 d=1.0/b;
00119 h=d;
00120
for (i=1;i<=
ITMAX;i++) {
00121 an = -i*(i-a);
00122 b += 2.0;
00123 d=an*d+b;
00124
if (fabs(d) <
FPMIN) d=
FPMIN;
00125 c=b+an/c;
00126
if (fabs(c) <
FPMIN) c=
FPMIN;
00127 d=1.0/d;
00128 del=d*c;
00129 h *= del;
00130
if (fabs(del-1.0) <
EPS)
break;
00131 }
00132
if (i >
ITMAX) {
00133
PLERROR(
"a too large, ITMAX too small in pl_gcf");
00134 }
00135
return exp(-
x+a*
log(
x)-(gln))*h;
00136 }
00137
00138
00139
00140
00141 real pl_gammq(
real a,
real x) {
00142
if (
x<0 || a<0)
00143
PLERROR(
"Error in function gammax. Bad arguments.");
00144
if (
x<a+1)
00145
return 1-
pl_gser(a,
x);
00146
return pl_gcf(a,
x);
00147 }
00148
00149
00150
00151 real pl_erf(
real x) {
00152
return (
x<0?-1:1)*(1-
pl_gammq(0.5,
x*
x));
00153 }
00154
00155
00156
00157
00158 real gauss_01_cum(
real x) {
00159
return 0.5*(1+
pl_erf(
x/1.414214));
00160 }
00161
00162
00163
00164
00165 real gauss_01_quantile(
real q) {
00166
00167
real a=-2;
00168
real b=2;
00169
real cum_a=
gauss_01_cum(a);
00170
real cum_b=
gauss_01_cum(b);
00171
while (cum_a>q) { a*=1.5; cum_a=
gauss_01_cum(a); }
00172
while (cum_b<q) { b*=1.5; cum_b=
gauss_01_cum(b); }
00173
00174
for (;;) {
00175
real c=0.5*(a+b);
00176
real precision = fabs(b-a);
00177
00178
if (precision < 1e-6)
00179
return c;
00180
real cum_c =
gauss_01_cum(c);
00181
if (cum_c < q)
00182 a=c;
00183
else
00184 b=c;
00185 }
00186
return 0;
00187 }
00188
00189
00190
00191 real gauss_01_density(
real x)
00192 {
00193
return exp(-0.5*
x*
x) /
Sqrt2Pi;
00194 }
00195
00196 real gauss_01_log_density(
real x)
00197 {
00198
return -0.5*
x*
x - 0.5*
Log2Pi;
00199 }
00200
00201 real gauss_log_density_var(
real x,
real mu,
real var)
00202 {
00203
real dx=
x-mu;
00204
return -0.5*(dx*dx/
var +
Log2Pi +
log(
var));
00205
00206 }
00207
00208 real gauss_density_var(
real x,
real mu,
real var) {
00209
real dx =
x - mu;
00210
return exp(-0.5 * dx * dx /
var) /
Sqrt2Pi;
00211 }
00212
00213 real gauss_log_density_stddev(
real x,
real mu,
real sigma)
00214 {
00215
real dx = (
x-mu) / sigma;
00216
return -0.5*(dx*dx +
Log2Pi) -
log(sigma);
00217 }
00218
00219 real p_value(
real mu,
real vn)
00220 {
00221
return 1 -
gauss_01_cum(fabs(mu/
sqrt(vn)));
00222 }
00223
00224
00225 }