double _ConstOptimizer::do_optimize(unsigned int n) { for (unsigned int i = 0; i < n; ++i) { get_scoring_function()->evaluate(false); update_states(); } return get_scoring_function()->evaluate(false); }
double MonteCarlo::do_optimize(unsigned int max_steps) { IMP_OBJECT_LOG; IMP_CHECK_OBJECT(this); if (get_number_of_movers() == 0) { IMP_THROW("Running MonteCarlo without providing any" << " movers isn't very useful.", ValueException); } ParticleIndexes movable = get_movable_particles(); // provide a way of feeding in this value last_energy_ = do_evaluate(movable); if (return_best_) { best_ = new Configuration(get_model()); best_energy_ = last_energy_; } reset_statistics(); update_states(); IMP_LOG_TERSE("MC Initial energy is " << last_energy_ << std::endl); for (unsigned int i = 0; i < max_steps; ++i) { if (get_stop_on_good_score() && get_scoring_function()->get_had_good_score()) { break; } do_step(); if (best_energy_ < get_score_threshold()) break; } IMP_LOG_TERSE("MC Final energy is " << last_energy_ << std::endl); if (return_best_) { // std::cout << "Final score is " << get_model()->evaluate(false) //<< std::endl; best_->swap_configuration(); IMP_LOG_TERSE("MC Returning energy " << best_energy_ << std::endl); IMP_IF_CHECK(USAGE) { IMP_LOG_TERSE("MC Got " << do_evaluate(get_movable_particles()) << std::endl); /*IMP_INTERNAL_CHECK((e >= std::numeric_limits<double>::max() && best_energy_ >= std::numeric_limits<double>::max()) || std::abs(best_energy_ - e) < .01+.1* std::abs(best_energy_ +e), "Energies do not match " << best_energy_ << " vs " << e << std::endl);*/ } return do_evaluate(movable); } else { return last_energy_;
double GSLOptimizer::optimize(unsigned int iter, const gsl_multimin_fminimizer_type*t, double ms, double mxs) { fis_= get_optimized_attributes(); best_score_=std::numeric_limits<double>::max(); unsigned int n= get_dimension(); if (n ==0) { IMP_LOG(TERSE, "Nothing to optimize" << std::endl); return get_scoring_function()->evaluate(false); } gsl_multimin_fminimizer *s=gsl_multimin_fminimizer_alloc (t, n); gsl_vector *x= gsl_vector_alloc(get_dimension()); update_state(x); gsl_vector *ss= gsl_vector_alloc(get_dimension()); gsl_vector_set_all(ss, mxs); gsl_multimin_function f= internal::create_f_function_data(this); gsl_multimin_fminimizer_set (s, &f, x, ss); try { int status; do { --iter; //update_state(x); status = gsl_multimin_fminimizer_iterate(s); if (status) { IMP_LOG(TERSE, "Ending optimization because of state " << s << std::endl); break; } double sz= gsl_multimin_fminimizer_size(s); status= gsl_multimin_test_size(sz, ms); update_states(); if (status == GSL_SUCCESS) { IMP_LOG(TERSE, "Ending optimization because of small size " << sz << std::endl); break; } } while (status == GSL_CONTINUE && iter >0); } catch (AllDone){ } gsl_vector *ret=gsl_multimin_fminimizer_x (s); best_score_=gsl_multimin_fminimizer_minimum (s); write_state(ret); gsl_multimin_fminimizer_free (s); gsl_vector_free (x); return best_score_; }
bool MonteCarlo::do_accept_or_reject_move(double score, double last, double proposal_ratio) { bool ok = false; if (score < last) { ++stat_downward_steps_taken_; ok = true; if (score < best_energy_ && return_best_) { best_ = new Configuration(get_model()); best_energy_ = score; } } else { double diff = score - last; double e = std::exp(-diff / temp_); double r = rand_(random_number_generator); IMP_LOG_VERBOSE(diff << " " << temp_ << " " << e << " " << r << std::endl); if (e * proposal_ratio > r) { ++stat_upward_steps_taken_; ok = true; } else { ok = false; } } if (ok) { IMP_LOG_TERSE("Accept: " << score << " previous score was " << last << std::endl); last_energy_ = score; update_states(); for (int i = get_number_of_movers() - 1; i >= 0; --i) { get_mover(i)->accept(); } return true; } else { IMP_LOG_TERSE("Reject: " << score << " current score stays " << last << std::endl); for (int i = get_number_of_movers() - 1; i >= 0; --i) { get_mover(i)->reject(); } ++stat_num_failures_; if (isf_) { isf_->reset_moved_particles(); } return false; } }
double Simulator::do_simulate(double time) { IMP_FUNCTION_LOG; set_was_used(true); ParticleIndexes ps = get_simulation_particle_indexes(); setup(ps); double target = current_time_ + time; boost::scoped_ptr<boost::progress_display> pgs; if (get_log_level() == PROGRESS) { pgs.reset(new boost::progress_display(time / max_time_step_)); } while (current_time_ < target) { last_time_step_ = do_step(ps, max_time_step_); current_time_ += last_time_step_; update_states(); if (get_log_level() == PROGRESS) { ++(*pgs); } } return Optimizer::get_scoring_function()->evaluate(false); }
void calc_jacobian(MeshCTX* meshctx, PropCTX* propctx) { int myid = propctx->myid, numprocs = propctx->numproc; HashTable* El_Table = meshctx->el_table; HashTable* NodeTable = meshctx->nd_table; TimeProps* timeprops_ptr = propctx->timeprops; MapNames* mapname_ptr = propctx->mapnames; MatProps* matprops_ptr = propctx->matprops; HashEntryPtr* buck = El_Table->getbucketptr(); HashEntryPtr currentPtr; DualElem* Curr_El = NULL; int iter = timeprops_ptr->iter; double tiny = GEOFLOW_TINY; #ifdef DEBUGFILE ofstream myfile; myfile.open("debug.txt",ios::app); #endif for (int i = 0; i < El_Table->get_no_of_buckets(); i++) { if (*(buck + i)) { currentPtr = *(buck + i); while (currentPtr) { Curr_El = (DualElem*) (currentPtr->value); if (Curr_El->get_adapted_flag() > 0) { double *prev_state_vars = Curr_El->get_prev_state_vars(); double *state_vars = Curr_El->get_state_vars(); double *d_state_vars = Curr_El->get_d_state_vars(); double *gravity = Curr_El->get_gravity(); double *d_gravity = Curr_El->get_d_gravity(); double *curvature = Curr_El->get_curvature(); Curr_El->calc_stop_crit(matprops_ptr); //this function updates bedfric properties double bedfrict = Curr_El->get_effect_bedfrict(); double *dx = Curr_El->get_dx(); if (timeprops_ptr->iter < 51) matprops_ptr->frict_tiny = 0.1; else matprops_ptr->frict_tiny = 0.000000001; double flux[4][NUM_STATE_VARS]; get_flux(El_Table, NodeTable, Curr_El->pass_key(), matprops_ptr, myid, flux); double dt = timeprops_ptr->dt.at(iter - 1); //at final time step we do not need the computation of adjoint and we always compute it for the previouse time so we need iter. double dtdx = dt / dx[0]; double dtdy = dt / dx[1]; int stop[DIMENSION] = { 0, 0 }; double orgSrcSgn[4] = { 0., 0., 0., 0. }; update_states(state_vars, prev_state_vars, flux[0], flux[1], flux[2], flux[3], dtdx, dtdy, dt, d_state_vars, (d_state_vars + NUM_STATE_VARS), curvature, matprops_ptr->intfrict, bedfrict, gravity, d_gravity, *(Curr_El->get_kactxy()), matprops_ptr->frict_tiny, stop, orgSrcSgn); Vec_Mat<9>& jacobian = Curr_El->get_jacobian(); for (int effelement = 0; effelement < EFF_ELL; effelement++) { //0 for the element itself, and the rest id for neighbour elements #ifdef DEBUG char filename[] = "jacobian"; int bb = 1, aa = 0; if (fabs(*(Curr_El->get_coord()) - 161.3) < .04 && fabs(*(Curr_El->get_coord() + 1) - 539.58) < .04 && (iter == 545 || iter == 546)) bb = aa; /*Curr_El->get_ithelem() == 8255 && effelement == 0) {/**(Curr_El->pass_key()) == KEY0 && *(Curr_El->pass_key() + 1) == KEY1 && iter == ITER && effelement == EFFELL Curr_El->write_elem_info(NodeTable, filename, timeprops_ptr->iter, dt);*/ #endif if ((effelement == 0 && prev_state_vars[0] == 0.) || //this is a void element so the residual vector does not change by changing it's values (effelement > 4 && *(Curr_El->get_neigh_proc() + (effelement - 1)) == -2) || //one neighbor in this side (effelement != 0 && void_neigh_elem(El_Table, Curr_El, effelement)) || //this is a void neighbor element so the residual of the curr_el does not depend on this neighbor (effelement > 0 && *(Curr_El->get_neigh_proc() + (effelement - 1)) == INIT)) { Curr_El->set_jacobianMat_zero(effelement); } else { const Mat3x3 *jac_flux_n_x, *jac_flux_p_x, *jac_flux_n_y, *jac_flux_p_y; double dh_sens[2]; set_fluxes_hsens(Curr_El, jac_flux_n_x, jac_flux_p_x, jac_flux_n_y, jac_flux_p_y, dh_sens, effelement); calc_jacobian_elem(jacobian(effelement), *jac_flux_n_x, *jac_flux_p_x, *jac_flux_n_y, *jac_flux_p_y, prev_state_vars, d_state_vars, (d_state_vars + NUM_STATE_VARS), curvature, gravity, d_gravity, dh_sens, matprops_ptr->intfrict, bedfrict, *(Curr_El->get_kactxy()), effelement, dtdx, dtdy, dt, stop, orgSrcSgn); } } } currentPtr = currentPtr->next; } } } // cout<<"max jacobian: "<<max_jac<<endl; #ifdef DEBUGFILE myfile.close(); #endif }
double Simulator::do_simulate_wave(double time, double max_time_step_factor, double base) { IMP_FUNCTION_LOG; set_was_used(true); ParticleIndexes ps = get_simulation_particle_indexes(); setup(ps); double target = current_time_ + time; IMP_USAGE_CHECK(max_time_step_factor > 1.0, "simulate wave time step factor must be >1.0"); // build wave into cur_ts double wave_max_ts = max_time_step_factor * max_time_step_; std::vector<double> ts_seq; { int n_half = 2; // subwave length bool max_reached = false; double raw_wave_time = 0.0; do { double cur_ts = max_time_step_; // go up for (int i = 0; i < n_half; i++) { ts_seq.push_back(cur_ts); raw_wave_time += cur_ts; cur_ts *= base; if (cur_ts > wave_max_ts) { max_reached = true; break; } } // go down for (int i = 0; i < n_half; i++) { cur_ts /= base; ts_seq.push_back(cur_ts); raw_wave_time += cur_ts; if (cur_ts < max_time_step_) { break; } } n_half++; } while (!max_reached && raw_wave_time < time); // adjust to fit into time precisely unsigned int n = (unsigned int)std::ceil(time / raw_wave_time); double wave_time = time / n; double adjust = wave_time / raw_wave_time; IMP_LOG(PROGRESS, "Wave time step seq: "); for (unsigned int i = 0; i < ts_seq.size(); i++) { ts_seq[i] *= adjust; IMP_LOG(PROGRESS, ts_seq[i] << ", "); } IMP_LOG(PROGRESS, std::endl); } unsigned int i = 0; unsigned int k = ts_seq.size(); // n waves of k frames int orig_nf_left = (int)(time / max_time_step_); while (current_time_ < target) { last_time_step_ = do_step(ps, ts_seq[i++ % k]); current_time_ += last_time_step_; // emulate state updating by frames for the origin max_time_step // (for periodic optimizers) int nf_left = (int)((target - current_time_) / max_time_step_); while (orig_nf_left >= nf_left) { IMP_LOG(PROGRESS, "Updating states: " << orig_nf_left << "," << nf_left << " target time " << target << " current time " << current_time_ << std::endl); update_states(); // needs to move orig_nf_left--; } } IMP_LOG(PROGRESS, "Simulated for " << i << " actual frames with waves of " << k << " frames each" << std::endl); IMP_USAGE_CHECK(current_time_ >= target - 0.001 * max_time_step_, "simulations did not advance to target time for some reason"); return Optimizer::get_scoring_function()->evaluate(false); }
double SteepestDescent::do_optimize(unsigned int max_steps) { IMP_OBJECT_LOG; Float last_score, new_score = 0.0; // set up the indexes FloatIndexes float_indexes = get_optimized_attributes(); Float current_step_size = step_size_; // ... and space for the old values algebra::VectorKD temp_derivs = algebra::get_zero_vector_kd(float_indexes.size()); algebra::VectorKD temp_values = algebra::get_zero_vector_kd(float_indexes.size()); for (unsigned int step = 0; step < max_steps; step++) { // model.show(std::cout); int cnt = 0; // evaluate the last model state last_score = get_scoring_function()->evaluate(true); IMP_LOG_TERSE("start score: " << last_score << std::endl); // store the old values for (unsigned int i = 0; i < temp_derivs.get_dimension(); i++) { temp_derivs[i] = get_derivative(float_indexes[i]); temp_values[i] = get_value(float_indexes[i]); } bool constant_score = false; while (true) { cnt++; // try new values based on moving down the gradient at the current // step size IMP_LOG_VERBOSE("step: " << temp_derivs * current_step_size << std::endl); for (unsigned int i = 0; i < float_indexes.size(); i++) { set_value(float_indexes[i], temp_values[i] - temp_derivs[i] * current_step_size); } // check the new model new_score = get_scoring_function()->evaluate(false); IMP_LOG_TERSE("last score: " << last_score << " new score: " << new_score << " step size: " << current_step_size << std::endl); // if the score got better, we'll take it if (new_score < last_score) { IMP_LOG_TERSE("Accepting step of size " << current_step_size); update_states(); if (new_score <= threshold_) { IMP_LOG_TERSE("Below threshold, returning." << std::endl); return new_score; } current_step_size = std::min(current_step_size * 1.4, max_step_size_); break; } // if the score is the same, keep going one more time if (std::abs(new_score - last_score) < .0000001) { if (constant_score) { break; } current_step_size *= 0.9; constant_score = true; } else { constant_score = false; current_step_size *= .7; } if (cnt > 200) { // stuck for (unsigned int i = 0; i < float_indexes.size(); i++) { set_value(float_indexes[i], temp_values[i]); } IMP_LOG_TERSE("Unable to find a good step. Returning" << std::endl); return last_score; } if (current_step_size < .00000001) { // here is as good as any place we found update_states(); IMP_LOG_TERSE("Unable to make progress, returning." << std::endl); return new_score; } } } return new_score; }
void Game_Loop::run() { const float interval = 1.0 / target_fps; double time = SDL_GetTicks() / 1000.0; running = true; update_state_stack(); while (running) { double current_time = SDL_GetTicks() / 1000.0; // Failsafe in case updates keep taking more time than interval and the // loop keeps falling back. int max_updates = 16; if (current_time - time >= interval) { while (current_time - time >= interval) { running = update_states(interval); if (!running) break; time += interval; if (max_updates-- <= 0) { // Forget about catching up. time = current_time; break; } } glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); auto dim = get_dim(); glViewport(0, 0, dim[0], dim[1]); for (auto& state : states) state->draw(); SDL_GL_SwapBuffers(); } else { // Don't busy wait. SDL_Delay(10); } SDL_Event event; while (SDL_PollEvent(&event)) { Game_State *top = top_state(); switch (event.type) { case SDL_KEYDOWN: if (top) top->key_event(event.key.keysym.sym, event.key.keysym.unicode); break; case SDL_KEYUP: if (top) top->key_event(-event.key.keysym.sym, -1); break; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: if (top) top->mouse_event(event.button.x, event.button.y, mouse_button_mask()); break; case SDL_MOUSEMOTION: if (top) top->mouse_event(event.motion.x, event.motion.y, mouse_button_mask()); break; case SDL_QUIT: quit(); break; } } } SDL_Quit(); }
Float ConjugateGradients::do_optimize(unsigned int max_steps) { IMP_OBJECT_LOG; IMP_USAGE_CHECK(get_model(), "Must set the model on the optimizer before optimizing"); clear_range_cache(); Vector<NT> x, dx; int i; // ModelData* model_data = get_model()->get_model_data(); FloatIndexes float_indices = get_optimized_attributes(); int n = float_indices.size(); if (n == 0) { IMP_THROW("There are no optimizable degrees of freedom.", ModelException); } x.resize(n); dx.resize(n); // get initial state in x(n): for (i = 0; i < n; i++) { #ifdef IMP_CG_SCALE x[i] = get_scaled_value(float_indices[i]); // scaled #else x[i] = get_value(float_indices[i]); // scaled #endif IMP_USAGE_CHECK( !IMP::isnan(x[i]) && std::abs(x[i]) < std::numeric_limits<NT>::max(), "Bad input to CG"); } // Initialize optimization variables int ifun = 0; int nrst; NT dg1, xsq, dxsq, alpha, step, u1, u2, u3, u4; NT f = 0., dg = 1., w1 = 0., w2 = 0., rtst, bestf; bool gradient_direction; // dx holds the gradient at x // search holds the search vector // estimate holds the best current estimate to the minimizer // destimate holds the gradient at the best current estimate // resy holds the restart Y vector // ressearch holds the restart search vector Vector<NT> search, estimate, destimate, resy, ressearch; search.resize(n); estimate.resize(n); destimate.resize(n); resy.resize(n); ressearch.resize(n); /* Calculate the function and gradient at the initial point and initialize nrst,which is used to determine whether a Beale restart is being done. nrst=n means that this iteration is a restart iteration. */ g20: f = get_score(float_indices, x, dx); if (get_stop_on_good_score() && get_scoring_function()->get_had_good_score()) { estimate = x; goto end; } ifun++; nrst = n; // this is a gradient, not restart, direction: gradient_direction = true; /* Calculate the initial search direction, the norm of x squared, and the norm of dx squared. dg1 is the current directional derivative, while xsq and dxsq are the squared norms. */ dg1 = xsq = 0.; for (i = 0; i < n; i++) { search[i] = -dx[i]; xsq += x[i] * x[i]; dg1 -= dx[i] * dx[i]; } dxsq = -dg1; /* Test if the initial point is the minimizer. */ if (dxsq <= cg_eps * cg_eps * std::max(NT(1.0), xsq)) { goto end; } /* Begin the major iteration loop. */ g40: update_states(); /* Begin linear search. alpha is the steplength. */ if (gradient_direction) { /* This results in scaling the initial search vector to unity. */ alpha = 1.0 / sqrt(dxsq); } else if (nrst == 1) { /* Set alpha to 1.0 after a restart. */ alpha = 1.0; } else { /* Set alpha to the nonrestart conjugate gradient alpha. */ alpha = alpha * dg / dg1; } /* Store current best estimate for the score */ estimate = x; destimate = dx; /* Try to find a better score by linear search */ if (!line_search(x, dx, alpha, float_indices, ifun, f, dg, dg1, max_steps, search, estimate)) { /* If the line search failed, it was either because the maximum number of iterations was exceeded, or the minimum could not be found */ if (static_cast<unsigned int>(ifun) > max_steps) { goto end; } else if (gradient_direction) { goto end; } else { goto g20; } } /* THE LINE SEARCH HAS CONVERGED. TEST FOR CONVERGENCE OF THE ALGORITHM. */ dxsq = xsq = 0.0; for (i = 0; i < n; i++) { dxsq += dx[i] * dx[i]; xsq += x[i] * x[i]; } if (dxsq < threshold_) { goto end; } /* Search continues. Set search(i)=alpha*search(i),the full step vector. */ for (i = 0; i < n; i++) { search[i] *= alpha; } /* COMPUTE THE NEW SEARCH VECTOR; TEST IF A POWELL RESTART IS INDICATED. */ rtst = 0.; for (i = 0; i < n; ++i) { rtst += dx[i] * destimate[i]; } if (std::abs(rtst / dxsq) > .2) { nrst = n; } /* If a restart is indicated, save the current d and y as the Beale restart vectors and save d'y and y'y in w1 and w2. */ if (nrst == n) { ressearch = search; w1 = w2 = 0.; for (i = 0; i < n; i++) { resy[i] = dx[i] - destimate[i]; w1 += resy[i] * resy[i]; w2 += search[i] * resy[i]; } } /* CALCULATE THE RESTART HESSIAN TIMES THE CURRENT GRADIENT. */ u1 = u2 = 0.0; for (i = 0; i < n; i++) { u1 -= ressearch[i] * dx[i] / w1; u2 += ressearch[i] * dx[i] * 2.0 / w2 - resy[i] * dx[i] / w1; } u3 = w2 / w1; for (i = 0; i < n; i++) { estimate[i] = -u3 * dx[i] - u1 * resy[i] - u2 * ressearch[i]; } /* If this is a restart iteration, estimate contains the new search vector. */ if (nrst != n) { /* NOT A RESTART ITERATION. CALCULATE THE RESTART HESSIAN TIMES THE CURRENT Y. */ u1 = u2 = u3 = 0.0; for (i = 0; i < n; i++) { u1 -= (dx[i] - destimate[i]) * ressearch[i] / w1; u2 = u2 - (dx[i] - destimate[i]) * resy[i] / w1 + 2.0 * ressearch[i] * (dx[i] - destimate[i]) / w2; u3 += search[i] * (dx[i] - destimate[i]); } step = u4 = 0.; for (i = 0; i < n; i++) { step = (w2 / w1) * (dx[i] - destimate[i]) + u1 * resy[i] + u2 * ressearch[i]; u4 += step * (dx[i] - destimate[i]); destimate[i] = step; } /* CALCULATE THE DOUBLY UPDATED HESSIAN TIMES THE CURRENT GRADIENT TO OBTAIN THE SEARCH VECTOR. */ u1 = u2 = 0.0; for (i = 0; i < n; i++) { u1 -= search[i] * dx[i] / u3; u2 += (1.0 + u4 / u3) * search[i] * dx[i] / u3 - destimate[i] * dx[i] / u3; } for (i = 0; i < n; i++) { estimate[i] = estimate[i] - u1 * destimate[i] - u2 * search[i]; } } /* CALCULATE THE DERIVATIVE ALONG THE NEW SEARCH VECTOR. */ search = estimate; dg1 = 0.0; for (i = 0; i < n; i++) { dg1 += search[i] * dx[i]; } /* IF THE NEW DIRECTION IS NOT A DESCENT DIRECTION,STOP. */ if (dg1 <= 0.0) { /* UPDATE NRST TO ASSURE AT LEAST ONE RESTART EVERY N ITERATIONS. */ if (nrst == n) { nrst = 0; } nrst++; gradient_direction = false; goto g40; } /* ROUNDOFF HAS PRODUCED A BAD DIRECTION. */ end: // If the 'best current estimate' is better than the current state, return // that: bestf = get_score(float_indices, estimate, destimate); if (bestf < f) { f = bestf; } else { // Otherwise, restore the current state x (note that we already have the // state x and its derivatives dx, so it's rather inefficient to // recalculate the score here, but it's cleaner) f = get_score(float_indices, x, dx); } update_states(); return f; }