/*********************************************************************/ /* */ /* skewers.c */ /* Program for matrix comparison test of random */ /* skewers folowing Cheverud et al. (1983) and */ /* Cheverud (1996). */ /* written by Liam J. Revell (ljrevell@wustl.edu) */ /* */ /*********************************************************************/ #include #include #include #include #define IM1 2147483563 #define IM2 2147483399 #define AM (1.0/IM1) #define IMM1 (IM1-1) #define IA1 40014 #define IA2 40692 #define IQ1 53668 #define IQ2 52744 #define IR1 12211 #define IR2 3791 #define NTAB 32 #define NDIV (1+IMM1/NTAB) #define ERROR 0.000000001 // function declarations FILE *fp_read(char *, int); FILE *fp_write(char *, int); double ***mem_3d(int, int, int); double **mem_alloc(int, int); void zero_array(double **, int, int); double *mem_1d(int); double ran_ecu(long *); void rescale_vector(double *, int, double); void zero_vector(double *, int); double vector_correl(double *, double *, int); void write_output(double **, int, FILE *); double gauss(long *); // end function declarations // functions // function returns gaussian random number double gauss(long *seed) { double unif[2], rsq, factor; int i; while(1) { for(i=0; i<2; i++) unif[i]=2.0*ran_ecu(seed)-1.0; rsq=unif[0]*unif[0]+unif[1]*unif[1]; if(rsq<1) break; } factor=sqrt(-2.0*log(rsq)/rsq); return(unif[0]*factor); } // function returns file pointer "r" FILE *fp_read(char *filename, int str_size){ FILE *fp; filename[str_size-1]='\0'; fp=fopen(filename,"r"); if(!fp){ printf("Failed to open %s.\nExiting.\n",filename); exit(1); } return fp; } // function returns file pointer "w" FILE *fp_write(char *filename, int str_size){ FILE *fp; filename[str_size-1]='\0'; fp=fopen(filename,"w"); if(!fp){ printf("Failed to open %s.\nExiting.\n",filename); exit(1); } return fp; } // memory allocation for 3D double array double ***mem_3d(int depth, int width, int length){ int i,j; double ***result; result=malloc(depth*sizeof(double)); if(!result){ printf("Memory allocation failure.\n"); exit(1);} for(i=0;i=0; j--){ k=(*seed)/IQ1; *seed=IA1*(*seed-k*IQ1)-k*IR1; if (*seed<0) *seed += IM1; if (j < NTAB) iv[j]=*seed; } iy=iv[0]; } k=(*seed)/IQ1; *seed=IA1*(*seed-k*IQ1)-k*IR1; if (*seed<0) *seed += IM1; k=seed2/IQ2; seed2=IA2*(seed2-k*IQ2)-k*IR2; if (seed2<0) seed2 += IM2; j=iy/NDIV; iy=iv[j]-seed2; iv[j]=*seed; if (iy<1) iy += IMM1; result=AM*iy; return(result); } // rescale vector to arbitrary length void rescale_vector(double *vector, int size, double scale){ double sqlength, length; int i; sqlength=0.0; for(i=0;i=(r[k][l]-ERROR)) p[k][l]+=1.0/(double)num_skew; } } } printf("\n"); if(num_matrices<=4) write_output(p,num_matrices,stdout); fprintf(output,"Random skewers significances matrix:\n"); write_output(p,num_matrices,output); printf("Done. Output (also) printed to %s.\n\n",filename); printf("Press ENTER to exit.\n"); c=fgetc(stdin); c=fgetc(stdin); system("clear"); // to compile for Windows, comment this line // system("cls"); // to compile for Linux/Unix, comment this line return 0; }