void GeneticAlgorithm::run_optimization(std::vector<exp_signal> const& signals_exp, Spin const& spinA, Spin const& spinB, std::vector<int> const& param_numbers, std::vector<int> const& param_modes, std::vector<bound> const& param_bounds, genetic_parameters const& genetic_param, output_parameters const& output_param) const { // Initialize the calculator of PELDOR signals PeldorCalculator* peldor_calc = new PeldorCalculator(genetic_param.num_avg); peldor_calc->calculate_spinA_excitation(signals_exp, spinA); // Calculate the spectrum of the spin system if (output_param.record_spectrum) { std::cout << " Recording the spectrum... "; peldor_calc->save_spectrum(signals_exp, spinA, spinB, output_param); std::cout << "Done!" << std::endl; } // Start optimization int n = 1; std::cout << " Optimization step " << n << "/" << genetic_param.num_generations_max << std::endl; // Create a first generation Generation* generation = new Generation(genetic_param); generation->create_initial_generation(param_bounds, genetic_param); // Score first generation generation->score_chromosomes(*peldor_calc, signals_exp, spinA, spinB, param_numbers, param_modes, genetic_param); generation->sort_chromosomes(); std::vector<double> best_fitness; best_fitness.reserve(genetic_param.num_generations_max); best_fitness.push_back(generation->chromosomes[0].fitness); // Proceed with next generations for (int n = 2; n <= genetic_param.num_generations_max; ++n) { // loop over generations std::cout << " Optimization step " << n << "/" << genetic_param.num_generations_max << std::endl; // Create next generation generation->produce_offspring(genetic_param, param_bounds); // Score the generation generation->score_chromosomes(*peldor_calc, signals_exp, spinA, spinB, param_numbers, param_modes, genetic_param); generation->sort_chromosomes(); best_fitness.push_back(generation->chromosomes[0].fitness); } // Save the fitness of the best chromosome if (output_param.record_score) { std::cout << " Recording the fitness vs the number of optimization steps... "; record_score(best_fitness, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Save the calculated fit to the PELDOR signals for the best chromosome if (output_param.record_fit) { std::cout << " Recording the fit to the PELDOR signals... "; record_fit(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Save the genes of the best chromosome if (output_param.record_parameters) { std::cout << " Recording the best values of fitting parameters... "; record_parameters(generation->chromosomes[0], param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Record the calculated for-factors for the PELDOR signals if (output_param.record_form_factor) { std::cout << " Recording the form-factors of PELDOR signals... "; record_form_factor(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, output_param); std::cout << "Done!" << std::endl; } // Record the symmetry-related sets of fitting parameters if (output_param.record_symmetric_solutions) { std::cout << " Recording the symmetry-related sets of fitting parameters... "; record_symmetric_parameters(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, param_bounds, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Record the error plots if (output_param.record_error_plot) { std::cout << " Recording the error plot... "; record_error_plot(*peldor_calc, generation->chromosomes[0], signals_exp, spinA, spinB, param_numbers, param_modes, param_bounds, genetic_param, output_param); std::cout << "Done!" << std::endl; } // Clean up delete peldor_calc; delete generation; }