static double best_fit(args_t *args, dist_t *dist, int ngauss, double *params) { if ( ngauss==1 ) { gauss_fit(dist,ngauss,params); params[1] *= params[1]; return eval_fit(dist->dat.nvals, dist->dat.xvals, dist->dat.yvals, ngauss,params); } int i, j, n = 3; int ipk = 3*(ngauss-1); double delta = 0.5 * (params[ipk] - params[0]) / n; double best_params[9], tmp_params[9], best_fit = HUGE_VAL; for (i=0; i<n; i++) { memcpy(tmp_params,params,sizeof(double)*ngauss*3); tmp_params[0] += delta*i; tmp_params[ipk] -= delta*i; if ( gauss_fit(dist,ngauss,tmp_params)<0 ) continue; // did not converge for (j=0; j<ngauss; j++) tmp_params[j*3+1] *= tmp_params[j*3+1]; // From the nature of the data, we can assume that in presence of // multiple peaks they will be placed symmetrically around 0.5. Also // their size should be about the same. We evaluate the fit with this // in mind. double dx = fabs(0.5 - tmp_params[0]) + fabs(tmp_params[ipk] - 0.5); tmp_params[0] = 0.5 - dx*0.5; tmp_params[ipk] = 0.5 + dx*0.5; double fit = eval_fit(dist->dat.nvals, dist->dat.xvals, dist->dat.yvals, ngauss, tmp_params); if ( best_fit < fit ) continue; // worse than previous best_fit = fit; memcpy(best_params,tmp_params,sizeof(double)*ngauss*3); } memcpy(params,best_params,sizeof(double)*ngauss*3); return best_fit; }
/** * GA with a single fitness function */ int evolve_both(int* first, int* second, int* winner, int* loser, int* population) { int round = 0; float fitness_first, fitness_second; int first_bitflipped[GENOTYPE_LENGTH], second_bitflipped[GENOTYPE_LENGTH]; do { round++; // generate the complementary individuals bitflip(first, first_bitflipped); bitflip(second, second_bitflipped); // mark them as tested in the population population[hash(first)] = 1; population[hash(second)] = 1; // evaluate first and its complementary fitness_first = eval_fit(first, first_bitflipped); // evaluate second fitness_second = eval_fit(second, second_bitflipped); // optimal solution? if ( fitness_first == 0.0 ) { copy_individual(first, winner); copy_individual(second, loser); break; } if ( fitness_second == 0.0 ) { copy_individual(second, winner); copy_individual(first, loser); break; } if ( fitness_first < fitness_second ) { // first wins // mutate loser if ( mutate_1gene(second, population) < 0 ) { // if no more mutations are possible copy_individual(first, winner); copy_individual(second, loser); break; } } else { // second wins // mutate loser if ( mutate_1gene(first, population) < 0 ) { copy_individual(second, winner); copy_individual(first, loser); break; } } } while ( 1 ); return round; }