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 #include "Math/VavilovFast.h"
00035 #include "Math/PdfFuncMathCore.h"
00036 #include "Math/ProbFuncMathCore.h"
00037 #include "Math/SpecFuncMathCore.h"
00038 #include "Math/SpecFuncMathMore.h"
00039
00040 #include <cassert>
00041 #include <iostream>
00042 #include <cmath>
00043 #include <limits>
00044
00045
00046 namespace ROOT {
00047 namespace Math {
00048
00049 VavilovFast *VavilovFast::fgInstance = 0;
00050
00051
00052 VavilovFast::VavilovFast(double kappa, double beta2)
00053 {
00054 SetKappaBeta2 (kappa, beta2);
00055 }
00056
00057
00058 VavilovFast::~VavilovFast()
00059 {
00060
00061 }
00062
00063 void VavilovFast::SetKappaBeta2 (double kappa, double beta2)
00064 {
00065
00066 fKappa = kappa;
00067 fBeta2 = beta2;
00068
00069 double BKMNX1 = 0.02, BKMNY1 = 0.05, BKMNX2 = 0.12, BKMNY2 = 0.05,
00070 BKMNX3 = 0.22, BKMNY3 = 0.05, BKMXX1 = 0.1 , BKMXY1 = 1,
00071 BKMXX2 = 0.2 , BKMXY2 = 1 , BKMXX3 = 0.3 , BKMXY3 = 1;
00072
00073 double FBKX1 = 2/(BKMXX1-BKMNX1), FBKX2 = 2/(BKMXX2-BKMNX2),
00074 FBKX3 = 2/(BKMXX3-BKMNX3), FBKY1 = 2/(BKMXY1-BKMNY1),
00075 FBKY2 = 2/(BKMXY2-BKMNY2), FBKY3 = 2/(BKMXY3-BKMNY3);
00076
00077 double FNINV[] = {0, 1, 0.5, 0.33333333, 0.25, 0.2};
00078
00079 double EDGEC[]= {0, 0, 0.16666667e+0, 0.41666667e-1, 0.83333333e-2,
00080 0.13888889e-1, 0.69444444e-2, 0.77160493e-3};
00081
00082 double U1[] = {0, 0.25850868e+0, 0.32477982e-1, -0.59020496e-2,
00083 0. , 0.24880692e-1, 0.47404356e-2,
00084 -0.74445130e-3, 0.73225731e-2, 0. ,
00085 0.11668284e-2, 0. , -0.15727318e-2,-0.11210142e-2};
00086
00087 double U2[] = {0, 0.43142611e+0, 0.40797543e-1, -0.91490215e-2,
00088 0. , 0.42127077e-1, 0.73167928e-2,
00089 -0.14026047e-2, 0.16195241e-1, 0.24714789e-2,
00090 0.20751278e-2, 0. , -0.25141668e-2,-0.14064022e-2};
00091
00092 double U3[] = {0, 0.25225955e+0, 0.64820468e-1, -0.23615759e-1,
00093 0. , 0.23834176e-1, 0.21624675e-2,
00094 -0.26865597e-2, -0.54891384e-2, 0.39800522e-2,
00095 0.48447456e-2, -0.89439554e-2, -0.62756944e-2,-0.24655436e-2};
00096
00097 double U4[] = {0, 0.12593231e+1, -0.20374501e+0, 0.95055662e-1,
00098 -0.20771531e-1, -0.46865180e-1, -0.77222986e-2,
00099 0.32241039e-2, 0.89882920e-2, -0.67167236e-2,
00100 -0.13049241e-1, 0.18786468e-1, 0.14484097e-1};
00101
00102 double U5[] = {0, -0.24864376e-1, -0.10368495e-2, 0.14330117e-2,
00103 0.20052730e-3, 0.18751903e-2, 0.12668869e-2,
00104 0.48736023e-3, 0.34850854e-2, 0. ,
00105 -0.36597173e-3, 0.19372124e-2, 0.70761825e-3, 0.46898375e-3};
00106
00107 double U6[] = {0, 0.35855696e-1, -0.27542114e-1, 0.12631023e-1,
00108 -0.30188807e-2, -0.84479939e-3, 0. ,
00109 0.45675843e-3, -0.69836141e-2, 0.39876546e-2,
00110 -0.36055679e-2, 0. , 0.15298434e-2, 0.19247256e-2};
00111
00112 double U7[] = {0, 0.10234691e+2, -0.35619655e+1, 0.69387764e+0,
00113 -0.14047599e+0, -0.19952390e+1, -0.45679694e+0,
00114 0. , 0.50505298e+0};
00115 double U8[] = {0, 0.21487518e+2, -0.11825253e+2, 0.43133087e+1,
00116 -0.14500543e+1, -0.34343169e+1, -0.11063164e+1,
00117 -0.21000819e+0, 0.17891643e+1, -0.89601916e+0,
00118 0.39120793e+0, 0.73410606e+0, 0. ,-0.32454506e+0};
00119
00120 double V1[] = {0, 0.27827257e+0, -0.14227603e-2, 0.24848327e-2,
00121 0. , 0.45091424e-1, 0.80559636e-2,
00122 -0.38974523e-2, 0. , -0.30634124e-2,
00123 0.75633702e-3, 0.54730726e-2, 0.19792507e-2};
00124
00125 double V2[] = {0, 0.41421789e+0, -0.30061649e-1, 0.52249697e-2,
00126 0. , 0.12693873e+0, 0.22999801e-1,
00127 -0.86792801e-2, 0.31875584e-1, -0.61757928e-2,
00128 0. , 0.19716857e-1, 0.32596742e-2};
00129
00130 double V3[] = {0, 0.20191056e+0, -0.46831422e-1, 0.96777473e-2,
00131 -0.17995317e-2, 0.53921588e-1, 0.35068740e-2,
00132 -0.12621494e-1, -0.54996531e-2, -0.90029985e-2,
00133 0.34958743e-2, 0.18513506e-1, 0.68332334e-2,-0.12940502e-2};
00134
00135 double V4[] = {0, 0.13206081e+1, 0.10036618e+0, -0.22015201e-1,
00136 0.61667091e-2, -0.14986093e+0, -0.12720568e-1,
00137 0.24972042e-1, -0.97751962e-2, 0.26087455e-1,
00138 -0.11399062e-1, -0.48282515e-1, -0.98552378e-2};
00139
00140 double V5[] = {0, 0.16435243e-1, 0.36051400e-1, 0.23036520e-2,
00141 -0.61666343e-3, -0.10775802e-1, 0.51476061e-2,
00142 0.56856517e-2, -0.13438433e-1, 0. ,
00143 0. , -0.25421507e-2, 0.20169108e-2,-0.15144931e-2};
00144
00145 double V6[] = {0, 0.33432405e-1, 0.60583916e-2, -0.23381379e-2,
00146 0.83846081e-3, -0.13346861e-1, -0.17402116e-2,
00147 0.21052496e-2, 0.15528195e-2, 0.21900670e-2,
00148 -0.13202847e-2, -0.45124157e-2, -0.15629454e-2, 0.22499176e-3};
00149
00150 double V7[] = {0, 0.54529572e+1, -0.90906096e+0, 0.86122438e-1,
00151 0. , -0.12218009e+1, -0.32324120e+0,
00152 -0.27373591e-1, 0.12173464e+0, 0. ,
00153 0. , 0.40917471e-1};
00154
00155 double V8[] = {0, 0.93841352e+1, -0.16276904e+1, 0.16571423e+0,
00156 0. , -0.18160479e+1, -0.50919193e+0,
00157 -0.51384654e-1, 0.21413992e+0, 0. ,
00158 0. , 0.66596366e-1};
00159
00160 double W1[] = {0, 0.29712951e+0, 0.97572934e-2, 0. ,
00161 -0.15291686e-2, 0.35707399e-1, 0.96221631e-2,
00162 -0.18402821e-2, -0.49821585e-2, 0.18831112e-2,
00163 0.43541673e-2, 0.20301312e-2, -0.18723311e-2,-0.73403108e-3};
00164
00165 double W2[] = {0, 0.40882635e+0, 0.14474912e-1, 0.25023704e-2,
00166 -0.37707379e-2, 0.18719727e+0, 0.56954987e-1,
00167 0. , 0.23020158e-1, 0.50574313e-2,
00168 0.94550140e-2, 0.19300232e-1};
00169
00170 double W3[] = {0, 0.16861629e+0, 0. , 0.36317285e-2,
00171 -0.43657818e-2, 0.30144338e-1, 0.13891826e-1,
00172 -0.58030495e-2, -0.38717547e-2, 0.85359607e-2,
00173 0.14507659e-1, 0.82387775e-2, -0.10116105e-1,-0.55135670e-2};
00174
00175 double W4[] = {0, 0.13493891e+1, -0.26863185e-2, -0.35216040e-2,
00176 0.24434909e-1, -0.83447911e-1, -0.48061360e-1,
00177 0.76473951e-2, 0.24494430e-1, -0.16209200e-1,
00178 -0.37768479e-1, -0.47890063e-1, 0.17778596e-1, 0.13179324e-1};
00179
00180 double W5[] = {0, 0.10264945e+0, 0.32738857e-1, 0. ,
00181 0.43608779e-2, -0.43097757e-1, -0.22647176e-2,
00182 0.94531290e-2, -0.12442571e-1, -0.32283517e-2,
00183 -0.75640352e-2, -0.88293329e-2, 0.52537299e-2, 0.13340546e-2};
00184
00185 double W6[] = {0, 0.29568177e-1, -0.16300060e-2, -0.21119745e-3,
00186 0.23599053e-2, -0.48515387e-2, -0.40797531e-2,
00187 0.40403265e-3, 0.18200105e-2, -0.14346306e-2,
00188 -0.39165276e-2, -0.37432073e-2, 0.19950380e-2, 0.12222675e-2};
00189
00190 double W8[] = {0, 0.66184645e+1, -0.73866379e+0, 0.44693973e-1,
00191 0. , -0.14540925e+1, -0.39529833e+0,
00192 -0.44293243e-1, 0.88741049e-1};
00193
00194 fItype = 0;
00195 if (fKappa <0.01 || fKappa >12) {
00196 std::cerr << "VavilovFast::set: illegal value of kappa=" << kappa << std::endl;
00197 if (fKappa < 0.01) fKappa = 0.01;
00198 else if (fKappa > 12) fKappa = 12;
00199 }
00200
00201 double DRK[6];
00202 double DSIGM[6];
00203 double ALFA[8];
00204 int j;
00205 double x, y, xx, yy, x2, x3, y2, y3, xy, p2, p3, q2, q3, pq;
00206 if (fKappa >= 0.29) {
00207 fItype = 1;
00208 fNpt = 100;
00209 double wk = 1./std::sqrt(fKappa);
00210
00211 fAC[0] = (-0.032227*fBeta2-0.074275)*fKappa + (0.24533*fBeta2+0.070152)*wk + (-0.55610*fBeta2-3.1579);
00212 fAC[8] = (-0.013483*fBeta2-0.048801)*fKappa + (-1.6921*fBeta2+8.3656)*wk + (-0.73275*fBeta2-3.5226);
00213 DRK[1] = wk*wk;
00214 DSIGM[1] = std::sqrt(fKappa/(1-0.5*fBeta2));
00215 for (j=1; j<=4; j++) {
00216 DRK[j+1] = DRK[1]*DRK[j];
00217 DSIGM[j+1] = DSIGM[1]*DSIGM[j];
00218 ALFA[j+1] = (FNINV[j]-fBeta2*FNINV[j+1])*DRK[j];
00219 }
00220 fHC[0]=std::log(fKappa)+fBeta2+0.42278434;
00221 fHC[1]=DSIGM[1];
00222 fHC[2]=ALFA[3]*DSIGM[3];
00223 fHC[3]=(3*ALFA[2]*ALFA[2] + ALFA[4])*DSIGM[4]-3;
00224 fHC[4]=(10*ALFA[2]*ALFA[3]+ALFA[5])*DSIGM[5]-10*fHC[2];
00225 fHC[5]=fHC[2]*fHC[2];
00226 fHC[6]=fHC[2]*fHC[3];
00227 fHC[7]=fHC[2]*fHC[5];
00228 for (j=2; j<=7; j++)
00229 fHC[j]*=EDGEC[j];
00230 fHC[8]=0.39894228*fHC[1];
00231 }
00232 else if (fKappa >=0.22) {
00233 fItype = 2;
00234 fNpt = 150;
00235 x = 1+(fKappa-BKMXX3)*FBKX3;
00236 y = 1+(std::sqrt(fBeta2)-BKMXY3)*FBKY3;
00237 xx = 2*x;
00238 yy = 2*y;
00239 x2 = xx*x-1;
00240 x3 = xx*x2-x;
00241 y2 = yy*y-1;
00242 y3 = yy*y2-y;
00243 xy = x*y;
00244 p2 = x2*y;
00245 p3 = x3*y;
00246 q2 = y2*x;
00247 q3 = y3*x;
00248 pq = x2*y2;
00249 fAC[1] = W1[1] + W1[2]*x + W1[4]*x3 + W1[5]*y + W1[6]*y2 + W1[7]*y3 +
00250 W1[8]*xy + W1[9]*p2 + W1[10]*p3 + W1[11]*q2 + W1[12]*q3 + W1[13]*pq;
00251 fAC[2] = W2[1] + W2[2]*x + W2[3]*x2 + W2[4]*x3 + W2[5]*y + W2[6]*y2 +
00252 W2[8]*xy + W2[9]*p2 + W2[10]*p3 + W2[11]*q2;
00253 fAC[3] = W3[1] + W3[3]*x2 + W3[4]*x3 + W3[5]*y + W3[6]*y2 + W3[7]*y3 +
00254 W3[8]*xy + W3[9]*p2 + W3[10]*p3 + W3[11]*q2 + W3[12]*q3 + W3[13]*pq;
00255 fAC[4] = W4[1] + W4[2]*x + W4[3]*x2 + W4[4]*x3 + W4[5]*y + W4[6]*y2 + W4[7]*y3 +
00256 W4[8]*xy + W4[9]*p2 + W4[10]*p3 + W4[11]*q2 + W4[12]*q3 + W4[13]*pq;
00257 fAC[5] = W5[1] + W5[2]*x + W5[4]*x3 + W5[5]*y + W5[6]*y2 + W5[7]*y3 +
00258 W5[8]*xy + W5[9]*p2 + W5[10]*p3 + W5[11]*q2 + W5[12]*q3 + W5[13]*pq;
00259 fAC[6] = W6[1] + W6[2]*x + W6[3]*x2 + W6[4]*x3 + W6[5]*y + W6[6]*y2 + W6[7]*y3 +
00260 W6[8]*xy + W6[9]*p2 + W6[10]*p3 + W6[11]*q2 + W6[12]*q3 + W6[13]*pq;
00261 fAC[8] = W8[1] + W8[2]*x + W8[3]*x2 + W8[5]*y + W8[6]*y2 + W8[7]*y3 + W8[8]*xy;
00262 fAC[0] = -3.05;
00263 } else if (fKappa >= 0.12) {
00264 fItype = 3;
00265 fNpt = 200;
00266 x = 1 + (fKappa-BKMXX2)*FBKX2;
00267 y = 1 + (std::sqrt(fBeta2)-BKMXY2)*FBKY2;
00268 xx = 2*x;
00269 yy = 2*y;
00270 x2 = xx*x-1;
00271 x3 = xx*x2-x;
00272 y2 = yy*y-1;
00273 y3 = yy*y2-y;
00274 xy = x*y;
00275 p2 = x2*y;
00276 p3 = x3*y;
00277 q2 = y2*x;
00278 q3 = y3*x;
00279 pq = x2*y2;
00280 fAC[1] = V1[1] + V1[2]*x + V1[3]*x2 + V1[5]*y + V1[6]*y2 + V1[7]*y3 +
00281 V1[9]*p2 + V1[10]*p3 + V1[11]*q2 + V1[12]*q3;
00282 fAC[2] = V2[1] + V2[2]*x + V2[3]*x2 + V2[5]*y + V2[6]*y2 + V2[7]*y3 +
00283 V2[8]*xy + V2[9]*p2 + V2[11]*q2 + V2[12]*q3;
00284 fAC[3] = V3[1] + V3[2]*x + V3[3]*x2 + V3[4]*x3 + V3[5]*y + V3[6]*y2 + V3[7]*y3 +
00285 V3[8]*xy + V3[9]*p2 + V3[10]*p3 + V3[11]*q2 + V3[12]*q3 + V3[13]*pq;
00286 fAC[4] = V4[1] + V4[2]*x + V4[3]*x2 + V4[4]*x3 + V4[5]*y + V4[6]*y2 + V4[7]*y3 +
00287 V4[8]*xy + V4[9]*p2 + V4[10]*p3 + V4[11]*q2 + V4[12]*q3;
00288 fAC[5] = V5[1] + V5[2]*x + V5[3]*x2 + V5[4]*x3 + V5[5]*y + V5[6]*y2 + V5[7]*y3 +
00289 V5[8]*xy + V5[11]*q2 + V5[12]*q3 + V5[13]*pq;
00290 fAC[6] = V6[1] + V6[2]*x + V6[3]*x2 + V6[4]*x3 + V6[5]*y + V6[6]*y2 + V6[7]*y3 +
00291 V6[8]*xy + V6[9]*p2 + V6[10]*p3 + V6[11]*q2 + V6[12]*q3 + V6[13]*pq;
00292 fAC[7] = V7[1] + V7[2]*x + V7[3]*x2 + V7[5]*y + V7[6]*y2 + V7[7]*y3 +
00293 V7[8]*xy + V7[11]*q2;
00294 fAC[8] = V8[1] + V8[2]*x + V8[3]*x2 + V8[5]*y + V8[6]*y2 + V8[7]*y3 +
00295 V8[8]*xy + V8[11]*q2;
00296 fAC[0] = -3.04;
00297 } else {
00298 fItype = 4;
00299 if (fKappa >=0.02) fItype = 3;
00300 fNpt = 200;
00301 x = 1+(fKappa-BKMXX1)*FBKX1;
00302 y = 1+(std::sqrt(fBeta2)-BKMXY1)*FBKY1;
00303 xx = 2*x;
00304 yy = 2*y;
00305 x2 = xx*x-1;
00306 x3 = xx*x2-x;
00307 y2 = yy*y-1;
00308 y3 = yy*y2-y;
00309 xy = x*y;
00310 p2 = x2*y;
00311 p3 = x3*y;
00312 q2 = y2*x;
00313 q3 = y3*x;
00314 pq = x2*y2;
00315 if (fItype==3){
00316 fAC[1] = U1[1] + U1[2]*x + U1[3]*x2 + U1[5]*y + U1[6]*y2 + U1[7]*y3 +
00317 U1[8]*xy + U1[10]*p3 + U1[12]*q3 + U1[13]*pq;
00318 fAC[2] = U2[1] + U2[2]*x + U2[3]*x2 + U2[5]*y + U2[6]*y2 + U2[7]*y3 +
00319 U2[8]*xy + U2[9]*p2 + U2[10]*p3 + U2[12]*q3 + U2[13]*pq;
00320 fAC[3] = U3[1] + U3[2]*x + U3[3]*x2 + U3[5]*y + U3[6]*y2 + U3[7]*y3 +
00321 U3[8]*xy + U3[9]*p2 + U3[10]*p3 + U3[11]*q2 + U3[12]*q3 + U3[13]*pq;
00322 fAC[4] = U4[1] + U4[2]*x + U4[3]*x2 + U4[4]*x3 + U4[5]*y + U4[6]*y2 + U4[7]*y3 +
00323 U4[8]*xy + U4[9]*p2 + U4[10]*p3 + U4[11]*q2 + U4[12]*q3;
00324 fAC[5] = U5[1] + U5[2]*x + U5[3]*x2 + U5[4]*x3 + U5[5]*y + U5[6]*y2 + U5[7]*y3 +
00325 U5[8]*xy + U5[10]*p3 + U5[11]*q2 + U5[12]*q3 + U5[13]*pq;
00326 fAC[6] = U6[1] + U6[2]*x + U6[3]*x2 + U6[4]*x3 + U6[5]*y + U6[7]*y3 +
00327 U6[8]*xy + U6[9]*p2 + U6[10]*p3 + U6[12]*q3 + U6[13]*pq;
00328 fAC[7] = U7[1] + U7[2]*x + U7[3]*x2 + U7[4]*x3 + U7[5]*y + U7[6]*y2 + U7[8]*xy;
00329 }
00330 fAC[8] = U8[1] + U8[2]*x + U8[3]*x2 + U8[4]*x3 + U8[5]*y + U8[6]*y2 + U8[7]*y3 +
00331 U8[8]*xy + U8[9]*p2 + U8[10]*p3 + U8[11]*q2 + U8[13]*pq;
00332 fAC[0] = -3.03;
00333 }
00334
00335 fAC[9] = (fAC[8] - fAC[0])/fNpt;
00336 fAC[10] = 1./fAC[9];
00337 if (fItype == 3) {
00338 x = (fAC[7]-fAC[8])/(fAC[7]*fAC[8]);
00339 y = 1./std::log (fAC[8]/fAC[7]);
00340 p2 = fAC[7]*fAC[7];
00341 fAC[11] = p2*(fAC[1]*std::exp(-fAC[2]*(fAC[7]+fAC[5]*p2)-
00342 fAC[3]*std::exp(-fAC[4]*(fAC[7]+fAC[6]*p2)))-0.045*y/fAC[7])/(1+x*y*fAC[7]);
00343 fAC[12] = (0.045+x*fAC[11])*y;
00344 }
00345 if (fItype == 4) fAC[13] = 0.995/ROOT::Math::landau_cdf(fAC[8]);
00346
00347
00348 x = fAC[0];
00349 fWCM[0] = 0;
00350 double fl, fu;
00351 int k;
00352 fl = Pdf (x);
00353 for (k=1; k<=fNpt; k++) {
00354 x += fAC[9];
00355 fu = Pdf (x);
00356 fWCM[k] = fWCM[k-1] + fl + fu;
00357 fl = fu;
00358 }
00359 x = 0.5*fAC[9];
00360 for (k=1; k<=fNpt; k++)
00361 fWCM[k]*=x;
00362 }
00363
00364 double VavilovFast::Pdf (double x) const
00365 {
00366
00367
00368
00369 double v = 0;
00370 if (x < fAC[0] || x > fAC[8])
00371 return 0;
00372 int k;
00373 double h[10];
00374 if (fItype ==1 ) {
00375 double fn = 1;
00376 double xx = (x + fHC[0])*fHC[1];
00377 h[1] = xx;
00378 h[2] = xx*xx -1;
00379 for (k=2; k<=8; k++) {
00380 fn++;
00381 h[k+1] = xx*h[k]-fn*h[k-1];
00382 }
00383 double s = 1 + fHC[7]*h[9];
00384 for (k=2; k<=6; k++)
00385 s += fHC[k]*h[k+1];
00386 if (s>0) v = fHC[8]*std::exp(-0.5*xx*xx);
00387 }
00388 else if (fItype == 2) {
00389 double xx = x*x;
00390 v = fAC[1]*std::exp(-fAC[2]*(x+fAC[5]*xx) - fAC[3]*std::exp(-fAC[4]*(x+fAC[6]*xx)));
00391 }
00392 else if (fItype == 3) {
00393 if (x < fAC[7]) {
00394 double xx = x*x;
00395 v = fAC[1]*std::exp(-fAC[2]*(x+fAC[5]*xx)-fAC[3]*std::exp(-fAC[4]*(x+fAC[6]*xx)));
00396 } else {
00397 double xx = 1./x;
00398 v = (fAC[11]*xx + fAC[12])*xx;
00399 }
00400 }
00401 else if (fItype == 4) {
00402 v = fAC[13]*ROOT::Math::landau_pdf(x);
00403 }
00404 return v;
00405 }
00406
00407
00408 double VavilovFast::Pdf (double x, double kappa, double beta2) {
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422 if (kappa != fKappa || beta2 != fBeta2) SetKappaBeta2 (kappa, beta2);
00423 return Pdf (x);
00424 }
00425
00426 double VavilovFast::Cdf (double x) const {
00427
00428 double xx, v;
00429 if (x < fAC[0]) v = 0;
00430 else if (x >= fAC[8]) v = 1;
00431 else {
00432 xx = x - fAC[0];
00433 int k = int (xx*fAC[10]);
00434 v = fWCM[k] + (xx - k*fAC[9])*(fWCM[k+1]-fWCM[k])*fAC[10];
00435 if (v > 1) v = 1;
00436 }
00437 return v;
00438 }
00439
00440 double VavilovFast::Cdf_c (double x) const {
00441 return 1-Cdf(x);
00442 }
00443
00444 double VavilovFast::Cdf (double x, double kappa, double beta2) {
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 if (kappa != fKappa || beta2 != fBeta2) SetKappaBeta2 (kappa, beta2);
00459 return Cdf (x);
00460 }
00461
00462 double VavilovFast::Cdf_c (double x, double kappa, double beta2) {
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476 if (kappa != fKappa || beta2 != fBeta2) SetKappaBeta2 (kappa, beta2);
00477 return Cdf_c (x);
00478 }
00479
00480 double VavilovFast::Quantile (double z) const {
00481 if (z < 0 || z > 1) return std::numeric_limits<double>::signaling_NaN();
00482
00483
00484
00485 double t = 2*z/fAC[9];
00486 double rlam = fAC[0];
00487 double fl = 0;
00488 double fu = 0;
00489 double s = 0;
00490 double h[10];
00491 for (int n = 1; n <= fNpt; ++n) {
00492 rlam += fAC[9];
00493 if (fItype == 1) {
00494 double fn = 1;
00495 double x = (rlam+fHC[0])*fHC[1];
00496 h[1] = x;
00497 h[2] = x*x-1;
00498 for (int k = 2; k <= 8; ++k) {
00499 ++fn;
00500 h[k+1] = x*h[k]-fn*h[k-1];
00501 }
00502 double y = 1+fHC[7]*h[9];
00503 for (int k = 2; k <= 6; ++k) {
00504 y += fHC[k]*h[k+1];
00505 }
00506 if (y > 0) fu = fHC[8]*std::exp(-0.5*x*x);
00507 }
00508 else if (fItype == 2) {
00509 double x = rlam*rlam;
00510 fu = fAC[1]*std::exp(-fAC[2]*(rlam+fAC[5]*x)-
00511 fAC[3]*std::exp(-fAC[4]*(rlam+fAC[6]*x)));
00512 }
00513 else if (fItype == 3) {
00514 if (rlam < fAC[7]) {
00515 double x = rlam*rlam;
00516 fu = fAC[1]*std::exp(-fAC[2]*(rlam+fAC[5]*x)-
00517 fAC[3]*std::exp(-fAC[4]*(rlam+fAC[6]*x)));
00518 } else {
00519 double x = 1/rlam;
00520 fu = (fAC[11]*x+fAC[12])*x;
00521 }
00522 }
00523 else {
00524 fu = fAC[13]*Pdf(rlam);
00525 }
00526 s += fl+fu;
00527 if (s > t) break;
00528 fl = fu;
00529 }
00530 double s0 = s-fl-fu;
00531 double v = rlam-fAC[9];
00532 if (s > s0) v += fAC[9]*(t-s0)/(s-s0);
00533 return v;
00534 }
00535
00536 double VavilovFast::Quantile (double z, double kappa, double beta2) {
00537 if (kappa != fKappa || beta2 != fBeta2) SetKappaBeta2 (kappa, beta2);
00538 return Quantile (z);
00539 }
00540
00541 double VavilovFast::Quantile_c (double z) const {
00542 if (z < 0 || z > 1) return std::numeric_limits<double>::signaling_NaN();
00543 return Quantile (1-z);
00544 }
00545
00546 double VavilovFast::Quantile_c (double z, double kappa, double beta2) {
00547 if (kappa != fKappa || beta2 != fBeta2) SetKappaBeta2 (kappa, beta2);
00548 return Quantile_c (z);
00549 }
00550
00551 double VavilovFast::GetLambdaMin() const {
00552 return fAC[0];
00553 }
00554
00555 double VavilovFast::GetLambdaMax() const {
00556 return fAC[8];
00557 }
00558
00559 double VavilovFast::GetKappa() const {
00560 return fKappa;
00561 }
00562
00563 double VavilovFast::GetBeta2() const {
00564 return fBeta2;
00565 }
00566
00567 VavilovFast *VavilovFast::GetInstance() {
00568 if (!fgInstance) fgInstance = new VavilovFast (1, 1);
00569 return fgInstance;
00570 }
00571
00572 VavilovFast *VavilovFast::GetInstance(double kappa, double beta2) {
00573 if (!fgInstance) fgInstance = new VavilovFast (kappa, beta2);
00574 else if (kappa != fgInstance->fKappa || beta2 != fgInstance->fBeta2) fgInstance->SetKappaBeta2 (kappa, beta2);
00575 return fgInstance;
00576 }
00577
00578 double vavilov_fast_pdf (double x, double kappa, double beta2) {
00579 VavilovFast *vavilov = VavilovFast::GetInstance (kappa, beta2);
00580 return vavilov->Pdf (x);
00581 }
00582
00583 double vavilov_fast_cdf (double x, double kappa, double beta2) {
00584 VavilovFast *vavilov = VavilovFast::GetInstance (kappa, beta2);
00585 return vavilov->Cdf (x);
00586 }
00587
00588 double vavilov_fast_cdf_c (double x, double kappa, double beta2) {
00589 VavilovFast *vavilov = VavilovFast::GetInstance (kappa, beta2);
00590 return vavilov->Cdf_c (x);
00591 }
00592
00593 double vavilov_fast_quantile (double z, double kappa, double beta2) {
00594 VavilovFast *vavilov = VavilovFast::GetInstance (kappa, beta2);
00595 return vavilov->Quantile (z);
00596 }
00597
00598 double vavilov_fast_quantile_c (double z, double kappa, double beta2) {
00599 VavilovFast *vavilov = VavilovFast::GetInstance (kappa, beta2);
00600 return vavilov->Quantile_c (z);
00601 }
00602
00603
00604 }
00605 }