boolean fitting_score(population *pop, entity *entity) { int i; /* Loop variable over training points. */ double score=0.0; /* Mean of squared deviations. */ char * params; double params_d[4]; /* Fitting parameters. */ fitting_data_t *data; /* Training data. */ double E,R,L,C; entity->fitness = 0; data = (fitting_data_t *)pop->data; params = (char *)entity->chromosome[0]; chromo_translator(params, params_d); E = params_d[0]; R = params_d[1]; L = params_d[2]; C = params_d[3]; for (i=0; i<data->size; i++) { if(score > 10000000) { score = 10000000; break; } score += SQU(data->y[i]-(target_function(data->x[i], params_d))); } entity->fitness = -sqrt(score / data->size); return TRUE; }
static gpointer replacement_target_function (GString * str) { gpointer result; g_string_append_c (str, '/'); result = target_function (str); g_string_append_c (str, '\\'); return result; }
template <class FT> int Pruner<FT>::nelder_mead_step(/*io*/ vec &b) { int dn = b.size(); int l = dn + 1; evec tmp_constructor(dn); vector<evec> bs(l); // The simplexe (d+1) vector of dim d FT *fs = new FT[l]; // Values of f at the simplex vertices for (int i = 0; i < l; ++i) // Intialize the simplex { bs[i] = b; // Start from b if (i < dn) { bs[i][i] += (bs[i][i] < .5) ? ND_INIT_WIDTH : -ND_INIT_WIDTH; } enforce(bs[i]); fs[i] = target_function(bs[i]); // initialize the value } FT init_cf = fs[l - 1]; vec bo(dn); // centeroid FT fo; // value at the centroid FT fs_maxi_last = fs[0]; // value of the last centroid if (verbosity) { cerr << " Starting nelder_mead cf = " << init_cf << " proba = " << measure_metric(b) << endl; } unsigned int counter = 0; int mini = 0, maxi = 0, maxi2 = 0; while (1) // Main loop { mini = maxi = maxi2 = 0; for (int i = 0; i < dn; ++i) bo[i] = bs[0][i]; //////////////// // step 1. and 2. : Order and centroid //////////////// for (int i = 1; i < l; ++i) // determine min and max, and centroid { mini = (fs[i] < fs[mini]) ? i : mini; maxi = (fs[i] > fs[mini]) ? i : maxi; for (int j = 0; j < dn; ++j) { bo[j] += bs[i][j]; } } FT tmp; tmp = l; for (int i = 0; i < dn; ++i) bo[i] /= tmp; // Centroid calculated fs_maxi_last = (!counter) ? fs[maxi] : fs_maxi_last; // determine min and max, and centroid maxi2 += (!maxi); for (int i = 1; i < l; ++i) { maxi2 = ((fs[i] > fs[maxi2]) && (i != maxi)) ? i : maxi2; } if (enforce(bo)) // Maybe want to skip this test, that may be kinda costly. { throw std::runtime_error("Concavity says that should not happen."); } if (verbosity) // Not sure such verbosity is now of any use { cerr << " melder_mead step " << counter << "cf = " << fs[mini] << " proba = " << measure_metric(bs[mini]) << " cost = " << single_enum_cost(bs[mini]) << endl; for (int i = 0; i < dn; ++i) { cerr << ceil(bs[mini][i].get_d() * 1000) << " "; } cerr << endl; } //////////////// // Stopping condition (Not documented on wikipedia, improvising) // I'm not satistifed by it anymore. Exploration needed. //////////////// counter++; if (!(counter % l)) // Every l steps, we check progress and stop if none is done { if (fs[maxi] > fs_maxi_last * min_cf_decrease) { break; } fs_maxi_last = fs[maxi]; } for (int i = 0; i < l; ++i) // determine second best { if ((fs[i] > fs[maxi2]) && (i != maxi)) maxi2 = i; } if (verbosity) { cerr << mini << " " << maxi2 << " " << maxi << endl; cerr << fs[mini] << " < " << fs[maxi2] << " < " << fs[maxi] << " | " << endl; } //////////////// // step 3. Reflection //////////////// vec br(dn); // reflected point FT fr; // Value at the reflexion point for (int i = 0; i < dn; ++i) br[i] = bo[i] + ND_ALPHA * (bo[i] - bs[maxi][i]); enforce(br); fr = target_function(br); if (verbosity) { cerr << "fr " << fr << endl; } if ((fs[mini] <= fr) && (fr < fs[maxi2])) { bs[maxi] = br; fs[maxi] = fr; if (verbosity) { cerr << " Reflection " << endl; } continue; // Go to step 1. } //////////////// // step 4. Expansion //////////////// if (fr < fs[mini]) { vec be(dn); FT fe; for (int i = 0; i < dn; ++i) be[i] = bo[i] + ND_GAMMA * (br[i] - bo[i]); enforce(be); fe = target_function(be); if (verbosity) { cerr << "fe " << fe << endl; } if (fe < fr) { bs[maxi] = be; fs[maxi] = fe; if (verbosity) { cerr << " Expansion A " << endl; } continue; // Go to step 1. } else { bs[maxi] = br; fs[maxi] = fr; if (verbosity) { cerr << " Expansion B " << endl; } continue; // Go to step 1. } } //////////////// // step 5. Contraction //////////////// if (!(fr >= fs[maxi2])) // Here, it is certain that fr >= fs[maxi2] { throw std::runtime_error("Something certain is false in Nelder-Mead."); } vec bc(dn); FT fc; for (int i = 0; i < dn; ++i) bc[i] = bo[i] + ND_RHO * (bs[maxi][i] - bo[i]); enforce(bc); fc = target_function(bc); if (verbosity) { cerr << "fc " << fc << endl; } if (fc < fs[maxi]) { bs[maxi] = bc; fs[maxi] = fc; if (verbosity) { cerr << " Contraction " << endl; } continue; // Go to step 1. } //////////////// // step 6. Shrink //////////////// if (verbosity) { cerr << " Shrink " << endl; } for (int j = 0; j < l; ++j) { for (int i = 0; i < dn; ++i) { bs[j][i] = bs[mini][i] + ND_SIGMA * (bs[j][i] - bs[mini][i]); } enforce(bs[j]); fs[j] = target_function(bs[j]); // initialize the value } } b = bs[mini]; int improved = (init_cf * min_cf_decrease) > fs[mini]; if (verbosity) { cerr << "Done nelder_mead, after " << counter << " steps" << endl; cerr << "Final cf = " << fs[mini] << " proba = " << measure_metric(b) << endl; if (improved) { cerr << "Progress has been made: init cf = " << init_cf << endl; } cerr << endl; } return improved; // Has MN made any progress }
/** * One gradient descent step */ template <class FT> int Pruner<FT>::gradient_descent_step(/*io*/ vec &b) { int dn = b.size(); FT cf = target_function(b); FT old_cf = cf; vec new_b(dn); vector<double> pr(dn); vec gradient(dn); target_function_gradient(b, gradient); FT norm = 0.0; // normalize the gradient for (int i = 0; i < dn; ++i) { norm += gradient[i] * gradient[i]; new_b[i] = b[i]; } if (verbosity) { cerr << " Gradient descent step starts at cf=" << cf << endl; } norm /= (double)dn; norm = sqrt(norm); if (verbosity) { cerr << " Gradient norm " << norm << endl; } if (norm <= 0.) return 0; for (int i = 0; i < dn; ++i) { gradient[i] /= norm; } FT new_cf; FT step = min_step; int j; for (j = 0;; ++j) { if (step > dn) { return -1; // throw std::runtime_error("Infinite loop in pruner gradient_descent_step"); } for (int i = 0; i < dn; ++i) { new_b[i] = new_b[i] + step * gradient[i]; } enforce(new_b); new_cf = target_function(new_b); if (new_cf >= cf) { break; } b = new_b; cf = new_cf; step *= step_factor; } if (verbosity) { cerr << " Gradient descent step ends after " << j << " mini-steps at cf=" << cf << endl; } if (cf > old_cf * min_cf_decrease) { return 0; } return j; }
void Pruner<FT>::optimize_coefficients_local_adjust_incr_prob(/*io*/ vector<double> &pr) { int trials, tours, maxi, ind; FT old_cf, old_cf0, old_cfs, new_cf, old_b; double current_max; vector<double> detailed_cost(n); vector<double> slices(n, 10.0); // (b[i+1] - b[i])/slice will be used as step vec b(n); load_coefficients(b, pr); // initial cost old_cf0 = target_function(b); tours = 0; while (1) { tours++; // old cost old_cf = target_function(b); // find bottleneck index old_cfs = single_enum_cost(b, &(detailed_cost)); current_max = 0.0; maxi = 0; for (int i = 0; i < n; i++) { if (detailed_cost[i] > current_max) { current_max = detailed_cost[i]; maxi = i; } } ind = n - maxi - 1; if (ind <= 1) break; #ifdef BALANCE_HEURISTIC_PRUNER_OPTIMIZE if (old_cfs > sqrt(old_cf) / 10.0) break; #endif for (int i = ind; i >= 1; --i) { if (b[i] <= b[i - 1]) continue; trials = 0; // fixed i-1, trying to increase b[i-1] while (1) { // old cost old_cf = target_function(b); // try increase old_b = b[i - 1]; b[i - 1] = b[i - 1] + (b[i] - b[i - 1]) / slices[i - 1]; // new cost new_cf = target_function(b); // cerr << " i = " << i << " old_cf = " << old_cf << " new_cf = " << // new_cf << endl; // if not improved -- recover if (new_cf >= (old_cf * 1.2)) { b[i - 1] = old_b; break; } else { if (slices[i - 1] < 1024) slices[i - 1] = slices[i - 1] * 1.2; } trials++; if (trials >= 10) break; } } new_cf = target_function(b); if (new_cf > (old_cf0 * 1.1) || tours > 4) break; } #ifdef DEBUG_PRUNER_OPTIMIZE_TC cerr << "# [TuningProb]" << endl; cerr << b << endl; cerr << "# [TuningProb] all_enum_cost = " << repeated_enum_cost(b) << endl; cerr << "# [TuningProb] succ_probability = " << measure_metric(b) << endl; #endif save_coefficients(pr, b); }
void Pruner<FT>::optimize_coefficients_local_adjust_decr_single(/*io*/ vector<double> &pr) { int maxi, lasti, consecutive_fails; double improved_ratio, current_max = 0.0; FT old_cf, old_cfs, new_cf, old_b; vector<double> detailed_cost(n); vector<double> slices(n, 10.0); // (b[i+1] - b[i])/slice will be used as step vector<int> thresholds(n, 3); vec b(n); load_coefficients(b, pr); lasti = -1; // last failed index, make sure we do not try it again in // the next time consecutive_fails = 0; // number of consecutive failes; break if // reaches it improved_ratio = 0.995; // if reduced by 0.995, descent while (1) { // old cost old_cf = target_function(b); // find bottleneck index old_cfs = single_enum_cost(b, &(detailed_cost)); // heuristic #ifdef BALANCE_HEURISTIC_PRUNER_OPTIMIZE if (old_cfs < sqrt(old_cf) / 10.0) break; #endif current_max = 0.0; maxi = 0; for (int i = 0; i < n; i++) { if ((i != (n - lasti - 1)) && (thresholds[n - i - 1] > 0)) { if (detailed_cost[i] > current_max) { current_max = detailed_cost[i]; maxi = i; } } } // b[ind] is the one to be reduced int ind = n - maxi - 1; old_b = b[ind]; if (ind != 0) { b[ind] = b[ind] - (b[ind] - b[ind - 1]) / slices[ind]; } else { break; } // new cost new_cf = target_function(b); // if not improved -- recover if (new_cf >= (old_cf * improved_ratio)) { b[ind] = old_b; lasti = ind; thresholds[lasti]--; consecutive_fails++; } else { // cerr << " improved from " << old_cf << " to " << new_cf << endl; if (slices[ind] < 1024) slices[ind] = slices[ind] * 1.05; consecutive_fails = 0; } // quit after 10 consecutive failes if (consecutive_fails > 10) { break; } } #ifdef DEBUG_PRUNER_OPTIMIZE_TC cerr << "# [TuningCost]" << endl; cerr << b << endl; cerr << "# [TuningCost] all_enum_cost = " << repeated_enum_cost(b) << endl; cerr << "# [TuningCost] succ_probability = " << measure_metric(b) << endl; #endif save_coefficients(pr, b); }
int main(int argc, char **argv) { population *pop; /* Population of solutions. */ fitting_data_t data; /* Training data. */ FILE * fData; random_seed(time(NULL)); double params_d[4]; double x; // fitting if(argc >= 3 && strcmp(argv[1], "fit") == 0) { pop = ga_genesis_char( 100, /* const int population_size */ 1, /* const int num_chromo */ 3, /* const int len_chromo */ fitting_generation_callback, /* GAgeneration_hook generation_hook */ NULL, /* GAiteration_hook iteration_hook */ NULL, /* GAdata_destructor data_destructor */ NULL, /* GAdata_ref_incrementor data_ref_incrementor */ fitting_score, /* GAevaluate evaluate */ //fitting_seed, /* GAseed seed */ ga_seed_char_random, NULL, /* GAadapt adapt */ //ga_select_one_linearrank, ga_select_one_random, /* GAselect_one select_one */ ga_select_two_random, /* GAselect_two select_two */ ga_mutate_char_singlepoint_randomize,/* GAmutate mutate */ ga_crossover_char_allele_mixing,/* GAcrossover crossover */ NULL, /* GAreplace replace */ NULL /* vpointer User data */ ); ga_population_set_parameters( pop, /* population *pop */ GA_SCHEME_DARWIN, /* const ga_scheme_type scheme */ GA_ELITISM_PARENTS_DIE, /* const ga_elitism_type elitism */ 0.8, /* double crossover */ 0.8, /* double mutation */ 0.0 /* double migration */ ); fData = fopen("data", "r"); debug_message("Begin Get Data\n"); get_data(fData, &data); pop->data = &data; debug_message("Done Get Data\n"); debug_message("Begin Evolution\n"); ga_evolution( pop, /* population *pop */ 200 /* const int max_generations */ ); debug_message("Done Evolution\n"); ga_extinction(pop); } // plot else if(argc >= 5 && strcmp(argv[1], "plot")==0) { params_d[0] = E_GIVEN; params_d[1] = atof(argv[2]); params_d[2] = atof(argv[3]); params_d[3] = atof(argv[4]); for(x = 0; x < 10; x += 0.01) { fprintf(stdout, "%lf %lf\n", x, target_function(x, params_d)); } } else { fprintf(stdout, "usage: %s [plot/fit] [params]\n", argv[0]); } }