int main(int argc, char *argv[]) { int i, count, readfile; void config(int rt, int rmax, int ic); double ewens_form(int *r, int r_tot, double *mpt); double F(int *r), multiplicity; double theta_est(int k_obs, int n); void print_config(int *r); long start_time, finish_time, net_time; void fill_factors(); start_time = time(NULL); if (argc == 1) { printf("Specify the configuration on the command line\n"); exit(0); } k = argc - 1; for (i=1; i<=k; i++) { r_obs[i] = atoi(argv[i]); r_tot += r_obs[i]; } F_obs = F(r_obs); printf("\nn = %d, k = %d, theta = %g, F = %g\n", r_tot, k, theta_est(k, r_tot), F_obs); if (r_tot >= RLIM) { printf("n = %d is too large..\n", r_tot); exit(0); } if (k >= KLIMIT) { printf("k = %d is too large.\n", k); exit(0); } for (i=1; i<k; i++) if (r_obs[i] < r_obs[i+1]) { print_config(r_obs); printf(" is not a valid configuration.\n"); exit(0); } r_top = r_tot - 1; Fsig = Esig = 0; fill_factors(); obs_value = ewens_form(r_obs, r_obs[1], &multiplicity); config(r_tot, r_tot-k+1, 1); print_config(r_obs); printf(": P_E = %g, ", sig_sum / tot_sum); printf("P_H = %g\n", F_sig_sum / tot_sum); finish_time = time(NULL); net_time = time(NULL) - start_time; if (net_time < 60) printf("Program took %ld seconds\n", net_time); else printf("Program took %4.2f minutes\n", net_time / 60.0); } /* end, main */
void Slatkin::GetEwens(int* r_obs_param, int k_param, double& theta_rval, double& F_rval, double& p_e_rval, double& p_h_rval) { void config(int rt, int rmax, int ic); void fill_factors(); void print_config(int *r); double ewens_form(int *r, int r_top, double *mpt); double F(int *r), multiplicity; double theta_est(int k_obs, int n); double kval(double x, int n); init(); k = k_param; for (int i = 0; i < k; i++) { r_obs[i+1] = r_obs_param[i]; } printf("[get_ewens]\tentering with k=%d\n", k); printf("\t\tr_obs: "); int i; long start_time, finish_time, net_time; start_time = time(NULL); r_tot = 0; for (i=1; i<=k; i++) { r_tot += r_obs[i]; printf("%d ", r_obs[i]); fflush(stdout); } printf("\n"); F_obs = F(r_obs); theta_rval = theta_est(k, r_tot); //printf("\nn = %d, k = %d, theta = %g, F = %g\n",r_tot, k, theta_rval, F_obs); F_rval = F_obs; if (r_tot >= RLIM) { printf("n = %d is too large..\n", r_tot); exit(0); } if (k >= KLIMIT) { printf("k = %d is too large.\n", k); exit(0); } for (i=1; i<k; i++) if (r_obs[i] < r_obs[i+1]) { //print_config(r_obs); printf(" is not a valid configuration.\n"); exit(0); } r_top = r_tot - 1; Fsig = Esig = 0; fill_factors(); obs_value = ewens_form(r_obs, r_obs[1], &multiplicity); config(r_tot, r_tot-k+1, 1); //print_config(r_obs); p_e_rval = sig_sum / tot_sum; p_h_rval = F_sig_sum / tot_sum; //printf(": P_E = %g, ", p_e_rval); //printf("P_H = %g\n", p_h_rval); finish_time = time(NULL); net_time = time(NULL) - start_time; //if (net_time < 60) // printf("Program took %ld seconds\n", net_time); //else // printf("Program took %4.2f minutes\n", net_time / 60.0); }
slatkin_result slatkin_mc(int maxreps, int r_obs[]) { slatkin_result results; double theta_estimate; int i, j, k, n, repno, Ecount, Fcount; int *r_random, *r_random_to_free; double E_obs, F_obs; double *ranvec; seedMT(time(NULL)); /* Find k and n from the observed configuration */ k = 0; n = 0; while (r_obs[k+1]) { k++; n+=r_obs[k]; } /* memory management notes - the following are dynamically allocated and need to be freed: Slatkin allocates these in the ivector, vector, and matrix methods, BUT does not pass back the raw pointer to the allocated region or "head." Instead, he passes back the spot where he wants the calling code to write data (in the case of the vector call especially). So...we have to readjust the pointers *back* in order to free them...wacky, but true. r_random -- what's being returned is head + 1, so free r_random - 1 ranvec -- just free this pointer b -- have to walk K+1 rows, free each of the rows, then free b */ r_random = ivector(0, k+1); r_random_to_free = r_random - 1; r_random[0] = r_random[k+1] = 0; ranvec = vector(1, k-1); // to avoid doing this in each replicate /* fill b matrix */ //double **b = matrix(1, k, 1, n); double **b = create2DDoubleArray(k+1, n+1); for (j=1; j<=n; j++) b[1][j] = 1.0 / j; for (i=2; i<=k; i++) { b[i][i] = 1.0; for (j=i; j<n; j++) b[i][j+1] = (i * b[i-1][j] + j * b[i][j]) / (j + 1.0); } F_obs = F(k, n, r_obs); E_obs = ewens_stat(r_obs); /*printf("\nn = %d, k = %d, theta = %g, F = %g, maxrep = %d\n", n, k, theta_est(k, n), F_obs, maxrep);*/ Ecount = 0; Fcount = 0; for (repno=1; repno<=maxreps; repno++) { generate(k, n, r_random, ranvec, b); if (ewens_stat(r_random) <= E_obs) Ecount++; if (F(k, n, r_random) <= F_obs) Fcount++; } theta_estimate = theta_est(k, n); results.probability = (double) Ecount / (double) maxreps; results.theta_estimate = theta_estimate; /* free the dynamically allocated memory - the matrix b is still problematic */ free(ranvec); free(r_random_to_free); /* the allocations occur in the matrix() function, starting on line 207 The matrix first allocates a number of rows (k) as pointers to doubles. then it allocates all the columns (n) as pointers to doubles. So to unwind this, we need to walk the matrix and free each row of doubles, and then we can free the original list of double* pointers to the rows themselves. right? */ for(i=0; i < k+1; i++) { free(b[i]); } free(b); return results; }