void xcount (int * m, int * k, double * count, int * safeSecs) { countLimit = *count; if (*count < 1) countLimit = 1e100; // Set limit to a huge number unless user asked for a limit tableCount = 0; // If there are only 2 alleles, that's a special case. if (*k==2) { *count = twoAlleleSpecialCase(m); return; } // Set up global variables used during recursion nAlleles = *k; Rbytes = *k * sizeof(COUNTTYPE); Rarray = Calloc(*k * *k * (*k-1)/2, COUNTTYPE); for (int i = 0; i < nAlleles; i++) { Rarray[i] = m[i]; } hashCoefs = Calloc(nAlleles, unsigned long long); hashCoefs[0] = m[0] + 1; for (int i = 1; i < nAlleles; i++) { hashCoefs[i] = hashCoefs[i-1] * (m[i] + 1); } nextNode = 0; timeLimit = *safeSecs; start = time(NULL); // ***************** This is the call to do all the work! homozygote(nAlleles, Rarray); // *count = tableCount; Free(hashCoefs); Free(Rarray); }
void xtest (int * rm, int * rk, double * robservedVals, // observed stats: LLR, Prob, U, X2 double * rPvals, // computed P values: LLR, Prob, U, X2 int * rstatID, // which statistic to use for histogram (1-4) int * rhistobins, // number of bins for histogram. (no histogram if 0) double * rhistobounds, // Two values indicating the range for histogram double * rhistoData, // histogram data. length = histobounds. int * rsafeSecs, // abort calculation after this many seconds double * tables // the number of tables examined ) { // Set up global variables used during recursion nAlleles = *rk; pU = pLLR = pPr = pX2 =probSum = 0; hProb = rhistoData; Rbytes = *rk * sizeof(COUNTTYPE); statID = *rstatID; timeLimit = *rsafeSecs; HN = *rhistobins; start = time(NULL); Rarray = Calloc(*rk * *rk * (*rk-1)/2, COUNTTYPE); for (int i = 0; i < nAlleles; i++) Rarray[i] = rm[i]; mi = rm-1; // 1-based list of allele counts tableCount = 0; umean = 0; uvariance = 0; // Make lookup tables xlnx = Calloc(rm[0] + 1, double); lnFact = Calloc(rm[0] + 1, double); uTerm1 = Calloc(rm[0]/2 + 1, double); uTerm2 = Calloc(rm[1]/2 + 1, double); int biggesta11 = rm[0]/2; int biggesta22 = rm[1]/2; int biggesta21 = rm[1]; x211 = Calloc((biggesta11+1), double); x222 = Calloc((biggesta22 + 1), double); x221 = Calloc((biggesta21+1), double); xlnx[0] = 0; lnFact[0] = 0; double lni; for (int i = 1; i <= rm[0]; i++) { lni = log(i); xlnx[i] = lni * i; lnFact[i] = lnFact[i-1] + lni; } for(int i = 0; i <= rm[0]/2; i++) uTerm1[i] = (double)i/rm[0]; for(int i = 0; i <= rm[1]/2; i++) uTerm2[i] = (double)i/rm[1]; size_t nsq = fmax(2, nAlleles * nAlleles); exa = Calloc(nsq, double); // Expected numbers. Array uses extra space but saves time int nGenes = 0; for(int i = 0; i < nAlleles; i++) nGenes += rm[i]; ntotal = nGenes/2; for(int i = 0; i < nAlleles; i++) { exa[i * nAlleles + i] = (double)(rm[i] * rm[i])/(2.0 * nGenes); for (int j = 0; j < i; j++) { exa[i * nAlleles + j] = (double)(rm[i] * rm[j])/nGenes; } } for(int i = 0; i <= biggesta11; i++) x211[i] = R_pow_di(exa[0] - i, 2)/exa[0]; for(int i = 0; i <= biggesta21; i++) x221[i] = R_pow_di(exa[nAlleles] - i, 2)/exa[nAlleles]; for(int i = 0; i <= biggesta22; i++) x222[i] = R_pow_di(exa[nAlleles + 1] - i, 2)/exa[nAlleles + 1]; // Get constant terms for LLR and Prob constProbTerm = constLLRterm = 0; for (int i = 0; i < nAlleles; i++) { constProbTerm += lgammafn(rm[i] + 1); //lnFact[rm[i]]; constLLRterm += xlnx[rm[i]]; } constProbTerm += log(2)*ntotal + lgammafn(ntotal+1) - lgammafn(nGenes +1); constLLRterm += -log(2)*ntotal - log(ntotal) * ntotal; // Get cutoffs for the four test statistics double oneMinus = 0.9999999; // Guards against floating-point-equality-test errors if(robservedVals[0] > 0.000000000001) robservedVals[0] = 0; // positive values are rounding errors maxLLR = robservedVals[0] * oneMinus; maxlPr = log(robservedVals[1]) * oneMinus; minmaxU = robservedVals[2] * oneMinus; minX2 = robservedVals[3] * oneMinus; // Set up histogram if (HN) { switch (*rstatID) { case 0: // LLR -- histobounds gives bounds for -2LLR leftStat = rhistobounds[0]/(-2.0); statSpan = -2.0 * HN/(rhistobounds[1] - rhistobounds[0]); break; case 1: // Prob -- histobounds gives bounds for -2ln(pr) leftStat = rhistobounds[0]/(-2.0); statSpan = -2.0 * HN/(rhistobounds[1] - rhistobounds[0]); break; case 2: // U score -- histobounds is actual bounds leftStat = rhistobounds[0]; statSpan = (double)HN/(rhistobounds[1] - rhistobounds[0]); break; case 3: // X2 -- histobounds is actual bounds leftStat = rhistobounds[0]; statSpan = (double)HN/(rhistobounds[1] - rhistobounds[0]); break; default: break; } hProb = rhistoData; for(int i = 0; i < HN; i++) hProb[i] = 0; } start = time(NULL); if (nAlleles == 2) { twoAlleleSpecialCase(); } else { homozygote(nAlleles, 0, 0, 0, 0, Rarray); } *tables = tableCount; rPvals[0] = pLLR; rPvals[1] = pPr; rPvals[2] = pU; rPvals[3] = pX2; if (tableCount < 0) for(int i = 0; i < 4; i++) rPvals[i] = -1; // Process timed out and p values are meaningless // printf("\nU mean = %.8f", umean); // printf("\nU variance = %.8f\n", uvariance - umean * umean); Free(xlnx);Free(lnFact);Free(Rarray); Free(exa); Free(uTerm1); Free(uTerm2); Free(x211); Free(x221); Free(x222); }