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 #include <it/types.h>
00026 #include <it/math.h>
00027 #include <it/vec.h>
00028 #include <it/io.h>
00029
00030
00031
00032 it_function (itf_differentiate)
00033 {
00034 volatile double round;
00035 double epsilon;
00036 double fmin, fmax;
00037 it_function_t f = it_this->function;
00038 it_args_t args = it_this->args;
00039
00040
00041 epsilon = 1e-6 * ((x > 0) ? (x) : (-x));
00042 if (epsilon < 1e-6)
00043 epsilon = 1e-6;
00044
00045
00046 round = x + epsilon;
00047 epsilon = round - x;
00048
00049
00050 fmax = f (x + epsilon, args);
00051 fmin = f (x - epsilon, args);
00052
00053 return ((fmax - fmin) / (2.0 * epsilon));
00054 }
00055
00056
00057
00058
00059 it_function (itf_diff2)
00060 {
00061 volatile double round;
00062 double epsilon;
00063 double fmin, fmid, fmax;
00064 it_function_t f = it_this->function;
00065 it_args_t args = it_this->args;
00066
00067
00068 epsilon = 1e-3 * ((x > 0) ? (x) : (-x));
00069 if (epsilon < 1e-3)
00070 epsilon = 1e-3;
00071
00072
00073 round = x + epsilon;
00074 epsilon = round - x;
00075
00076
00077 fmax = f (x + epsilon, args);
00078 fmin = f (x - epsilon, args);
00079 fmid = f (x, args);
00080
00081 return ((fmax - 2 * fmid + fmin) / (epsilon * epsilon));
00082 }
00083
00084
00085
00086
00087 it_function (itf_integrate_trapezoid)
00088 {
00089 double b = x;
00090 double a = it_this->a;
00091 int N = it_this->N;
00092 it_function_t f = it_this->function;
00093 it_args_t args = it_this->args;
00094 double step;
00095 double sum;
00096 int i;
00097
00098 step = (b - a) / N;
00099
00100 sum = f (a, args) / 2;
00101 x = a + step;
00102
00103 for (i = 1; i <= N - 1; i++) {
00104 sum += f (x, args);
00105 x += step;
00106 }
00107
00108 sum += f (b, args) / 2;
00109 sum *= step;
00110
00111 return (sum);
00112 }
00113
00114
00115
00116
00117 it_function (itf_integrate_romberg)
00118 {
00119 double b = x;
00120 double a = it_this->a;
00121 int N = it_this->N;
00122 int p = it_this->p;
00123 it_function_t f = it_this->function;
00124 it_args_t args = it_this->args;
00125 double step;
00126 double r;
00127 int i, n;
00128 vec S;
00129
00130 step = (b - a) / N;
00131
00132 S = vec_new (p);
00133
00134
00135 S[0] = f (a, args) / 2;
00136 x = a + step;
00137
00138 for (i = 1; i <= N - 1; i++) {
00139 S[0] += f (x, args);
00140 x += step;
00141 }
00142
00143 S[0] += f (b, args) / 2;
00144 S[0] *= step;
00145
00146
00147 for (n = 1; n < p; n++) {
00148
00149 step /= 2;
00150 N *= 2;
00151 x = a + step;
00152 S[n] = 0;
00153
00154 for (i = 1; i <= N - 1; i += 2) {
00155 S[n] += f (x, args);
00156 x += 2 * step;
00157 }
00158 S[n] *= step;
00159 S[n] += S[n - 1] / 2;
00160 }
00161
00162
00163 for (n = p - 1; n >= 0; n--) {
00164 r = (1 << 2 * (p - n));
00165 for (i = 0; i < n; i++)
00166 S[i] = (r * S[i + 1] - S[i]) / (r - 1);
00167 }
00168
00169 r = S[0];
00170
00171 vec_delete (S);
00172
00173 return (r);
00174 }
00175
00176
00177
00178
00179 it_function (itf_integrate)
00180 {
00181 it_function_args (itf_integrate_romberg) integrate_romberg_args;
00182 double b = x;
00183 double a = it_this->a;
00184 int N;
00185 int p;
00186
00187
00188 N = (int) (2 * (b - a) + 1);
00189 p = 10;
00190
00191 integrate_romberg_args.a = a;
00192 integrate_romberg_args.N = N;
00193 integrate_romberg_args.p = p;
00194 integrate_romberg_args.function = it_this->function;
00195 integrate_romberg_args.args = it_this->args;
00196
00197 return (itf_integrate_romberg (x, &integrate_romberg_args));
00198 }
00199
00200
00201
00202
00203 it_function (itf_expectation)
00204 {
00205 it_function_args (itf_mul) mul_args;
00206 it_function_args (itf_integrate) integrate_args;
00207
00208
00209 mul_args.f = itf_identity;
00210 mul_args.f_args = NULL;
00211 mul_args.g = it_this->function;
00212 mul_args.g_args = it_this->args;
00213 integrate_args.function = itf_mul;
00214 integrate_args.args = &mul_args;
00215 integrate_args.a = it_this->a;
00216
00217 return (itf_integrate (x, &integrate_args));
00218 }
00219
00220
00221
00222
00223 it_function (itf_compose)
00224 {
00225 it_function_t f = it_this->f;
00226 it_function_t g = it_this->g;
00227 it_args_t f_args = it_this->f_args;
00228 it_args_t g_args = it_this->g_args;
00229
00230 return (f (g (x, g_args), f_args));
00231 }
00232
00233
00234
00235
00236 it_function (itf_sum)
00237 {
00238 it_function_t f = it_this->f;
00239 it_function_t g = it_this->g;
00240 it_args_t f_args = it_this->f_args;
00241 it_args_t g_args = it_this->g_args;
00242
00243 return (f (x, f_args) + g (x, g_args));
00244 }
00245
00246
00247
00248
00249 it_function (itf_mul)
00250 {
00251 it_function_t f = it_this->f;
00252 it_function_t g = it_this->g;
00253 it_args_t f_args = it_this->f_args;
00254 it_args_t g_args = it_this->g_args;
00255
00256 return (f (x, f_args) * g (x, g_args));
00257 }
00258
00259
00260
00261
00262 it_function (itf_identity)
00263 {
00264 return (x);
00265 }
00266
00267
00268
00269
00270 it_function (itf_gaussian)
00271 {
00272 double sigma = it_this->sigma;
00273
00274 return (1. / (sqrt (2. * M_PI) * sigma) *
00275 exp (-x * x / (2. * sigma * sigma)));
00276 }
00277
00278
00279
00280
00281 it_function (itf_laplacian)
00282 {
00283 double lambda = it_this->lambda;
00284
00285 return (1. / (2. * lambda) * exp (-fabs (x) / lambda));
00286 }
00287
00288
00289
00290
00291 #ifdef WIN32
00292 it_function (itf_generalized_gaussian)
00293 {
00294 it_fprintf (stderr, "undefined function lgamma()\n");
00295 return (NAN);
00296 }
00297 #else
00298 it_function (itf_generalized_gaussian)
00299 {
00300 double alpha = it_this->alpha;
00301 double beta = it_this->beta;
00302
00303 assert (alpha > 0);
00304 assert (beta > 0);
00305
00306 return (beta / (2.0 * alpha) *
00307 exp (-lgamma (1.0 / beta) - pow (fabs (x) / alpha, beta)));
00308 }
00309 #endif
00310
00311
00312 #define erfinv_a3 -0.140543331
00313 #define erfinv_a2 0.914624893
00314 #define erfinv_a1 -1.645349621
00315 #define erfinv_a0 0.886226899
00316
00317 #define erfinv_b4 0.012229801
00318 #define erfinv_b3 -0.329097515
00319 #define erfinv_b2 1.442710462
00320 #define erfinv_b1 -2.118377725
00321 #define erfinv_b0 1
00322
00323 #define erfinv_c3 1.641345311
00324 #define erfinv_c2 3.429567803
00325 #define erfinv_c1 -1.62490649
00326 #define erfinv_c0 -1.970840454
00327
00328 #define erfinv_d2 1.637067800
00329 #define erfinv_d1 3.543889200
00330 #define erfinv_d0 1
00331
00332 #ifdef WIN32
00333 double erfinv (double x)
00334 {
00335 it_fprintf (stderr, "undefined function erf()\n");
00336 return (NAN);
00337 }
00338 #else
00339 double erfinv (double x)
00340 {
00341 double x2, r, y;
00342 int sign_x;
00343
00344 if (x < -1 || x > 1)
00345 return NAN;
00346
00347 if (x == 0)
00348 return 0;
00349
00350 if (x > 0)
00351 sign_x = 1;
00352 else {
00353 sign_x = -1;
00354 x = -x;
00355 }
00356
00357 if (x <= 0.7) {
00358
00359 x2 = x * x;
00360 r =
00361 x * (((erfinv_a3 * x2 + erfinv_a2) * x2 + erfinv_a1) * x2 + erfinv_a0);
00362 r /= (((erfinv_b4 * x2 + erfinv_b3) * x2 + erfinv_b2) * x2 +
00363 erfinv_b1) * x2 + erfinv_b0;
00364 }
00365 else {
00366 y = sqrt (-log ((1 - x) / 2));
00367 r = (((erfinv_c3 * y + erfinv_c2) * y + erfinv_c1) * y + erfinv_c0);
00368 r /= ((erfinv_d2 * y + erfinv_d1) * y + erfinv_d0);
00369 }
00370
00371 r = r * sign_x;
00372 x = x * sign_x;
00373
00374 r -= (erf (r) - x) / (2 / sqrt (M_PI) * exp (-r * r));
00375 r -= (erf (r) - x) / (2 / sqrt (M_PI) * exp (-r * r));
00376
00377 return r;
00378 }
00379 #endif
00380
00381 #undef erfinv_a3
00382 #undef erfinv_a2
00383 #undef erfinv_a1
00384 #undef erfinv_a0
00385
00386 #undef erfinv_b4
00387 #undef erfinv_b3
00388 #undef erfinv_b2
00389 #undef erfinv_b1
00390 #undef erfinv_b0
00391
00392 #undef erfinv_c3
00393 #undef erfinv_c2
00394 #undef erfinv_c1
00395 #undef erfinv_c0
00396
00397 #undef erfinv_d2
00398 #undef erfinv_d1
00399 #undef erfinv_d0
00400
00401
00402
00403 static int nchoosek_tmp (int n, int k)
00404 {
00405 if (k == 0)
00406 return 1;
00407
00408 return (n * nchoosek_tmp (n - 1, k - 1)) / k;
00409 }
00410
00411
00412 int nchoosek (int n, int k)
00413 {
00414 if (k > n || k < 0)
00415 return 0;
00416
00417 if (k > n / 2)
00418 k = n - k;
00419
00420 return nchoosek_tmp (n, k);
00421 }
00422
00423
00424
00425 double lognchoosek (int n, int k)
00426 {
00427 int i;
00428 double r = 0;
00429 if (k > n || k < 0)
00430 return 0;
00431
00432 if (k > n / 2)
00433 k = n - k;
00434
00435 for (i = 1; i <= k; i++)
00436 r -= log (i);
00437
00438 for (i = n - k + 1; i <= n; i++)
00439 r += log (i);
00440
00441 return r;
00442 }
00443
00444
00445 double it_integrate (it_function_t function, it_args_t args, double a,
00446 double b)
00447 {
00448 it_function_args (itf_integrate) integrate_args;
00449
00450 integrate_args.function = function;
00451 integrate_args.args = args;
00452 integrate_args.a = a;
00453 return (itf_integrate (b, &integrate_args));
00454 }
00455
00456 double it_differentiate (it_function_t function, it_args_t args, double a)
00457 {
00458 it_function_args (itf_differentiate) differentiate_args;
00459
00460 differentiate_args.function = function;
00461 differentiate_args.args = args;
00462 return (itf_differentiate (a, &differentiate_args));
00463 }
00464
00465
00466
00467
00468 double log_sum(double log_a, double log_b)
00469 {
00470 if (log_a < log_b)
00471 return log_b + log (1 + exp(log_a - log_b));
00472 else
00473 return log_a + log (1 + exp(log_b - log_a));
00474 }
00475
00476
00477
00478 double log_gamma (double x)
00479 {
00480 double z=1/(x*x);
00481
00482 x=x+6;
00483 z=(((-0.000595238095238*z+0.000793650793651)
00484 *z-0.002777777777778)*z+0.083333333333333)/x;
00485 z=(x-0.5)*log(x)-x+0.918938533204673+z-log(x-1)-
00486 log(x-2)-log(x-3)-log(x-4)-log(x-5)-log(x-6);
00487 return z;
00488 }
00489
00490
00491
00492 double sigmoid (double x, double lambda)
00493 {
00494 return 1 / (1 + exp (-lambda * x));
00495 }
00496
00497
00498 double invsigmoid (double x, double lambda)
00499 {
00500 return - log(1 / x - 1) / lambda;
00501 }