#include "MaximumLikelihoodEstimation.h" /*-------------------------------------------------------------------------------------------*/ //Function declarations: void ReadDates(int noDates, char *DatesFile, int *dates); int ReadParam(char *ParamFile, param *GP); double neglogLikelihood(int noDates, int *dates, int *pfail, workparam Pi); double PDF(double x, double kappa, double eta); double gammaPDF(double x, double alpha, double beta); double weibullPDF(double x, double kappa, double eta); double MLE(char *InputFile , int noDates, int *dates, int ndim, int DoFit, param *GP); void ConstructLHTable(int num, int paramnum, double **SamplePoints); void FindMin(int i, int ndim, int noDates, int *dates, param *GP, workparam P[], double L[], workparam Pres[], double Lres[], int itres[]); int amoeba(int noDates, int *dates, workparam P[], double L[], double ftol, int ndim, double (*funk)(int, int *, int*, workparam), int *nfunk); double amotry(int noDates, int *dates, workparam P[], double L[], workparam psum, int ndim, double (*funk)(int, int *, int *, workparam), int worst, double fac); void OutputRes(char *OutputFile, int ndim, int DoFit, workparam Pres[], double Lres[], int itres[]); int CalcCIs(char *InputFile, int noDates, int *dates, int ndim, param *GP, double optL); /*-------------------------------------------------------------------------------------------*/ //Global variables: double **matrix; int DIST_SWITCH; //0 for gamma distribution, 1 for weibull distribution, //2 for negative binomial distribution. //currently, only 1=weibull works. long seed, rcount; /*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { int noDates; char InputFile[255], ParamFile[255]; int *dates; param *GP; int DoFit, ndim; double neg2lnL; int i, fail; if(argc<7) ERR_CRITICAL("Syntax:\n \n"); sscanf(argv[1],"%d", &DIST_SWITCH); sscanf(argv[2],"%d", &noDates); sscanf(argv[3],"%s", InputFile); sscanf(argv[4],"%s", ParamFile); sscanf(argv[5],"%d", &DoFit); sscanf(argv[6],"%d", &seed); if(seed>0) seed=-seed; if(seed==0) { seed=(long)time(NULL); if(seed>0) seed=-seed; } if(noDates<=0) ERR_CRITICAL("positive number of dates necessary.\n"); if(!(dates=(int *) calloc(noDates+1, sizeof(int)))) ERR_CRITICAL("Unable to allocate memory for list of dates.\n"); if(!(GP=(param *) malloc(sizeof(param)))) ERR_CRITICAL("Unable to allcoate memory for parameters GP.\n"); if(!(matrix=dmatrix(0, noDates, 0, noDates))) ERR_CRITICAL("main: Unable to allocate memory for matrix.\n"); ReadDates(noDates, InputFile, dates); ndim=ReadParam(ParamFile, GP); neg2lnL=MLE(InputFile , noDates, dates, ndim, DoFit, GP); fail=CalcCIs(InputFile, noDates, dates, ndim, GP, neg2lnL); for(i=0;i=0;i++){ eofind=fscanf(indat, "%d", &dates[i]); } if(eofind<0) ERR_CRITICAL("ReadDates: input file does not contain enough dates.\n"); fclose(indat); printf("Successfully read list of dates.\n"); } /*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/ int ReadParam(char *ParamFile, param *GP){ FILE *indat; char filename[255]; int j; int scan=0; sprintf(filename, "%s.txt", ParamFile); if(!(indat=fopen(filename, "r"))) ERR_CRITICAL("ReadParam: Unable to open file for input.\n"); for(j=0;jindex.array[j].Value, &GP->index.array[j].Min, &GP->index.array[j].Max, &GP->index.array[j].Scale, &GP->index.array[j].Scan); if(GP->index.array[j].Scan==1 || GP->index.array[j].Scan==2) scan++; } fclose(indat); printf("Successfully read Params.\n"); return scan; } /*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/ double neglogLikelihood(int noDates, int *dates, int *pfail, workparam Pi) { int i,j,jmin; int timediffij; double lnL, Lsum; *pfail=0; //Calculate probability matrix: for(i=0;i0 /*&& timediffij<=30*/ && i!=j){ //i can infect j if i was earlier, //but less than 30 days before, //and i cannot infect itself. matrix[i][j] = PDF(timediffij, Pi.index.named.kappa, Pi.index.named.eta); } else { matrix[i][j]=0; } } jmin=1; while(dates[jmin]==dates[jmin-1]) jmin++; lnL=0.0; for(j=jmin;jn) ERR_CRITICAL("noverk: k>n.\n"); if(k==0 || k==n) return 1; if(k>n/2.0) k=n-k; prod=n; for(i=n-1;i>n-k;i--) prod*=i; for(i=2;i<=k;i++) prod/=i; return prod; } /*-------------------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------------------*/ double MLE(char *InputFile , int noDates, int *dates, int ndim, int DoFit, param *GP) { workparam *P, *Pres; double bestL, *L, *Lres; int *itres; double **SamplePoints; int loop; int i,j,k,l; if(!(P=(workparam *) calloc(ndim+2, sizeof(workparam)))) ERR_CRITICAL("MLE: Unable to allocate memory for workparam P.\n"); if(!(L=(double *) calloc(ndim+2, sizeof(double)))) ERR_CRITICAL("MLE: Unable to allocate memory for L.\n"); if(!(Pres=(workparam *) calloc(DoFit+2, sizeof(workparam)))) ERR_CRITICAL("MLE: Unable to allocate memory for workparam Pres.\n"); if(!(Lres=(double *) calloc(DoFit+2, sizeof(double)))) ERR_CRITICAL("MLE: Unable to allocate memory for Lres.\n"); if(!(itres=(int *) calloc(DoFit+2, sizeof(int)))) ERR_CRITICAL("MLE: Unable to allocate memory for itres.\n"); if(DoFit>0) { if(!(SamplePoints=dmatrix(0,DoFit+1,0,ndim+1))) ERR_CRITICAL("MLE: Unable to allocate memory for SamplePoints.\n"); ConstructLHTable(DoFit, ndim, SamplePoints); loop=DoFit; for(i=0;i0)&&(jindex.array[j].Scan==1) { P[0].index.array[k] = GP->index.array[j].Min + SamplePoints[i][k] * (GP->index.array[j].Max-GP->index.array[j].Min); for(l=1;lindex.array[j].Scale; k++; } else if(GP->index.array[j].Scan==2) { if(GP->index.array[j].Max<0.0) { P[0].index.array[k] = -exp(log(-GP->index.array[j].Min) + (log(-GP->index.array[j].Max)-log(GP->index.array[i].Min)) *SamplePoints[i][k]); for(l=1;lindex.array[j].Scale; } else { P[0].index.array[k] = exp(log(GP->index.array[j].Min) + (log(GP->index.array[j].Max)-log(GP->index.array[j].Min)) *SamplePoints[i][k]); for(l=1;lindex.array[j].Scale; } k++; } } FindMin(i, ndim, noDates, dates, GP, P, L, Pres, Lres, itres); } OutputRes(InputFile, ndim, DoFit, Pres, Lres, itres); //write the MLestimates into GP: for(k=0, j=0;jindex.array[k].Scan>0) { GP->index.array[k].Value=Pres[0].index.array[j]; j++; } } bestL=Lres[0]; printf("ML estimation completed.\n"); free_dmatrix(SamplePoints, 0, DoFit+1, 0, ndim+1); free(Pres); free(Lres); free(itres); } else if (DoFit==0) { for(k=0, j=0;jindex.array[j].Scan>0) { P[0].index.array[k] = GP->index.array[j].Value; for(l=1;lindex.array[j].Scale; k++; } } FindMin(0, ndim, noDates, dates, GP, P, L, Pres, Lres, itres); //write the MLestimates into GP: for(k=0, j=0;jindex.array[k].Scan>0) { GP->index.array[k].Value=Pres[0].index.array[j]; j++; } } bestL=Lres[0]; } free(P); free(L); return bestL; } /*-------------------------------------------------------------------------------------------*/ void ConstructLHTable(int num, int paramnum, double **SamplePoints) { int i,j,k,l; double r, f,ns,s; static FILE *dat; ns=(double) num; s=1.0/ns; for(i=0;iindex.array[k-1].Scale; } } amoeba(noDates, dates, P, L, TINY, ndim, &neglogLikelihood, &nfunk); it+=nfunk; } best=0; for(j=1;jL[1]) { sworst=1; worst=0; } else { sworst=0; worst=1; } for(i=0;iL[worst]) { sworst=worst; worst=i; } else if (L[i]>L[sworst] && i!=worst) sworst=i; } rtol=2.0*fabs(L[best]-L[worst])/(fabs(L[worst])+fabs(L[best])+TINY); //Compute the fractional range from worst to best and return if satisfactory. if(rtol=NMAX) { fprintf(stderr, "amoeba: NMAX exceeded\n"); return 1; } *nfunk+=2; //Begin a new iteration. First extrapolate by a factor -1 through the face of the //simplex across from the high point, i.e., reflect the simplex from the hight point. Ltry=amotry(noDates, dates, P, L, psum, ndim, funk, worst, 2.0); if(Ltry <=L[best]) //Gives a result better than the best point, //so try an additional extrapolation by a factor 2. Ltry=amotry(noDates, dates, P, L, psum, ndim, funk, worst, 2.0); else if (Ltry>=L[sworst]) { //The reflecte point is worse than the second worst, //so look for an intermediate better point, i.e., do a one-dimensional contraction. Lsave=L[worst]; Ltry=amotry(noDates, dates, P, L, psum, ndim, funk, worst, 0.5); if(Ltry>=Lsave) { //Can't seem to get rid of that bad point. Better for(i=0;iindex.array[l].Scan>0) { P.index.array[m]=GP->index.array[l].Value; for(i=0;iindex.array[k].Scan) { case 1: j++; xmin=GP->index.array[k].Min; xmax=GP->index.array[k].Max; dx=(xmax-xmin)/(NO_X-1); for(i=0;iindex.array[k].Min; xmax=GP->index.array[k].Max; dx=pow(xmax/xmin, 1.0/(NO_X-1)); for(i=0;iindex.named.kappa.Value, GP->index.named.eta.Value); for(i=0;iindex.array[k].Scan==1 || GP->index.array[k].Scan==2) { GP->index.array[k].Value=Pbest.index.array[j]; j++; } } fail=1; } //printf("CalcCIs: minimum -2lnL = %lg at kappa = %lg, eta = %lg\n", // Lbest, GP->index.named.kappa.Value, GP->index.named.eta.Value); free_dmatrix(x, 0, ndim, 0, NO_X); return fail; }