Ejemplo n.º 1
0
int main(int argc, char *argv[])
{
    double a = 1, b = 2, S, I = primitive(b) - primitive(a);
    unsigned i, n = 10;
    if(argc > 1) n = atoi(argv[1]);
    rlxd_init(2,time(NULL));
    FILE *f1 = fopen("integral1.dat","a");
    FILE *f2 = fopen("integral2.dat","a");
    FILE *f3 = fopen("integral3.dat","a");
    FILE *f4 = fopen("integral4.dat","a");

    for(S = i = 0; i < n; i++)
        S += newton_cotes1(function, a+i*(b-a)/n, a+(i+1)*(b-a)/n);
    fprintf(f1,"%d\t%e\n", n, fabs(I-S));

    for(S = i = 0; i < n; i++)
        S += newton_cotes2(function, a+i*(b-a)/n, a+(i+1)*(b-a)/n);
    fprintf(f2,"%d\t%e\n", n, fabs(I-S));

    for(S = i = 0; i < n; i++)
        S += gauss5(function, a+i*(b-a)/n, a+(i+1)*(b-a)/n);
    fprintf(f3,"%d\t%e\n", n, fabs(I-S));

    S = monte_carlo(function, a, b, n);
    fprintf(f4,"%d\t%e\n", n, fabs(I-monte_carlo(function, a, b, n)));

    fclose(f1);
    fclose(f2);
    fclose(f3);
    fclose(f4);

    return 0;
}
Ejemplo n.º 2
0
int main(int argc,char*argv[]){
    const int num_iters=200000,num_shortlist_iters=1000000;

    srand(tick_count());
    Player me,opponent;
    if(argc==5){
        sscanf(argv[1],"%d",&me.health);
        sscanf(argv[2],"%d",&opponent.health);
        sscanf(argv[3],"%d",&me.honour);
        sscanf(argv[4],"%d",&opponent.honour);
        me.lastMove=WAIT;
        opponent.lastMove=WAIT;
    }else{
        sscanf(argv[3],"%d",&me.health);
        sscanf(argv[4],"%d",&opponent.health);
        sscanf(argv[5],"%d",&me.honour);
        sscanf(argv[6],"%d",&opponent.honour);
        me.lastMove=decode_move(argv[1][strlen(argv[1])-1]);
        opponent.lastMove=decode_move(argv[2][strlen(argv[2])-1]);
    }

    struct SimulationStat results[6];
    results[0].first_me_move=WAIT;
    results[0].win=0;
    results[0].draw=0;
    results[0].lose=num_iters;
    results[0].compound=-num_iters*2-1000; //waiting is worse than any other action

    for(enum Move first_me_move=BOW;first_me_move<=OVERHEAD;++first_me_move){
        results[first_me_move]=monte_carlo(num_iters,first_me_move,me,opponent);
        struct SimulationStat *cur=&results[first_me_move];
        cur->compound=cur->win*4+cur->draw*1-cur->lose*2;
    }
    qsort(results,OVERHEAD-WAIT+1,sizeof(*results),stat_compare);

    for(int i=0;i<OVERHEAD-BOW+1;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_iters*100.,(double)cur->draw/num_iters*100.,(double)cur->lose/num_iters*100.,cur->compound);
    }

    for(int i=0;i<2;++i){
        results[i]=monte_carlo(num_shortlist_iters,results[i].first_me_move,me,opponent);
        struct SimulationStat *cur=&results[i];
        cur->compound=cur->win*2+cur->draw*1;
    }
    qsort(results,2,sizeof(*results),stat_compare); 

    for(int i=0;i<2;++i){
        struct SimulationStat *cur=&results[i];
//        fprintf(stderr,"%c: %f%% win, %f%% draw, %f%% lose => %d\n","WBGIPO"[cur->first_me_move],(double)cur->win/num_shortlist_iters*100.,(double)cur->draw/num_shortlist_iters*100.,(double)cur->lose/num_shortlist_iters*100.,cur->compound);
    }
    putchar("WBGIPO"[results[0].first_me_move]);
    return 0;
}
int main () {
    FILE
        *entrada;
    int
        i,
        n_rep, /* Número de repetições */
        n_pontos, /* Número de pontos */
        k; /* Numero de retangulos ou trapezios */
    long
        semente;
    char
        metodo;
    float
        soma,
        area;

    entrada = fopen (ENTRADA, "r");
    if (entrada == NULL) {
        printf ("ERRO : arquivo nao encontrado\n");
        return -1;
    }

    while (!feof (entrada)) {
        fscanf (entrada, "%c", &metodo);
        switch (metodo) {
            case 'm' :
                fscanf (entrada, "%ld %d %d", &semente, &n_rep, &n_pontos);
                printf ("Metodo Monte Carlo, semente=%ld repeticoes=%d pontos=%d\n", semente, n_rep, n_pontos);

                soma = 0;
                for ( i = 1; i <= n_rep; ++ i) {
                    area = monte_carlo (0, 1, &semente, n_pontos);
                    printf (" Estimativa %d:    pi=%.5f    erro=%.5f\n", i, area * 4, errorel (area * 4, PI));
                    soma += area * 4;
                }
                printf ("<resposta> <mtc>     %.5f     %.5f\n\n", soma / n_rep, errorel (soma / n_rep, PI));
                break;
            case 'r' :
                fscanf (entrada, "%d\n", &k);
                printf ("Metodo dos retangulos, retangulos=%d  deltax=%.5f\n", k, 1.0 / k);
                area = retangulo (0, 1, k);
                printf ("<resposta> <ret>     %.5f     %.5f\n\n", area * 4, errorel (area * 4, PI));
                break;
            case 't' :
                fscanf (entrada, "%d", &k);
                printf ("Metodo dos trapezios, retangulos=%d  deltax=%.5f\n", k, 1.0 / k);
                area = trapezoide (0, 1, k);
                printf ("<resposta> <tpz>     %.5f     %.5f\n\n", area * 4, errorel (area * 4, PI));
                break;
        }
    }
    fclose (entrada);
    return 0;
}
Ejemplo n.º 4
0
void simulation::run() {
    //generate a time based seed
    unsigned long int t_seed = std::chrono::high_resolution_clock::
        now().time_since_epoch().count();
    std::mt19937 generator (t_seed);
    std::uniform_real_distribution<double> dist(0.0, 1.0);
    //std::cout << t_seed << std::endl;
    //loop for generating tor angles
    //starts at 3rd atom -> n-1
    for (unsigned int n=3; n < (m_back_list.size()-1); n++) {
        cond_prob(m_back_list[n-1], m_back_list[n], m_tor_list[n-3]);
        double rand_num = dist(generator);
        //std::cout << rand_num << std::endl;
        monte_carlo(rand_num);
    }
}
Ejemplo n.º 5
0
float find_location(Map map, Particle particles[]) {
    float readings[72] = {
        32, 32, 32, 32, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30,	30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30, 30, 30, 30,	30, 30, 30, 30, 30, 30, 30, 30, 30, 15, 15, 15,
        15, 15, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30
    };
    int i = 54, ii;
    int *histogram = calloc(360, sizeof(int));

    robot_position = 270;

    while (variance(particles, NUM_PARTICLES) > POSITION_PROBABILITY_THRESHOLD * POSITION_PROBABILITY_THRESHOLD) {

        move_particles(particles);
        robot_position += TRAVEL_DISTANCE;

        if (robot_position > 360)
            robot_position -= 360;

        monte_carlo(map, particles, NUM_PARTICLES, readings[i % 72]);

        qsort(particles, NUM_PARTICLES, sizeof(Particle), compare_particles);
        if (i == 1 || i == 10) {
            printf("at time %d:\n", i);

            for (ii = 0; ii < NUM_PARTICLES; ii++) {
                histogram[(int)particles[ii].position]++;
            }

            for (ii = 0; ii < 360; ii++) {
                printf("%d, %d\n", ii, histogram[ii]);
            }
        }
        printf("at time %d std deviation: %.2f\n", i, standard_deviation(particles, NUM_PARTICLES));
        i++;
        if (i > 71)
            i = 0;
    }

    printf("Location %.2f in %d turns\n", mean_position(particles, NUM_PARTICLES), i);
    printf("Actual location %d\n", (int)robot_position);
    free(histogram);
    return mean_position(particles, NUM_PARTICLES);
}
Ejemplo n.º 6
0
std::vector<double> stratification(int n, Fct f, 
								   std::list<double> pk,
								   std::list<Gen> Gk) 
{
	std::vector<double> result(3, 0), res_tmp; 
	std::list<double>::iterator it_pk = pk.begin();
	typename std::list<Gen>::iterator it_Gk = Gk.begin();
	double var_strate_k = 0;
	while (it_pk != pk.end()) {
		unsigned nk = floor(n*(*it_pk));
		res_tmp = monte_carlo(nk, f, *it_Gk);
		result[0] += (*it_pk) * res_tmp[0];
		result[1] += (*it_pk) * res_tmp[1];
		it_pk++; it_Gk++;
	}
	result[2] = 1.96*sqrt(result[1]/(double) n);
	return result;	
}
Ejemplo n.º 7
0
int main(){

    frame anim = frame(400, 300, 10, "frames/image");
    anim.init(0,0,0);

    anim.curr_frame = 1;

    //animate_square(anim, 1.0, 250, anim.origin);

    //anim.curr_frame += 50;

    //animate_circle(anim, 1.0, 250 / 2, anim.origin);

    //cairo_move_to(anim.frame_ctx[anim.curr_frame],200,150);
    //cairo_rel_line_to(anim.frame_ctx[anim.curr_frame],250 / 2,0);
    //cairo_stroke(anim.frame_ctx[anim.curr_frame]);

    //draw_batman(anim, anim.res_x * 0.05, anim.origin);

    monte_carlo(anim, 0.01, 250);

    anim.draw_frames();    
} 
Ejemplo n.º 8
0
int main ( void )

/******************************************************************************/
/*
  Purpose:

    MAIN is the main program for RANDOM_OPENMP.

  Discussion:

    This program simply explores one issue in the generation of random
    numbers in a parallel program.  If the random number generator uses
    an integer seed to determine the next entry, then it is not easy for
    a parallel program to reproduce the same exact sequence.

    But what is worse is that it might not be clear how the separate
    OpenMP threads should handle the SEED value - as a shared or private
    variable?  It seems clear that each thread should have a private
    seed that is initialized to a distinct value at the beginning of
    the computation.

  Licensing:

    This code is distributed under the GNU LGPL license. 

  Modified:

    03 September 2012

  Author:

    John Burkardt
*/
{
  int n;
  int seed;

  timestamp ( );

  printf ( "\n" );
  printf ( "RANDOM_OPENMP\n" );
  printf ( "  C version\n" );
  printf ( "  An OpenMP program using random numbers.\n" );
  printf ( "  The random numbers depend on a seed.\n" );
  printf ( "  We need to insure that each OpenMP thread\n" );
  printf ( "  starts with a different seed.\n" );
  printf ( "\n" );
  printf ( "  Number of processors available = %d\n", omp_get_num_procs ( ) );
  printf ( "  Number of threads =              %d\n", omp_get_max_threads ( ) );

  n = 100;
  seed = 123456789;
  monte_carlo ( n, &seed );
/*
  Terminate.
*/
  printf ( "\n" );
  printf ( "RANDOM_OPENMP\n" );
  printf ( "  Normal end of execution.\n" );

  printf ( "\n" );
  timestamp ( );

  return 0;
}
Ejemplo n.º 9
0
std::vector<double> monte_carlo(int n, Fct1 f1, Fct2 f2, Gen G)
{
	return monte_carlo(n, compose(f1, compose(f2, G))); 
};
Ejemplo n.º 10
0
std::vector<double> monte_carlo(int n, Fct f, Gen G)
{
	return monte_carlo(n, compose(f, G)); 
};
Ejemplo n.º 11
0
main()
{
  MINTEG ia={2.0,9.0,10000,monte_carlo_ptr};
  double s=monte_carlo(&ia);
  printf("\ns=%e\n\n",s);
}
Ejemplo n.º 12
0
int main()
{
    size_t i;
    size_t num_iter_single = 1000000;
    size_t num_iter_parallel = 10000000;

    state base_state = (state) {rectangle(7, 7), 0, 0, 0, 0, 0, 0};
    int asdf;
    make_move(&base_state, one(3, 3), &asdf);
    state_info si;
    init_state(&base_state, &si);

    state s = base_state;
    jkiss jk;
    jkiss_init(&jk);
    printf("%d\n", playout(&s, si, &jk));
    print_state(&s);
    kill_groups(&s);
    print_state(&s);
    printf("%d\n", chinese_liberty_score(&s));

    score_bins sb = score_bins_new(base_state);

    for (i = 0; i < num_iter_single; i++) {
        score_bins_add(sb, clean_playout(base_state, si, &jk));
    }
    print_score_bins(sb, 50);
    printf("-----------------------------\n");

    score_bins_reset(sb);
    monte_carlo(base_state, si, sb, num_iter_parallel);
    print_score_bins(sb, 50);

    /*
    int num_threads = omp_get_max_threads();
    jkiss *jks = malloc(num_threads * sizeof(jkiss));
    bin_t **binss = malloc(num_threads * sizeof(bin_t*));
    for (int i = 0; i < num_threads; i++) {
        binss[i] = calloc(num_bins, sizeof(bin_t));
        jkiss_init(jks + i);
    }
    int tid;
    int finished = 0;
    #pragma omp parallel private(i, s, tid)
    {
        tid = omp_get_thread_num();
        for (i = 0; i < num_iter_parallel; i++) {
            s = base_state;
            playout(&s, si, jks + tid);
            kill_groups(&s);
            int score = chinese_liberty_score(&s);
            if (s.white_to_play) {
                score = -score;
            }
            binss[tid][si.size + score]++;
            // Bailout once one thread finishes.
            if (finished) {
                break;
            }
        }
        finished = 1;
    }

    for (i = 0; i < num_bins; i++) {
        bins[i] = 0;
    }
    for (i = 0; i < num_threads; i++) {
        for (int j = 0; j < num_bins; j++) {
            bins[j] += binss[i][j];
        }
    }
    print_bins(bins, num_bins, 128);
    */

    return 0;
}
Ejemplo n.º 13
0
int complement_match (Representation* X_rep, Representation* Y_rep,
		      Map * map, int map_max,
		      int * map_ctr, int * map_best, int best_max, int parent_map){
			
    Penalty_parametrization penalty_params; /* for SW */
    double **x    = X_rep->full;
    int * x_type  = X_rep->full_type;
    int NX        = X_rep->N_full;
    double **y    = Y_rep->full;
    int * y_type  = Y_rep->full_type;
    int NY        = Y_rep->N_full;
    
    double F_effective = 0.0;
    double F_current;
    double q[4] = {0.0}, q_init[4] = {0.0};
    double **x_rotated = NULL;
    double **tr_x_rotated = NULL;
    double **R;
    double z_scr = 0.0, *z_best;
    double avg, avg_sq, stdev;
    double alpha = options.alpha;
    double rmsd, best_rmsd[TOP_RMSD];
    double **best_quat;
    double cutoff_rmsd = 3.0; /* <<<<<<<<<<<<<<<<< hardcoded */
    int *x_type_fudg, *y_type_fudg;
    int *anchor_x, *anchor_y, no_anchors;
    int no_top_rmsd = TOP_RMSD, chunk;
    int x_ctr, y_ctr, top_ctr;
    int **best_triple_x;
    int **best_triple_y;
    int x_triple[3], y_triple[3];
    int retval, done = 0;
    int best_ctr;
    int i, j;
    int t;
    int smaller;
    int my_map_ctr;
    int stored_new;
    int * x2y, map_unstable;
    //time_t  time_now, time_start;
    
    int cull_by_dna (Representation * X_rep, int *set_of_directions_x,
		 Representation * Y_rep, int *set_of_directions_y,
		     int set_size, Map *map, double cutoff_rmsd);
    int distance_of_nearest_approach (Representation * X_rep, int *set_of_directions_x,
				      Representation * Y_rep, int *set_of_directions_y,
				      int set_size,  double * rmsd_ptr);
    int same_hand_triple (Representation * X_rep, int *set_of_directions_x,
			  Representation * Y_rep, int *set_of_directions_y, int set_size);
    
    int find_map (Penalty_parametrization * params, Representation *X_rep,  Representation *Y_rep,
		  double ** R, double alpha, double * F_effective,  Map *map, 
		  int *anchor_x, int * anchor_y, int anchor_size );
    int find_next_triple (double **X, double **Y, 
			  int *x_type, int *y_type, int NX, int NY,
			  int *x_triple, int *y_triple);
    int gradient_descent (int first_call, double alpha,
			  double **x, int * x_type, int NX,
			  double **y, int * y_type, int NY,
			  double *q_best, double *F_best_ptr) ;
    int map_quality_metrics (Representation *X_rep, Representation *Y_rep,
			     double ** tr_x_rotated, Map * map, int *reasonable_angle_ct);
    int monte_carlo (double alpha,
		 double **x, int * x_type, int NX,
		 double **y, int * y_type, int NY,
		 double  *q_best, double *F_best_ptr);
    int opt_quat (double ** x, int NX, int *set_of_directions_x,
		  double ** y, int NY, int *set_of_directions_y,
		  int set_size, double * q, double * rmsd);
    int qmap (double *x0, double *x1, double *y0, double *y1, double * quat);
    int store_sorted (Map * map, int NX, int NY, int *map_best, int map_max,
		      double * z_best, int best_ctr,
		      double z_scr, int  my_map_ctr, int *stored);
    
	    
    
    map_best[0] = -1; /* it is the end-of-array flag */
    if ( *map_ctr >= map_max ) {
	fprintf (stderr, "Map array undersized.\n");
	exit (1);
    }

    smaller = (NX <= NY) ? NX : NY;
 
    /***********************/
    /* memory allocation   */
    /***********************/
    if ( ! (R=dmatrix(3,3) ) ) return 1; /* compiler is bugging me otherwise */
    if ( ! (x_rotated    = dmatrix (NX,3)) ) return 1;
    if ( ! (tr_x_rotated = dmatrix (NX,3)) ) return 1;
    if ( ! (best_quat    = dmatrix (no_top_rmsd,4)) ) return 1;
    if ( ! (best_triple_x    = intmatrix (no_top_rmsd,3)) ) return 1;
    if ( ! (best_triple_y    = intmatrix (no_top_rmsd,3)) ) return 1;
    if ( ! (z_best = emalloc(NX*NY*sizeof(double) )) ) return 1;
    if ( ! (x_type_fudg = emalloc(NX*sizeof(int) )) ) return 1;
    if ( ! (y_type_fudg = emalloc(NY*sizeof(int) )) ) return 1;
    if ( ! (anchor_x = emalloc(NX*sizeof(int) )) ) return 1;
    if ( ! (anchor_y = emalloc(NY*sizeof(int) )) ) return 1;

    penalty_params.custom_gap_penalty_x = NULL;
    penalty_params.custom_gap_penalty_y = NULL;
    //if ( ! (penalty_params.custom_gap_penalty_x = emalloc(NX*sizeof(double) )) ) return 1; 
    //if ( ! (penalty_params.custom_gap_penalty_y = emalloc(NY*sizeof(double) )) ) return 1; 
    /***********************/
    
    /***********************/
    /* expected quantities */
    /***********************/
    avg = avg_sq = stdev = 0.0;
    //if (options.postprocess) {
    if (0) {
	if (F_moments (x, x_type, NX, y, y_type, NY, alpha, &avg, &avg_sq, &stdev)) return 1;
    }
    /***********************/
    

    /***********************/
    /* initialization      */
    /***********************/
    best_ctr   = 0;
    penalty_params.gap_opening   = options.gap_open;
    penalty_params.gap_extension = options.gap_extend;
    penalty_params.endgap        = options.endgap;
    penalty_params.endgap_special_treatment = options.use_endgap;
    /***********************/

    /***************************************/
    /* find reasonble triples of SSEs      */
    /* that correspond in type             */
    /*  and can be mapped onto each other  */
    /***************************************/
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	best_rmsd[top_ctr] = BAD_RMSD+1;
	best_triple_x[top_ctr][0] = -1;
    }
	
    for (x_ctr=0; x_ctr < NX-2 && !done; x_ctr++) {
	
	for (y_ctr=0; y_ctr < NY-2 && !done; y_ctr++) {

	    if ( y_type[y_ctr] != x_type[x_ctr] ) continue;
	    
	    x_triple[0] = x_ctr;
	    y_triple[0] = y_ctr;
	    
	    if (find_next_triple (x, y,  x_type, y_type,
				  NX, NY,  x_triple, y_triple) ){
		continue;
	    }

	    if ( x_triple[1] < 0 ||  x_triple[2] < 0 ) continue;
	    if ( y_triple[1] < 0 ||  y_triple[2] < 0 ) continue;

	    /* do these three have  kind-of similar layout in space?*/
	    /* is handedness the same? */
	    if ( ! same_hand_triple ( X_rep, x_triple, Y_rep, y_triple, 3)) continue;
	    
	    /* are distances comparab;e? */
	    if (distance_of_nearest_approach ( X_rep, x_triple,
					       Y_rep, y_triple, 3, &rmsd)) continue;
	    if ( rmsd > cutoff_rmsd) continue;
	    
	    /* find q_init that maps the two triples as well as possible*/
	    if ( opt_quat ( x,  NX, x_triple, y, NY, y_triple, 3, q_init, &rmsd)) continue;


	    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
		
		if (  rmsd <= best_rmsd[top_ctr] ) {
			    
		    chunk = no_top_rmsd - top_ctr -1;

		    if (chunk) {
			memmove (best_rmsd+top_ctr+1, best_rmsd+top_ctr, chunk*sizeof(double)); 
			memmove (best_quat[top_ctr+1],
				 best_quat[top_ctr], chunk*4*sizeof(double)); 
			memmove (best_triple_x[top_ctr+1],
				 best_triple_x[top_ctr], chunk*3*sizeof(int)); 
			memmove (best_triple_y[top_ctr+1],
				 best_triple_y[top_ctr], chunk*3*sizeof(int)); 
		    }
		    best_rmsd[top_ctr] = rmsd;
		    memcpy (best_quat[top_ctr], q_init, 4*sizeof(double)); 
		    memcpy (best_triple_x[top_ctr], x_triple, 3*sizeof(int)); 
		    memcpy (best_triple_y[top_ctr], y_triple, 3*sizeof(int)); 
		    break;
		}
	    }
	    
	}
    }

# if 0
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	if ( best_rmsd[top_ctr] > BAD_RMSD ) break;
	printf (" %3d %8.3lf   ", top_ctr,  best_rmsd[top_ctr]);
	vec_out ( best_quat[top_ctr], 4, "quat: ");
	for (t=0; t<3; t++ ) {
	    printf ("\t %3d  %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 );
	}
    }
    exit (1);
# endif

    /*********************************************/
    /*   main loop                               */
    /*********************************************/
    for (top_ctr=0; top_ctr<no_top_rmsd; top_ctr++) {
	
	if ( best_rmsd[top_ctr] > BAD_RMSD ) break;

	quat_to_R (best_quat[top_ctr], R);
	rotate (x_rotated, NX, R, x);


	F_current = F( y, y_type, NY, x_rotated, x_type, NX, alpha);

# if 0	
	printf ("\n***********************************\n");
	printf (" %3d %8.3lf  %8.3lf   ", top_ctr,  best_rmsd[top_ctr], F_current);
	vec_out ( best_quat[top_ctr], 4, "quat: ");
	for (t=0; t<3; t++ ) {
	    printf ("\t %3d  %3d \n", best_triple_x[top_ctr][t]+1, best_triple_y[top_ctr][t]+1 );
	}
# endif
	/* find map which uses the 2 triples as anchors */
	no_anchors = 3;
	find_map (&penalty_params, X_rep, Y_rep, R, alpha, &F_effective, map + (*map_ctr),
		   best_triple_x[top_ctr], best_triple_y[top_ctr], no_anchors);

	x2y = ( map + (*map_ctr) ) ->x2y;
	map_unstable  = 0;
	for (t=0; t<3; t++ ) {
	    if ( x2y[best_triple_x[top_ctr][t]] != best_triple_y[top_ctr][t] ) {
		map_unstable = 1;
	    }
	}
	if ( map_unstable) continue;
	
	/* dna here is not DNA but "distance of nearest approach" */
	cull_by_dna ( X_rep, best_triple_x[top_ctr], 
		      Y_rep, best_triple_y[top_ctr],  3,  map + (*map_ctr), cutoff_rmsd );
	
	//printf ("map after culling by dna:\n");
	//print_map (stdout, map+ (*map_ctr), NULL, NULL,  NULL, NULL, 1);

	/* monte that optimizes the aligned vectors only */
	for (i=0; i<NX; i++) {
	     x_type_fudg[i] = JACKFRUIT;
	}
	for (j=0; j<NY; j++) {
	     y_type_fudg[j] = JACKFRUIT*2;
	}

	no_anchors = 0;

	for (i=0; i<NX; i++) {
	     j = (map+(*map_ctr))->x2y[i];
	     if (j < 0 ) continue;
	     x_type_fudg[i] = x_type[i];
	     y_type_fudg[j] = y_type[j];
	     anchor_x[no_anchors] = i;
	     anchor_y[no_anchors] = j;
	     no_anchors ++;
	}


	if ( opt_quat ( x,  NX, anchor_x, y, NY, anchor_y, no_anchors, q, &rmsd)) continue;
	
	retval = monte_carlo ( alpha,  x, x_type_fudg, NX,
			       y,  y_type_fudg, NY, q, &F_current);
	if (retval) return retval;

	
	if (options.postprocess) {
	    z_scr = stdev ? (F_current - avg)/stdev : 0.0;
	} else {
	    z_scr =  0.0;
	}
	quat_to_R (q, R);
	/* store_image() is waste of time, but perhaps not critical */
	store_image (X_rep, Y_rep, R,  alpha, map + (*map_ctr));
	map_assigned_score ( X_rep, map + (*map_ctr));

	//printf ("map  %2d  assigned score:   %8.3lf      z_score: %8.3lf \n\n",
	//	*map_ctr+1, (map + (*map_ctr)) -> assigned_score, z_scr);


        /*   store the map that passed all the filters down to here*/
	my_map_ctr = *map_ctr;


	map[my_map_ctr].F       = F_current;
	map[my_map_ctr].avg     = avg;
	map[my_map_ctr].avg_sq  = avg_sq;
	map[my_map_ctr].z_score = z_scr;
	memcpy ( map[my_map_ctr].q, q, 4*sizeof(double) );
		
	/* recalculate the assigned score*/

	
	//if (top_ctr==24) exit (1);

	/************************/
	/* store sorted         */
	/************************/
	/* find the place for the new z-score */
	store_sorted (map, NX, NY, map_best, map_max,
		      z_best, best_ctr, -map[my_map_ctr].assigned_score, my_map_ctr, &stored_new);

	if ( stored_new ) { /* we want to keep this map */
	    (*map_ctr) ++;
	    best_ctr++;
	} /* otherwise this map space is reusable */
	    

	/* is this pretty much as good as it can get ? */
	if ( fabs (map[my_map_ctr].assigned_score - smaller)
	     < options.tol )  done = 1;


    }
    map_best[best_ctr] = -1;
  
    
    /******************************************************/
    /* look for the sub-map of a couple of best hits      */
    /******************************************************/
    /* initialization:*/
    
    map_consistence ( NX, NY, NULL, NULL, NULL, NULL, NULL); 
    
    best_ctr = 0;
    while (  map_best[best_ctr] >  -1 ) {
	best_ctr ++;
    }

    //exit (1);
    
    if (best_ctr) {
	int nr_maps = (best_ctr<options.number_maps_cpl)?
	    best_ctr : options.number_maps_cpl;
	int best_i;
	int consistent;
	double z;
	double total_assigned_score, score, best_score = -100;
	double gap_score;

	for (i=0; i<nr_maps; i++) { /* look for the complement */
	    best_i =  map_best[i];
	    
	    /*intialize the (list of) submatch map(s) */
	    if ( !map[best_i].submatch_best) {
		/* for now look for a single map only */
		/* TODO - would it be worth any to look at more maps?*/ 
		int map_max = 1;
		map[best_i].submatch_best = emalloc (map_max*sizeof(int) );
		if (! map[best_i].submatch_best) return 1;
	    }
	    map[best_i].submatch_best[0]    = -1;
	    map[best_i].score_with_children =  0;
	    map[best_i].compl_z_score       =  0;
	    
	    for (j=0; j<best_ctr; j++) {

		if (i==j) continue;
		
		map_complementarity ( map+best_i, map + map_best[j], &z);
			
		map_consistence ( NX, NY, map+best_i, map + map_best[j],
				  &total_assigned_score, &gap_score, NULL);
		consistent = ( (map+best_i)->assigned_score < total_assigned_score
			       && (map + map_best[j])->assigned_score
			       < total_assigned_score);
		if ( consistent ) {
		    score = total_assigned_score;
		    if (  score > best_score ) {
			best_score = score;
			map[best_i].submatch_best[0] = map_best[j];
			map[best_i].score_with_children = total_assigned_score;
			map[best_i].compl_z_score = z;
		    }
		}
	    }

	}
    }
    
    /**********************/
    /* garbage collection */
    gradient_descent (1, 0.0,  NULL, NULL, 0,
			       NULL, NULL, 0, NULL, NULL);
    free_dmatrix (R);
    free_dmatrix (x_rotated);
    free_dmatrix (tr_x_rotated);
    free_dmatrix (best_quat);
    free_imatrix (best_triple_x);
    free_imatrix (best_triple_y);
    free (z_best);
    free (x_type_fudg);
    free (y_type_fudg);
    free (anchor_x);
    free (anchor_y);
     
    if (penalty_params.custom_gap_penalty_x) free (penalty_params.custom_gap_penalty_x);
    if (penalty_params.custom_gap_penalty_y) free (penalty_params.custom_gap_penalty_y);
    /*********************/
    
    return 0;
}
int main()
{
    #ifdef __WIN__
        system("chcp 65001");
    #endif // __WIN__
    srand (time(NULL));
    INIReader reader("config.ini");

    if (reader.ParseError() < 0) {
        printf("Can't load 'config.ini'\n");
        return 1;
    }

    int N = 1000;
    int M = 5000;

    int z;
    bool A, P, T;
    z = reader.GetInteger("analytical", "z", 0);
    if (z)
    {
        double l = reader.GetReal("analytical", "l", 0.001);
        double ecut = reader.GetReal("analytical", "ecut", 400);
        analytical(z, M, N, l, ecut);
        A = true;
    }

    z = reader.GetInteger("table", "z", 0);
    if (z)
    {
        double l = reader.GetReal("table", "l", 0.001);
        double ecut = reader.GetReal("table", "ecut", 400);
        table(z, M, N, l, ecut);
        T = true;
    }

    z = reader.GetInteger("approximation", "z", 0);
    if (z)
    {
        double l = reader.GetReal("approximation", "l", 0.001);
        double ecut = reader.GetReal("approximation", "ecut", 400);
        approximation(z, M, N, l, ecut);
        P = true;
    }

    z = reader.GetInteger("monte-carlo", "z", 0);
    if (z)
    {
        double l = reader.GetReal("monte-carlo", "l", 0.00001);
        double s = reader.GetReal("monte-carlo", "s", 0.0001);
        double ecut = reader.GetReal("monte-carlo", "ecut", 10);
        int nparticles = reader.GetInteger("monte-carlo", "particles", 400);
        int ntimes = reader.GetInteger("monte-carlo", "times", 400);
        int N = 100;
        monte_carlo(z, nparticles, ntimes, N, ecut, s, l);
        plot_mc();
    }

    plot_analytics(A, P, T);
    return 0;
}