double Cephes::cephes_igam(double a, double x) { double ans, ax, c, r; if ( (x <= 0) || ( a <= 0) ) return 0.0; if ( (x > 1.0) && (x > a ) ) return 1.e0 - cephes_igamc(a,x); /* Compute x**a * exp(-x) / gamma(a) */ ax = a * log(x) - x - cephes_lgam(a); if ( ax < -MAXLOG ) { printf("igam: UNDERFLOW\n"); return 0.0; } ax = exp(ax); /* power series */ r = a; c = 1.0; ans = 1.0; do { r += 1.0; c *= x/r; ans += c; } while ( c/ans > MACHEP ); return ans * ax/a; }
double cephes_igamc(double a, double x) { double ans, ax, c, yc, r, t, y, z; double pk, pkm1, pkm2, qk, qkm1, qkm2; if ( (x <= 0) || ( a <= 0) ) return( 1.0 ); if ( (x < 1.0) || (x < a) ) return( 1.e0 - cephes_igam(a,x) ); ax = a * log(x) - x - cephes_lgam(a); if ( ax < -MAXLOG ) { printf("igamc: UNDERFLOW\n"); return 0.0; } ax = exp(ax); /* continued fraction */ y = 1.0 - a; z = x + y + 1.0; c = 0.0; pkm2 = 1.0; qkm2 = x; pkm1 = x + 1.0; qkm1 = z * x; ans = pkm1/qkm1; do { c += 1.0; y += 1.0; z += 2.0; yc = y * c; pk = pkm1 * z - pkm2 * yc; qk = qkm1 * z - qkm2 * yc; if ( qk != 0 ) { r = pk/qk; t = fabs( (ans - r)/r ); ans = r; } else t = 1.0; pkm2 = pkm1; pkm1 = pk; qkm2 = qkm1; qkm1 = qk; if ( fabs(pk) > big ) { pkm2 *= biginv; pkm1 *= biginv; qkm2 *= biginv; qkm1 *= biginv; } } while ( t > MACHEP ); return ans*ax; }
/* Logarithm of gamma function */ double Cephes::cephes_lgam(double x) { double p, q, u, w, z; int i; sgngam = 1; if ( x < -34.0 ) { q = -x; w = cephes_lgam(q); /* note this modifies sgngam! */ p = floor(q); if ( p == q ) { lgsing: goto loverf; } i = (int)p; if ( (i & 1) == 0 ) sgngam = -1; else sgngam = 1; z = q - p; if ( z > 0.5 ) { p += 1.0; z = p - q; } z = q * sin( PI * z ); if ( z == 0.0 ) goto lgsing; /* z = log(PI) - log( z ) - w;*/ z = log(PI) - log( z ) - w; return z; } if ( x < 13.0 ) { z = 1.0; p = 0.0; u = x; while ( u >= 3.0 ) { p -= 1.0; u = x + p; z *= u; } while ( u < 2.0 ) { if ( u == 0.0 ) goto lgsing; z /= u; p += 1.0; u = x + p; } if ( z < 0.0 ) { sgngam = -1; z = -z; } else sgngam = 1; if ( u == 2.0 ) return( log(z) ); p -= 2.0; x = x + p; p = x * cephes_polevl( x, (double *)B, 5 ) / cephes_p1evl( x, (double *)C, 6); return log(z) + p; } if ( x > MAXLGM ) { loverf: printf("lgam: OVERFLOW\n"); return sgngam * MAXNUM; } q = ( x - 0.5 ) * log(x) - x + log( sqrt( 2*PI ) ); if ( x > 1.0e8 ) return q; p = 1.0/(x*x); if ( x >= 1000.0 ) q += (( 7.9365079365079365079365e-4 * p - 2.7777777777777777777778e-3) *p + 0.0833333333333333333333) / x; else q += cephes_polevl( p, (double *)A, 4 ) / x; return q; }
void NonOverlappingTemplateMatchings(int m, int n) { int numOfTemplates[100] = {0, 0, 2, 4, 6, 12, 20, 40, 74, 148, 284, 568, 1116, 2232, 4424, 8848, 17622, 35244, 70340, 140680, 281076, 562152}; /*---------------------------------------------------------------------------- NOTE: Should additional templates lengths beyond 21 be desired, they must first be constructed, saved into files and then the corresponding number of nonperiodic templates for that file be stored in the m-th position in the numOfTemplates variable. ----------------------------------------------------------------------------*/ unsigned int bit, W_obs, nu[6], *Wj = NULL; FILE *fp; double sum, chi2, p_value, lambda, pi[6], varWj; int i, j, jj, k, match, SKIP, M, N, K = 5; char directory[100]; BitSequence *sequence = NULL; N = 8; M = n/N; if ( (Wj = (unsigned int*)calloc(N, sizeof(unsigned int))) == NULL ) { fprintf(stats[TEST_NONPERIODIC], "\tNONOVERLAPPING TEMPLATES TESTS ABORTED DUE TO ONE OF THE FOLLOWING : \n"); fprintf(stats[TEST_NONPERIODIC], "\tInsufficient memory for required work space.\n"); return; } lambda = (M-m+1)/pow(2, m); varWj = M*(1.0/pow(2.0, m) - (2.0*m-1.0)/pow(2.0, 2.0*m)); sprintf(directory, "templates/template%d", m); if ( ((isNegative(lambda)) || (isZero(lambda))) || ((fp = fopen(directory, "r")) == NULL) || ((sequence = (BitSequence *) calloc(m, sizeof(BitSequence))) == NULL) ) { fprintf(stats[TEST_NONPERIODIC], "\tNONOVERLAPPING TEMPLATES TESTS ABORTED DUE TO ONE OF THE FOLLOWING : \n"); fprintf(stats[TEST_NONPERIODIC], "\tLambda (%f) not being positive!\n", lambda); fprintf(stats[TEST_NONPERIODIC], "\tTemplate file <%s> not existing\n", directory); fprintf(stats[TEST_NONPERIODIC], "\tInsufficient memory for required work space.\n"); if ( sequence != NULL ) free(sequence); } else { fprintf(stats[TEST_NONPERIODIC], "\t\t NONPERIODIC TEMPLATES TEST\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\t\t COMPUTATIONAL INFORMATION\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\tLAMBDA = %f\tM = %d\tN = %d\tm = %d\tn = %d\n", lambda, M, N, m, n); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); fprintf(stats[TEST_NONPERIODIC], "\t\tF R E Q U E N C Y\n"); fprintf(stats[TEST_NONPERIODIC], "Template W_1 W_2 W_3 W_4 W_5 W_6 W_7 W_8 Chi^2 P_value Assignment Index\n"); fprintf(stats[TEST_NONPERIODIC], "-------------------------------------------------------------------------------------\n"); if ( numOfTemplates[m] < MAXNUMOFTEMPLATES ) SKIP = 1; else SKIP = (int)(numOfTemplates[m]/MAXNUMOFTEMPLATES); numOfTemplates[m] = (int)numOfTemplates[m]/SKIP; sum = 0.0; for ( i=0; i<2; i++ ) { /* Compute Probabilities */ pi[i] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1)); sum += pi[i]; } pi[0] = sum; for ( i=2; i<=K; i++ ) { /* Compute Probabilities */ pi[i-1] = exp(-lambda+i*log(lambda)-cephes_lgam(i+1)); sum += pi[i-1]; } pi[K] = 1 - sum; for( jj=0; jj<MIN(MAXNUMOFTEMPLATES, numOfTemplates[m]); jj++ ) { sum = 0; for ( k=0; k<m; k++ ) { fscanf(fp, "%d", &bit); sequence[k] = bit; fprintf(stats[TEST_NONPERIODIC], "%d", sequence[k]); } fprintf(stats[TEST_NONPERIODIC], " "); for ( k=0; k<=K; k++ ) nu[k] = 0; for ( i=0; i<N; i++ ) { W_obs = 0; for ( j=0; j<M-m+1; j++ ) { match = 1; for ( k=0; k<m; k++ ) { if ( (int)sequence[k] != (int)epsilon[i*M+j+k] ) { match = 0; break; } } if ( match == 1 ) W_obs++; } Wj[i] = W_obs; } sum = 0; chi2 = 0.0; /* Compute Chi Square */ for ( i=0; i<N; i++ ) { if ( m == 10 ) fprintf(stats[TEST_NONPERIODIC], "%3d ", Wj[i]); else fprintf(stats[TEST_NONPERIODIC], "%4d ", Wj[i]); chi2 += pow(((double)Wj[i] - lambda)/pow(varWj, 0.5), 2); } p_value = cephes_igamc(N/2.0, chi2/2.0); if ( isNegative(p_value) || isGreaterThanOne(p_value) ) fprintf(stats[TEST_NONPERIODIC], "\t\tWARNING: P_VALUE IS OUT OF RANGE.\n"); fprintf(stats[TEST_NONPERIODIC], "%9.6f %f %s %3d\n", chi2, p_value, p_value < ALPHA ? "FAILURE" : "SUCCESS", jj); if ( SKIP > 1 ) fseek(fp, (long)(SKIP-1)*2*m, SEEK_CUR); fprintf(results[TEST_NONPERIODIC], "%f\n", p_value); } } fprintf(stats[TEST_NONPERIODIC], "\n"); if ( sequence != NULL ) free(sequence); free(Wj); fclose(fp); }