/*********************************************************************/ /* */ /* multi_mantel.c */ /* Program for multiple matrix regression and */ /* hypothesis testing with the Mantel procedure */ /* (Mantel 1967). */ /* written by Liam J. Revell (ljrevell@wustl.edu) */ /* */ /*********************************************************************/ #include #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 SWAP(a,b) {temp=(a);(a)=(b);(b)=temp;} #define TOLERANCE 0.000000001; // function declarations FILE *fp_read(char *, int); double ***mem_3d(int, int, int); double **mem_alloc(int, int); void get_matrices(int n, int nummatrices, double ***matrix, FILE *fp); void get_matrix(int n, double **matrix, FILE *fp); double *mem_1d(int); void unfold_nx(int n, int num_matrices, double ***matrices, double **column); void unfold(int n, double **matrix, double *column); void calc_cov(int totN, int chars, double **data, double **matrix); double *cov_xy(int totN, int chars, double *y, double **x); void gaussj(double **a, int n, double **b, int m); int *mem_int_vect(int nl,int nh); void free_ivector(int *v,int nl,int nh); void reg_coefs(double **V, double *c, double *beta, int N); double **copy_array(double **, int, int); double SS_regression(double *y, int n, double **x, int p, double *beta, double beta0); double calc_intercept(int n, double *y, int p, double **x, double *beta); double SS_error(double *y, int n, double **x, int p, double *beta, double beta0); double SS_total(double *y, int n); double F_ratio(double SS_regression, double SS_error, int n, int p); void print_anova(FILE *fp, double R, double table[3][4], int n, int p, double **t_table); void permute(long *seed, int n, double **matrix); int *mem_1d_int(int length); double ran_ecu(long *seed); double multi_Rsq(double *y, double *beta, double *cov_yx, double **cov_xx, int n, int p); double *se_beta(int p, int n, double *y, double Rsq, double **cov_inv); FILE *fp_write(char *, int); int get_matrix_form(char c); void get_data(int form, int n, int nummatrices, double **ymatrix, double ***xmatrices, FILE *fp); void get_matrix_ld(int n, double **matrix, FILE *fp); void get_matrices_ld(int n, int nummatrices, double ***matrix, FILE *fp); void get_matrix_ud(int n, double **matrix, FILE *fp); void get_matrices_ud(int n, int nummatrices, double ***matrix, FILE *fp); double **print_predicted(int n, int numcols, double ***x, double *beta, double beta0, FILE *fp); double **print_residual(int n, double **y, double **predicted, FILE *fp); double sign(double num); // end function declarations // functions // returns sign (-1 or +1) double sign(double num){ double sign; if(num<0.0) sign=-1.0; else sign=1.0; return sign; } // prints residuals double **print_residual(int n, double **y, double **predicted, FILE *fp){ int i, j; double **residual; residual=mem_alloc(n,n); 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); } // malloc an integer vector int *mem_1d_int(int length){ int *result; result=malloc(length*sizeof(int)); if(!result){ printf("Memory allocation failure.\n"); exit(1);} return result; } // permute rows and columns together in matrix void permute(long *seed, int n, double **matrix){ int i,j,k,temp; int *pos; double **refmat; refmat=copy_array(matrix,n,n); pos=mem_1d_int(n); for(i=0;i0;j--){ k=(j+1)*ran_ecu(seed); temp=pos[j]; pos[j]=pos[k]; pos[k]=temp; } /* Use the randomized position vector to move the rows and columns of mat1 */ for(j=0;j=F\n"); fprintf(fp,"Model\t%d\t%lf\t%lf\t%lf\t%lf\n",p,table[0][0],table[0][1],table[0][2],table[0][3]); fprintf(fp,"Error\t%d\t%lf\t%lf\n",n-p-1,table[1][0],table[1][1]); fprintf(fp,"Total\t%d\t%lf\n",n,table[2][0]); fprintf(fp,"\nParameter Estimates : \n"); fprintf(fp,"Variable\tEstimate\tSE \tt \tProb>=t\n"); fprintf(fp,"Intercept\t%lf\n",t_table[0][0]); for(i=1;i<=p;i++) fprintf(fp,"Beta_%d \t%lf\t%lf\t%lf\t%lf\n",i,t_table[i][0],t_table[i][1],t_table[i][2],t_table[i][3]); fprintf(fp,"\n"); } // calculate the F-ratio double F_ratio(double SS_regression, double SS_error, int n, int p){ double MS_reg, MS_err; MS_reg=SS_regression/(double)p; MS_err=SS_error/(double)(n-p-1); return MS_reg/MS_err; } // calculate the total sum of squares double SS_total(double *y, int n){ int i, j; double ymean=0.0; double SS=0.0; // calculate mean y for(i=0;i=big){ big=fabs(a[j][k]); row=j; col=k; } } } ++(piv[col]); if(row!=col){ for(l=1;l<=n;l++) SWAP(a[row][l],a[col][l]); for(l=1;l<=m;l++) SWAP(b[row][l],b[col][l]); } xr[i]=row; xc[i]=col; if(a[col][col]==0.0) { printf("Error gaussj: Singular Matrix\n"); exit(1); } pivinv=1.0/a[col][col]; a[col][col]=1.0; for(l=1;l<=n;l++) a[col][l]*=pivinv; for(l=1;l<=n;l++) b[col][l]*=pivinv; for(ll=1;ll<=n;ll++) if(ll!=col){ dum=a[ll][col]; a[ll][col]=0.0; for(l=1;l<=n;l++) a[ll][l]-=a[col][l]*dum; for(l=1;l<=m;l++) a[ll][l]-=b[col][l]*dum; } } for(l=n;l>=1;l--){ if(xr[l]!=xc[l]); } free_ivector(piv,1,n); free_ivector(xr,1,n); free_ivector(xc,1,n); } // allocate an int vector with subscript range v[nl..nh] int *mem_int_vect(int nl,int nh){ int *v; v=(int *)malloc((unsigned) (nh-nl+1)*sizeof(int))-nl; if (v==NULL){ printf("Memory allocation error."); exit(1); } return v; } // free an int vector allocated with mem_int_vect() void free_ivector(int *v,int nl,int nh){ free((char*) (v+nl)); } // this function calculates a y with xi covariance vector double *cov_xy(int totN, int chars, double *y, double **x){ int i, k; double MCP, M[2]; double *cvector; cvector=mem_1d(chars+1); for(i=0;i=ANOVA_table[0][2]) ANOVA_table[0][3]+=(1.0/numperms); for(j=1;j<=nummatrices;j++){ t_sign=sign(t[j]); t[j]*=t_sign; t[j]+=TOLERANCE; if(t[j]>=fabs(t_table[j][2])) t_table[j][3]+=(1.0/numperms); } // permute y matrix permute(&seed, numvars, ymatrix); // free memory allocated within the loop free(cvector); } fclose(fp); fp=fp_write(outfile,strlen(outfile)); system("clear"); // comment line for Windows // system("cls"); // comment line for Linux fprintf(fp,"Results of regression analysis on %s : \n\n",filename); fprintf(stdout,"Results of regression analysis on %s : \n\n",filename); print_anova(stdout, Rsq0, ANOVA_table, numvars*(numvars-1)/2, nummatrices, t_table); print_anova(fp, Rsq0, ANOVA_table, numvars*(numvars-1)/2, nummatrices, t_table); if(print_resid==1){ predicted=print_predicted(numvars, nummatrices, xmatrices, beta_original, t_table[0][0], fp); residual=print_residual(numvars, ymatrix_original, predicted, fp); } printf("Output also printed to %s.\nPress ENTER to exit.\n", outfile); c=fgetc(stdin); c=fgetc(stdin); fclose(fp); return 0; }