/* Updated 9/18/2000. Earlier version had a serious bug. */ /* Modified 9/19/2000 to allow more than two samples, and carry out global test and test each pair of samples. */ /* This program carries out the "nearest neighbor test" described in Hudson, R.R. 2000 "A new statistic for detecting genetic differentiation" Genetics (in press). Data consists of a matrix of pairwise differences between sampled sequences, as described in readme. An example data file is sample.dat . The program can usually be compiled by gcc -o snn snn.c . And then run by snn y 1000 20 27 sample.out . On the command line, 20 is the sample size from locality one, and 27 is the sample size from locality two. 1000 is the number of permutations to carry out. y indicates that the input data matrix should be copied to the output.i If the first sample, in this example, were actually from two localities, say the first 8 from one locality and the next 12 from another locality, then one can run the program as follows: snn n 1000 8 12 27 sample2.out The program will carry out a global test for structure, and will test each pair of samples for significant structure. */ #include #include #include #include #include main( int argc, char * argv[] ) { int nperms, nlocs, nsam ; double **dij, **dij2, pval, snno, permt(), **tdij ; int i, loc, wf, *ni, tni[3], loc1, loc2, j, sti, stj, endi, endj ; int iloc, jloc, ni2[2] ; if( argc < 4 ) { printf( "usage: snn y/n(print data?) n_permutations n1 n2 ... \n"); exit(1) ; } nperms = atoi( argv[2] ) ; nlocs = argc - 3 ; if( (ni = (int *)malloc( (size_t) (nlocs+1)*sizeof(int) )) == NULL) perror( "malloc error1\n") ; nsam = 0 ; for( i=0; i 2 ) fprintf(stdout," Global test:\n "); fprintf(stdout," Snn: "); fprintf(stdout," %lf ( p-value: %lf)\n", snno, pval); if( nlocs > 2 ) { fprintf(stdout," Pairwise tests of samples:\n"); for( iloc = 0; iloc < nlocs-1; iloc++) for( jloc = iloc + 1 ; jloc < nlocs; jloc++){ loaddij( iloc, jloc, ni, dij, dij2 ) ; ni2[0] = ni[iloc]; ni2[1] = ni[jloc] ; pval = permt( nperms, ni2[0]+ni2[1], 2, ni2, dij2, &snno); fprintf(stdout," %d %d: Snn: ", iloc+1, jloc+1 ); fprintf(stdout," %lf ( p-value: %lf)\n", snno, pval); } } } int loaddij( int iloc, int jloc, int *ni, double **dij, double **dij2 ) { int start1, start2, i, j ; int ni2[2] ; start1 = start2 = 0 ; for( i=0; i< iloc; i++) start1 += ni[i] ; for( i=0; i< jloc; i++) start2 += ni[i] ; ni2[0] = ni[iloc]; ni2[1] = ni[jloc] ; for( i=0; i= snno ) count2++ ; } free( ran_ind); return( (double)count2/(double)nperms ); } int getmatrix(nsam,dij,pflag) int nsam; double **dij; char pflag; { int i, j, jstart, jend ; char gamnam[35], s[1000]; FILE *pf ; pf = stdin; i = 0 ; jend = -1 ; while( i< nsam-1 ){ jstart = jend +1 ; while(1){ fgets(s,1000, pf); if( pflag == 'y') fputs(s,stdout); if( s[0]=='O' && s[1]=='T' && s[2]=='U'&&s[3]=='s' ) { jend = countwords(s) + jstart -2 ; if( i==0) jstart++ ; break; } } for( i=0; i 0 ; i--){ j = ran1()*(i + 1) ; temp = ran_vect[j]; ran_vect[j] = ran_vect[i] ; ran_vect[i] = temp ; } } double ran1() { double drand48(); return( (double)drand48() ); } double snnf(int nsam, int npop, int *config, double **dij, int *ran_ind) { int i2, i, ind, nmall, nmwithin , pop, indstart ; double p, mall, minofdij() ; p = 0. ; for(ind= pop=0; pop