00001
00002
00003
00004 (function( factory ) {
00005 if ( typeof define === "function" && define.amd ) {
00006
00007 define( ['JSRootCore'], factory );
00008 } else {
00009 if (typeof JSROOT == 'undefined')
00010 throw new Error("This extension requires JSRootCore.js", "JSRootMath.js");
00011
00012 if (typeof JSROOT.Math == "object")
00013 throw new Error("This JSROOT Math already loaded", "JSRootMath.js");
00014
00015 factory(JSROOT);
00016 }
00017 } (function(JSROOT) {
00018
00019
00020 JSROOT.Math = {};
00021
00022 JSROOT.Math.lgam = function( x ) {
00023 var p, q, u, w, z, i, sgngam = 1;
00024 var kMAXLGM = 2.556348e305;
00025 var LS2PI = 0.91893853320467274178;
00026
00027 var A = [
00028 8.11614167470508450300E-4,
00029 -5.95061904284301438324E-4,
00030 7.93650340457716943945E-4,
00031 -2.77777777730099687205E-3,
00032 8.33333333333331927722E-2
00033 ];
00034
00035 var B = [
00036 -1.37825152569120859100E3,
00037 -3.88016315134637840924E4,
00038 -3.31612992738871184744E5,
00039 -1.16237097492762307383E6,
00040 -1.72173700820839662146E6,
00041 -8.53555664245765465627E5
00042 ];
00043
00044 var C = [
00045
00046 -3.51815701436523470549E2,
00047 -1.70642106651881159223E4,
00048 -2.20528590553854454839E5,
00049 -1.13933444367982507207E6,
00050 -2.53252307177582951285E6,
00051 -2.01889141433532773231E6
00052 ];
00053
00054 if (x >= Number.POSITIVE_INFINITY)
00055 return(Number.POSITIVE_INFINITY);
00056
00057 if ( x < -34.0 ) {
00058 q = -x;
00059 w = this.lgam(q);
00060 p = Math.floor(q);
00061 if ( p==q )
00062 return (Number.POSITIVE_INFINITY);
00063 i = Math.round(p);
00064 if ( (i & 1) == 0 )
00065 sgngam = -1;
00066 else
00067 sgngam = 1;
00068 z = q - p;
00069 if ( z > 0.5 ) {
00070 p += 1.0;
00071 z = p - q;
00072 }
00073 z = q * Math.sin( Math.PI * z );
00074 if ( z < 1e-300 )
00075 return (Number.POSITIVE_INFINITY);
00076 z = Math.log(Math.PI) - Math.log( z ) - w;
00077 return( z );
00078 }
00079 if ( x < 13.0 ) {
00080 z = 1.0;
00081 p = 0.0;
00082 u = x;
00083 while ( u >= 3.0 ) {
00084 p -= 1.0;
00085 u = x + p;
00086 z *= u;
00087 }
00088 while ( u < 2.0 ) {
00089 if ( u < 1e-300 )
00090 return (Number.POSITIVE_INFINITY);
00091 z /= u;
00092 p += 1.0;
00093 u = x + p;
00094 }
00095 if ( z < 0.0 ) {
00096 sgngam = -1;
00097 z = -z;
00098 }
00099 else
00100 sgngam = 1;
00101 if ( u == 2.0 )
00102 return( Math.log(z) );
00103 p -= 2.0;
00104 x = x + p;
00105 p = x * this.Polynomialeval(x, B, 5 ) / this.Polynomial1eval( x, C, 6);
00106 return( Math.log(z) + p );
00107 }
00108 if ( x > kMAXLGM )
00109 return( sgngam * Number.POSITIVE_INFINITY );
00110
00111 q = ( x - 0.5 ) * Math.log(x) - x + LS2PI;
00112 if ( x > 1.0e8 )
00113 return( q );
00114
00115 p = 1.0/(x*x);
00116 if ( x >= 1000.0 )
00117 q += ((7.9365079365079365079365e-4 * p
00118 - 2.7777777777777777777778e-3) *p
00119 + 0.0833333333333333333333) / x;
00120 else
00121 q += this.Polynomialeval( p, A, 4 ) / x;
00122 return( q );
00123 };
00124
00125
00126
00127
00128
00129 JSROOT.Math.Polynomialeval = function(x, a, N) {
00130 if (N==0) return a[0];
00131 else {
00132 var pom = a[0];
00133 for (var i=1; i <= N; ++i)
00134 pom = pom *x + a[i];
00135 return pom;
00136 }
00137 };
00138
00139
00140
00141
00142
00143 JSROOT.Math.Polynomial1eval = function(x, a, N) {
00144 if (N==0) return a[0];
00145 else {
00146 var pom = x + a[0];
00147 for (var i=1; i < N; ++i)
00148 pom = pom *x + a[i];
00149 return pom;
00150 }
00151 };
00152
00153 JSROOT.Math.ndtri = function( y0 ) {
00154 if ( y0 <= 0.0 )
00155 return( Number.NEGATIVE_INFINITY );
00156 if ( y0 >= 1.0 )
00157 return( Number.POSITIVE_INFINITY );
00158
00159 var P0 = new Array(
00160 -5.99633501014107895267E1,
00161 9.80010754185999661536E1,
00162 -5.66762857469070293439E1,
00163 1.39312609387279679503E1,
00164 -1.23916583867381258016E0
00165 );
00166
00167 var Q0 = new Array(
00168 1.95448858338141759834E0,
00169 4.67627912898881538453E0,
00170 8.63602421390890590575E1,
00171 -2.25462687854119370527E2,
00172 2.00260212380060660359E2,
00173 -8.20372256168333339912E1,
00174 1.59056225126211695515E1,
00175 -1.18331621121330003142E0
00176 );
00177
00178 var P1 = new Array(
00179 4.05544892305962419923E0,
00180 3.15251094599893866154E1,
00181 5.71628192246421288162E1,
00182 4.40805073893200834700E1,
00183 1.46849561928858024014E1,
00184 2.18663306850790267539E0,
00185 -1.40256079171354495875E-1,
00186 -3.50424626827848203418E-2,
00187 -8.57456785154685413611E-4
00188 );
00189
00190 var Q1 = new Array(
00191 1.57799883256466749731E1,
00192 4.53907635128879210584E1,
00193 4.13172038254672030440E1,
00194 1.50425385692907503408E1,
00195 2.50464946208309415979E0,
00196 -1.42182922854787788574E-1,
00197 -3.80806407691578277194E-2,
00198 -9.33259480895457427372E-4
00199 );
00200
00201 var P2 = new Array(
00202 3.23774891776946035970E0,
00203 6.91522889068984211695E0,
00204 3.93881025292474443415E0,
00205 1.33303460815807542389E0,
00206 2.01485389549179081538E-1,
00207 1.23716634817820021358E-2,
00208 3.01581553508235416007E-4,
00209 2.65806974686737550832E-6,
00210 6.23974539184983293730E-9
00211 );
00212
00213 var Q2 = new Array(
00214 6.02427039364742014255E0,
00215 3.67983563856160859403E0,
00216 1.37702099489081330271E0,
00217 2.16236993594496635890E-1,
00218 1.34204006088543189037E-2,
00219 3.28014464682127739104E-4,
00220 2.89247864745380683936E-6,
00221 6.79019408009981274425E-9
00222 );
00223
00224 var s2pi = 2.50662827463100050242e0;
00225 var code = 1;
00226 var y = y0;
00227 var x, z, y2, x0, x1;
00228
00229 if ( y > (1.0 - 0.13533528323661269189) ) {
00230 y = 1.0 - y;
00231 code = 0;
00232 }
00233 if ( y > 0.13533528323661269189 ) {
00234 y = y - 0.5;
00235 y2 = y * y;
00236 x = y + y * (y2 * this.Polynomialeval( y2, P0, 4)/ this.Polynomial1eval( y2, Q0, 8 ));
00237 x = x * s2pi;
00238 return(x);
00239 }
00240 x = Math.sqrt( -2.0 * Math.log(y) );
00241 x0 = x - Math.log(x)/x;
00242 z = 1.0/x;
00243 if ( x < 8.0 )
00244 x1 = z * this.Polynomialeval( z, P1, 8 )/ this.Polynomial1eval( z, Q1, 8 );
00245 else
00246 x1 = z * this.Polynomialeval( z, P2, 8 )/ this.Polynomial1eval( z, Q2, 8 );
00247 x = x0 - x1;
00248 if ( code != 0 )
00249 x = -x;
00250 return( x );
00251 }
00252
00253 JSROOT.Math.igam = function(a,x) {
00254 var kMACHEP = 1.11022302462515654042363166809e-16;
00255 var kMAXLOG = 709.782712893383973096206318587;
00256 var ans, ax, c, r;
00257
00258
00259
00260 if (a <= 0) return 1.0;
00261
00262 if (x <= 0) return 0.0;
00263
00264 if( (x > 1.0) && (x > a ) )
00265 return( 1.0 - this.igamc(a,x) );
00266
00267
00268 ax = a * Math.log(x) - x - this.lgam(a);
00269 if( ax < -kMAXLOG )
00270 return( 0.0 );
00271
00272 ax = Math.exp(ax);
00273
00274
00275 r = a;
00276 c = 1.0;
00277 ans = 1.0;
00278
00279 do
00280 {
00281 r += 1.0;
00282 c *= x/r;
00283 ans += c;
00284 }
00285 while( c/ans > kMACHEP );
00286
00287 return( ans * ax/a );
00288 }
00289
00290 JSROOT.Math.igamc = function(a,x) {
00291 var kMACHEP = 1.11022302462515654042363166809e-16;
00292 var kMAXLOG = 709.782712893383973096206318587;
00293
00294 var kBig = 4.503599627370496e15;
00295 var kBiginv = 2.22044604925031308085e-16;
00296
00297 var ans, ax, c, yc, r, t, y, z;
00298 var pk, pkm1, pkm2, qk, qkm1, qkm2;
00299
00300
00301
00302 if (a <= 0) return 0.0;
00303
00304 if (x <= 0) return 1.0;
00305
00306 if( (x < 1.0) || (x < a) )
00307 return ( 1.0 - JSROOT.Math.igam(a,x) );
00308
00309 ax = a * Math.log(x) - x - JSROOT.Math.lgam(a);
00310 if( ax < -kMAXLOG )
00311 return( 0.0 );
00312
00313 ax = Math.exp(ax);
00314
00315
00316 y = 1.0 - a;
00317 z = x + y + 1.0;
00318 c = 0.0;
00319 pkm2 = 1.0;
00320 qkm2 = x;
00321 pkm1 = x + 1.0;
00322 qkm1 = z * x;
00323 ans = pkm1/qkm1;
00324
00325 do
00326 {
00327 c += 1.0;
00328 y += 1.0;
00329 z += 2.0;
00330 yc = y * c;
00331 pk = pkm1 * z - pkm2 * yc;
00332 qk = qkm1 * z - qkm2 * yc;
00333 if(qk)
00334 {
00335 r = pk/qk;
00336 t = Math.abs( (ans - r)/r );
00337 ans = r;
00338 }
00339 else
00340 t = 1.0;
00341 pkm2 = pkm1;
00342 pkm1 = pk;
00343 qkm2 = qkm1;
00344 qkm1 = qk;
00345 if( Math.abs(pk) > kBig )
00346 {
00347 pkm2 *= kBiginv;
00348 pkm1 *= kBiginv;
00349 qkm2 *= kBiginv;
00350 qkm1 *= kBiginv;
00351 }
00352 }
00353 while( t > kMACHEP );
00354
00355 return( ans * ax );
00356 }
00357
00358
00359 JSROOT.Math.igami = function(a, y0) {
00360 var x0, x1, x, yl, yh, y, d, lgm, dithresh;
00361 var i, dir;
00362 var kMACHEP = 1.11022302462515654042363166809e-16;
00363
00364
00365 if (a <= 0) {
00366 alert("igami : Wrong domain for parameter a (must be > 0)");
00367 return 0;
00368 }
00369 if (y0 <= 0) {
00370 return Number.POSITIVE_INFINITY;
00371 }
00372 if (y0 >= 1) {
00373 return 0;
00374 }
00375
00376 var kMAXNUM = Number.MAX_VALUE;
00377 x0 = kMAXNUM;
00378 yl = 0;
00379 x1 = 0;
00380 yh = 1.0;
00381 dithresh = 5.0 * kMACHEP;
00382
00383
00384 d = 1.0/(9.0*a);
00385 y = ( 1.0 - d - this.ndtri(y0) * Math.sqrt(d) );
00386 x = a * y * y * y;
00387
00388 lgm = this.lgam(a);
00389
00390 for( i=0; i<10; ++i ) {
00391 if ( x > x0 || x < x1 )
00392 break;
00393 y = this.igamc(a,x);
00394 if ( y < yl || y > yh )
00395 break;
00396 if ( y < y0 ) {
00397 x0 = x;
00398 yl = y;
00399 }
00400 else {
00401 x1 = x;
00402 yh = y;
00403 }
00404
00405 d = (a - 1.0) * Math.log(x) - x - lgm;
00406 if ( d < -kMAXLOG )
00407 break;
00408 d = -Math.exp(d);
00409
00410 d = (y - y0)/d;
00411 if ( Math.abs(d/x) < kMACHEP )
00412 return( x );
00413 x = x - d;
00414 }
00415
00416 d = 0.0625;
00417 if ( x0 == kMAXNUM ) {
00418 if ( x <= 0.0 )
00419 x = 1.0;
00420 while ( x0 == kMAXNUM ) {
00421 x = (1.0 + d) * x;
00422 y = this.igamc( a, x );
00423 if ( y < y0 ) {
00424 x0 = x;
00425 yl = y;
00426 break;
00427 }
00428 d = d + d;
00429 }
00430 }
00431 d = 0.5;
00432 dir = 0;
00433
00434 for( i=0; i<400; ++i ) {
00435 x = x1 + d * (x0 - x1);
00436 y = this.igamc( a, x );
00437 lgm = (x0 - x1)/(x1 + x0);
00438 if ( Math.abs(lgm) < dithresh )
00439 break;
00440 lgm = (y - y0)/y0;
00441 if ( Math.abs(lgm) < dithresh )
00442 break;
00443 if ( x <= 0.0 )
00444 break;
00445 if ( y >= y0 ) {
00446 x1 = x;
00447 yh = y;
00448 if ( dir < 0 ) {
00449 dir = 0;
00450 d = 0.5;
00451 }
00452 else if ( dir > 1 )
00453 d = 0.5 * d + 0.5;
00454 else
00455 d = (y0 - yl)/(yh - yl);
00456 dir += 1;
00457 }
00458 else {
00459 x0 = x;
00460 yl = y;
00461 if ( dir > 0 ) {
00462 dir = 0;
00463 d = 0.5;
00464 }
00465 else if ( dir < -1 )
00466 d = 0.5 * d;
00467 else
00468 d = (y0 - yl)/(yh - yl);
00469 dir -= 1;
00470 }
00471 }
00472 return( x );
00473 };
00474
00475 JSROOT.Math.gamma_quantile_c = function(z, alpha, theta) {
00476 return theta * this.igami( alpha, z);
00477 };
00478
00479 JSROOT.Math.gamma_quantile = function(z, alpha, theta) {
00480 return theta * this.igami( alpha, 1.- z);
00481 };
00482
00483 JSROOT.Math.log10 = function(n) {
00484 return Math.log(n) / Math.log(10);
00485 };
00486
00487 JSROOT.Math.landau_pdf = function(x, xi, x0) {
00488
00489
00490 if (xi <= 0) return 0;
00491 var v = (x - x0)/xi;
00492 var u, ue, us, denlan;
00493 var p1 = new Array(0.4259894875,-0.1249762550, 0.03984243700, -0.006298287635, 0.001511162253);
00494 var q1 = new Array(1.0 ,-0.3388260629, 0.09594393323, -0.01608042283, 0.003778942063);
00495 var p2 = new Array(0.1788541609, 0.1173957403, 0.01488850518, -0.001394989411, 0.0001283617211);
00496 var q2 = new Array(1.0 , 0.7428795082, 0.3153932961, 0.06694219548, 0.008790609714);
00497 var p3 = new Array(0.1788544503, 0.09359161662,0.006325387654, 0.00006611667319,-0.000002031049101);
00498 var q3 = new Array(1.0 , 0.6097809921, 0.2560616665, 0.04746722384, 0.006957301675);
00499 var p4 = new Array(0.9874054407, 118.6723273, 849.2794360, -743.7792444, 427.0262186);
00500 var q4 = new Array(1.0 , 106.8615961, 337.6496214, 2016.712389, 1597.063511);
00501 var p5 = new Array(1.003675074, 167.5702434, 4789.711289, 21217.86767, -22324.94910);
00502 var q5 = new Array(1.0 , 156.9424537, 3745.310488, 9834.698876, 66924.28357);
00503 var p6 = new Array(1.000827619, 664.9143136, 62972.92665, 475554.6998, -5743609.109);
00504 var q6 = new Array(1.0 , 651.4101098, 56974.73333, 165917.4725, -2815759.939);
00505 var a1 = new Array(0.04166666667,-0.01996527778, 0.02709538966);
00506 var a2 = new Array(-1.845568670,-4.284640743);
00507
00508 if (v < -5.5) {
00509 u = Math.exp(v+1.0);
00510 if (u < 1e-10) return 0.0;
00511 ue = Math.exp(-1/u);
00512 us = Math.sqrt(u);
00513 denlan = 0.3989422803*(ue/us)*(1+(a1[0]+(a1[1]+a1[2]*u)*u)*u);
00514 } else if(v < -1) {
00515 u = Math.exp(-v-1);
00516 denlan = Math.exp(-u)*Math.sqrt(u)*
00517 (p1[0]+(p1[1]+(p1[2]+(p1[3]+p1[4]*v)*v)*v)*v)/
00518 (q1[0]+(q1[1]+(q1[2]+(q1[3]+q1[4]*v)*v)*v)*v);
00519 } else if(v < 1) {
00520 denlan = (p2[0]+(p2[1]+(p2[2]+(p2[3]+p2[4]*v)*v)*v)*v)/
00521 (q2[0]+(q2[1]+(q2[2]+(q2[3]+q2[4]*v)*v)*v)*v);
00522 } else if(v < 5) {
00523 denlan = (p3[0]+(p3[1]+(p3[2]+(p3[3]+p3[4]*v)*v)*v)*v)/
00524 (q3[0]+(q3[1]+(q3[2]+(q3[3]+q3[4]*v)*v)*v)*v);
00525 } else if(v < 12) {
00526 u = 1/v;
00527 denlan = u*u*(p4[0]+(p4[1]+(p4[2]+(p4[3]+p4[4]*u)*u)*u)*u)/
00528 (q4[0]+(q4[1]+(q4[2]+(q4[3]+q4[4]*u)*u)*u)*u);
00529 } else if(v < 50) {
00530 u = 1/v;
00531 denlan = u*u*(p5[0]+(p5[1]+(p5[2]+(p5[3]+p5[4]*u)*u)*u)*u)/
00532 (q5[0]+(q5[1]+(q5[2]+(q5[3]+q5[4]*u)*u)*u)*u);
00533 } else if(v < 300) {
00534 u = 1/v;
00535 denlan = u*u*(p6[0]+(p6[1]+(p6[2]+(p6[3]+p6[4]*u)*u)*u)*u)/
00536 (q6[0]+(q6[1]+(q6[2]+(q6[3]+q6[4]*u)*u)*u)*u);
00537 } else {
00538 u = 1/(v-v*Math.log(v)/(v+1));
00539 denlan = u*u*(1+(a2[0]+a2[1]*u)*u);
00540 }
00541 return denlan/xi;
00542 };
00543
00544 JSROOT.Math.Landau = function(x, mpv, sigma, norm) {
00545 if (sigma <= 0) return 0;
00546 var den = JSROOT.Math.landau_pdf((x - mpv) / sigma, 1, 0);
00547 if (!norm) return den;
00548 return den/sigma;
00549 }
00550
00551 JSROOT.Math.inc_gamma_c = function(a,x) {
00552 return JSROOT.Math.igamc(a,x);
00553 }
00554
00555 JSROOT.Math.chisquared_cdf_c = function(x,r,x0) {
00556 return JSROOT.Math.inc_gamma_c ( 0.5 * r , 0.5* (x-x0) );
00557 }
00558
00559 JSROOT.Math.Prob = function(chi2, ndf) {
00560 if (ndf <= 0) return 0;
00561
00562 if (chi2 <= 0) {
00563 if (chi2 < 0) return 0;
00564 else return 1;
00565 }
00566
00567 return JSROOT.Math.chisquared_cdf_c(chi2,ndf,0);
00568 }
00569
00570 JSROOT.Math.gaus = function(f, x, i) {
00571 return f['fParams'][i+0] * Math.exp(-0.5 * Math.pow((x-f['fParams'][i+1]) / f['fParams'][i+2], 2));
00572 };
00573
00574 JSROOT.Math.gausn = function(f, x, i) {
00575 return JSROOT.Math.gaus(f, x, i)/(Math.sqrt(2 * Math.PI) * f['fParams'][i+2]);
00576 };
00577
00578 JSROOT.Math.expo = function(f, x, i) {
00579 return Math.exp(f['fParams'][i+0] + f['fParams'][i+1] * x);
00580 };
00581
00582 JSROOT.Math.landau = function(f, x, i) {
00583 return JSROOT.Math.Landau(x, f['fParams'][i+1],f['fParams'][i+2], false);
00584 }
00585
00586 JSROOT.Math.landaun = function(f, x, i) {
00587 return JSROOT.Math.Landau(x, f['fParams'][i+1],f['fParams'][i+2], true);
00588 }
00589
00590 return JSROOT;
00591
00592 }));