#include "includes.h" #include "grid.h" #include "vector.h" #include extern ofstream errorfs; #include "declare.h" /*file contains source code for functions called in HMM assuming haplotype data*/ void makenullshare(dgrid &obsprobs, const igrid &data, const igrid &freqallele, const dgrid &freqfreq, const dgrid &condfreq2l, const dgrid &condfreq2r, const dgrid &condfreq2C, const ivector &allelecounts, const int &LE, const int &RE, const int &C) { //this function generates parts of observation probabilities for HMM //that do not involve parameters, i.e., conditional allele frequencies int i,j; const int numhap=data.dimx(); for (i=0;iRE //make column LE if (data(i,LE)==0) obsprobs(2*i+1,LE)=1; else obsprobs(2*i+1,LE)= getfreq(freqallele, freqfreq, data(i,LE), LE); //make columns LE+1: RE for (j=LE+1;j<=RE;j++) { if (data(i,j)==0) obsprobs(2*i+1,j)=1; else { if (data(i,j-1)==0) obsprobs(2*i+1,j)= getfreq(freqallele, freqfreq, data(i,j), j); else obsprobs(2*i+1,j)=getcondfreq2l(freqallele, allelecounts, condfreq2l, j-1, data(i,j-1), data(i,j)); } } //make column C if (data(i,C)==0) obsprobs(2*i+1,C)=1; else { if (data(i,RE)==0) obsprobs(2*i+1,C) = getfreq(freqallele, freqfreq, data(i,C), C); else obsprobs(2*i+1,C)= getjointfreq2C(freqallele, condfreq2C, data(i,RE), RE, data(i,C), C); } } } } for (i=0;iRE) assert(-0.000011 && mut(j)>0) { temp=pow(1-mut(j),tau); mutmatch(j)=temp + (1-temp)/(allelecounts(j)); mutnomatch(j)=(1-mutmatch(j))/(allelecounts(j)-1); } else { mutmatch(j)=1; mutnomatch(j)=0; } } else { mutmatch(j)=1; mutnomatch(j)=0; } } } void makemodlshare(dgrid &obsprobs, const igrid &data, const dvector &mutmatch, dvector &mutnomatch, const ivector &anchap, const int &C, const int &LE, const int &RE) { //completes observation probabilities generated in makenullshare; //includes components that depend on tau through m(l,tau,i,j) int i,j; const int numhap=data.dimx(); for (i=0;iA transstore(1,i)=0;//A->N transstore(3,i)= (1 - (1-p) * exp( -tau * x[i+1]) )/ (1 - (1-p) * exp( -tau * x[i]) );//N->N transstore(2,i)=1-transstore(3,i);//N->A } for (i=C;iA transstore(1,i)=0;//A->N transstore(3,i)= (1 - (1-p) * exp( -tau * x[i+1]) )/ (1 - (1-p) * exp( -tau * x[i]) );//N->N transstore(2,i)=1-transstore(3,i); } //N->A transstore(0,RE)=1;//A->A transstore(1,RE)=0;//A->N transstore(3,RE)= p/(1 - (1-p) * exp( -tau * x[RE]) );//N->N transstore(2,RE)=1-transstore(3,RE); //N->A } } } void maketransC(dgrid &transstoreC, const dvector &x, const double &tau, const double &p, const int &C, const int &LE, const int &RE) { //computes transition probabilities for jumps away from C if (LEA transstoreC(1,1)=1- transstoreC(0,1);//A->N transstoreC(2,1)=0;//N->A transstoreC(3,1)=1;//N->N } else { transstoreC(0,1)=transstoreC(1,1)= transstoreC(2,1)=transstoreC(3,1)= 0; } } void makealpha(dgrid &alpha, const dgrid &initstore, const dgrid &transstore, const dgrid &transstoreC, const dgrid &obsprobs, const dgrid &obsprobsCnum, const dgrid &obsprobsCden, const int &C, const int &LE, const int &RE) { //assembles alpha object int i,j,k,h,t; const int numhap=alpha.dimx()/2; int LHSle, LHSre, RHSle, RHSre; double sum,sum1; //these are endpoints for t, rather than t+1 if (LE=RHSle;t--) { for (i=0;i<2;i++) { sum=0; for (j=0;j<2;j++) { sum+= beta(2*h+j,t+1)*transstore(2*i+j,t)*obsprobs(2*h+j,t+1); } beta(2*h+i,t)=sum; } } if (LE=LHSle;t--) { for (i=0;i<2;i++) { sum=0; for (j=0;j<2;j++) { sum+= beta(2*h+j,t+1)*transstore(2*i+j,t)*obsprobs(2*h+j,t+1); } beta(2*h+i,t)=sum; } } if (C0); if ( (high-low)/high < 0.00001 || (high-low) < 0.00001) break; tau=(high+low)/2; part1=loglikder(tau,y,x,cstar,C,LE,RE); if (m>0) part2=mutloglikder(tau,mut, cstar, cstarmut,allelecounts, C, LE, RE); else part2=0; likder = part1+part2; if (likder > 0) low = tau; else high = tau; } return tau; }//bisecmle double loglikder(double &tau, const dvector &y, const dvector &x, const dvector &cstar, const int &C, const int &LE, const int &RE) { //computes the derivative w.r.t. tau of the complete data loglik for cstar; //used in bisection method int i; double value=0; if (CRE) { value += -cstar[RE] * x[RE] + (cstar[C] - cstar[RE]) * x[RE]/ (exp(tau * x[RE])-1); for (i = RE-1; i>= LE; i--) //derlik for i<0 { value += -cstar[i] * y[i] + (cstar[i+1] - cstar[i]) * y[i]/ (exp(tau * y[i])-1); } } else { for (i = C-1; i>= LE; i--) //derlik for i<0 { value += -cstar[i] * y[i] + (cstar[i+1] - cstar[i]) * y[i]/ (exp(tau * y[i])-1); } for (i = C+1; i<= RE; i++) //derlik for i>0 { value += -cstar[i] * y[i-1] + (cstar[i-1] - cstar[i]) * y[i-1]/ (exp(tau * y[i-1])-1); } } } return value; }//loglikder double mutloglikder(const double &tau, const dvector &mut,//mrescaled const dvector &cstar, const dvector &cstarmut, const ivector &allelecounts, const int &C, const int &LE, const int &RE) { //computes the derivative w.r.t. tau of the complete data loglik for //mutation process in cstarmut; code generated by maple //used in bisection method //note: mut(t) = m*( n(t) + 1 )/n(t) //note: assumes no mutation at C int t; double value=0; double t1=0,t2=0,t3=0,t7=0,t10=0,t13=0,t20=0; if (tau<0.1) return 0; else { for (t = LE; t<=RE; t++) { if (t!=C && mut(t)!=0) { t1 = 1.0-mut(t); t2 = log(t1); t3 = pow(t1,1.0*tau); t7 = t3*allelecounts(t); t10 = allelecounts(t)*cstar[t]; t13 = pow(t1,2.0*tau); t20 = t2/(-1.0+t3)/(t7+1.0-t3)* (-t10*t3+t10*t13+cstar[t]*t3-cstar[t]*t13+t7*cstarmut[t]); value += t20; } } if (! (value<0 || value>=0) ) { cerr << "ERROR in mutloglikder in bisecmle; mutation contribution" << " to derivative of loglik is NaN" << endl; exit(1); } return value; } }//mutloglikder double makep(const dvector &cstar, const int &numhap, const int &C) { //gets new estimate of heterogeneity parameter p from cstar and numb. of //haps double p=0; p=1-cstar[C]/numhap; return p; } void makeloglik(dvector &loglikvec, const dgrid &alpha, const dgrid &initstore, const int &C, const int &RE) { //computes vector of loglikelihoods from alpha and 1 unconditional distr.; //each entry corresponds to one haplotype int i,h,locus; double lik; const int numhap=alpha.dimx()/2; if (C