double gamma_cdf (double beta, double gamm, double pzero, double x) { if (x <= 0.0) return (pzero); else return (pzero + (1.0 - pzero) * gammap (gamm, x / beta)); }
/** [chi_pp p v] * Finds the percentage point [p] of the chi squared distribution of [v] degrees * of freedom. The gamma is related to this distribution by the define below. * * Algorithm AS91: The Percentage Points of the chi^2 Distribution * (translated to C, and removed goto's ~nrl) */ double chi_pp( double p, double v ){ double ch,s1,s2,s3,s4,s5,s6; double e,aa,xx,c,g,x,p1,a,q,p2,t,ig,b; assert( v > 0.0 ); if (p < 0.000002 || p > 0.999998) failwith("Chi^2 Percentage Points incorrect.1"); e = 0.5e-6; /** error term **/ aa= 0.6931471805; xx = 0.5 * v; c = xx - 1.0; g = lngamma( xx ); if( v < -1.24 * log(p) ){ ch = pow(p * xx * exp ( g + xx * aa), 1.0/xx); if( ch - e < 0 ) return ch; } else if( v > 0.32) { x = point_normal( p ); p1 = 0.222222 / v; ch = v * pow( x * sqrt( p1 ) + 1 - p1, 3.0) ; if (ch > 2.2 * v + 6) ch = -2.0 * (log(1-p) - c*log(0.5*ch)+g); } else { ch = 0.4; a = log (1 - p); do{ q = ch; p1 = 1 + ch * (4.67 + ch); p2 = ch * (6.73 + ch * (6.66 + ch)); t = -0.5 + (4.67 + 2*ch)/p1 - (6.73 + ch*(13.32 + 3*ch))/p2; ch = ch - (1- exp( a + g + 0.5*ch+c*aa) * p2/p1)/t; } while( fabs( q/ch - 1) - 0.01 > 0.0 ); } do{ q = ch; p1 = .5*ch; ig = gammap( p1, xx ); if (ig < 0){ failwith("Chi^2 Percentage Points incorrect.2"); } p2 = p - ig; t = p2 * exp( xx*aa + g + p1 - c*log(ch)); b = t / ch; a = (0.5*t) - (b*c); /* Seven terms of the Taylor series */ s1 = (210 + a*(140 + a*(105 + a*(84 + a*(70 + 60*a))))) / 420.0; s2 = (420 + a*(735 + a*(966 + a*(1141 + 1278*a)))) / 2520.0; s3 = (210 + a*(462 + a*(707 + 932*a))) / 2520.0; s4 = (252 + a*(672 + 1182*a) + c*(294 + a*(889 + 1740*a))) / 5040.0; s5 = ( 84 + 264*a + c*(175 + 606*a)) / 2520.0; s6 = (120 + c*(346 + 127*c)) / 5040.0; ch+= t*(1+0.5*t*s1-b*c*(s1-b*(s2-b*(s3-b*(s4-b*(s5-b*s6)))))); } while( fabs(q / ch - 1.0) > e); return (ch); }
/** [gamma_rates rates alpha beta cuts k] * calculates the rates into [rates] with percentage points [cuts] of [k] * categories and shape parameters [alpha] and [beta] */ void gamma_rates(double* rates,const double a,const double b,const double* cuts,const int k) { double fac, *ingam; int j; fac = a*((double)k)/b; ingam = (double*) malloc( k * sizeof(double)); CHECK_MEM(ingam); //calculate: rj = (A*k/B)*(I(bB,A+1)-I(aB,A+1)) for(j=0;j<(k-1);j++){ ingam[j] = gammap( cuts[j]*b, a+1 ); //printf("LG: %f\tNL: %f\n", ingam[j], gamma_i( cuts[j]*b, a+1 ) ); } rates[0] = ingam[0] * fac; //lower rate rates[k-1] = (1 - ingam[k-2]) * fac; //upper rate for(j=1;j<k-1;j++) rates[j] = (ingam[j] - ingam[j-1]) * fac; free( ingam ); }
void Foam::varyingGammaTotalTemperatureFvPatchScalarField::updateCoeffs() { if (updated()) { return; } const fluidThermo& thermo = this->patch().boundaryMesh().mesh().thisDb().lookupObject<fluidThermo>("thermophysicalProperties"); const fvPatchVectorField& Up = patch().lookupPatchField<volVectorField, vector>(UName_); const fvsPatchField<scalar>& phip = patch().lookupPatchField<surfaceScalarField, scalar>(phiName_); const fvPatchField<scalar>& psip = thermo.psi().boundaryField()[patch().index()]; const fvPatchField<scalar>& pp = thermo.p().boundaryField()[patch().index()]; const fvPatchField<scalar>& Tp = thermo.T().boundaryField()[patch().index()]; scalarField gammap ( thermo.gamma(pp, Tp, patch().index()) ); scalarField gM1ByG ((gammap - 1.0)/gammap); operator== ( T0_/(1.0 + 0.5*psip*gM1ByG*(1.0 - pos(phip))*magSqr(Up)) ); fixedValueFvPatchScalarField::updateCoeffs(); }
/* gammacdf: cumulative distribution function for the gamma distribution. * @x: the x-value for evaluation. * @a: the first parameter. * @b: the second parameter. */ double gammacdf (double x, double a, double b) { /* return the value. */ return gammap (a, x / b); }
double cumchi(double df,double x) { return gammap(df/2,x/2); }