void SimpleConjugateGradientStep::DisplaceParticles() { int errorStatus = gsl_multimin_fdfminimizer_iterate(minimizer); shouldContinue = (errorStatus == GSL_SUCCESS); // iteration is not making progress towards solution if (errorStatus == GSL_ENOPROG) { printf("Iteration is not making progress towards solution\n"); } if (shouldContinue) { // 1e-3 is global tolerance. const FLOAT_TYPE globalTolerance = 1e-15; int result = gsl_multimin_test_gradient(minimizer->gradient, globalTolerance); shouldContinue = (result == GSL_CONTINUE); } // When minimizing energy we update the inner diameter ratio, but that may not be perfectly correct, // as we don't know the details of algorithm, so at the end we calculate it once again. if (!shouldContinue) { //ParticlePair closestPair = distanceService->FindClosestPair(); //innerDiameterRatio = sqrt(closestPair.normalizedDistanceSquare); printf("Final potential energy: %g\n", minimizer->f); } }
void optimize_eps(gsl_vector * x, void * data, int n, gsl_vector * x2){ size_t iter = 0; int status, j; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf my_func; my_func.n = n; my_func.f = my_f; my_func.df = my_df; my_func.fdf = my_fdf; my_func.params = data; T = gsl_multimin_fdfminimizer_conjugate_fr; //T = gsl_multimin_fdfminimizer_vector_bfgs2; s = gsl_multimin_fdfminimizer_alloc (T, n); //gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.1, 0.01); gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); do{ iter++; status = gsl_multimin_fdfminimizer_iterate (s); //printf ("status = %s\n", gsl_strerror (status)); if (status){ if (iter == 1){ for (j = 0; j < n; j++){ gsl_vector_set(x2, j, gsl_vector_get(x, j)); } } break; } status = gsl_multimin_test_gradient (s->gradient, 1e-3); //print_state (iter, s); //printf ("status = %s\n", gsl_strerror (status)); /*if (status == GSL_SUCCESS) printf ("Minimum found at:\n"); printf ("%5d %.5f %.5f %10.5f\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), s->f);*/ if ((isnan(s->f)) || (isinf(s->f))) break; for (j = 0; j < n; j++){ gsl_vector_set(x2, j, gsl_vector_get(s->x, j)); } }while (status == GSL_CONTINUE && iter < 100); gsl_multimin_fdfminimizer_free (s); //gsl_vector_free (x); //return 0; }
int main (void) { size_t iter = 0; int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; /* Position of the minimum (1,2). */ double par[2] = { 1.0, 2.0 }; gsl_vector *x; gsl_multimin_function_fdf my_func; my_func.f = &my_f; my_func.df = &my_df; my_func.fdf = &my_fdf; my_func.n = 2; my_func.params = ∥ /* Starting point, x = (5,7) */ x = gsl_vector_alloc (2); gsl_vector_set (x, 0, 5.0); gsl_vector_set (x, 1, 7.0); T = gsl_multimin_fdfminimizer_conjugate_fr; s = gsl_multimin_fdfminimizer_alloc (T, 2); gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-4); do { iter++; status = gsl_multimin_fdfminimizer_iterate (s); if (status) break; status = gsl_multimin_test_gradient (s->gradient, 1e-3); if (status == GSL_SUCCESS) printf ("Minimum found at:\n"); printf ("%5d %.5f %.5f %10.5f\n", iter, gsl_vector_get (s->x, 0), gsl_vector_get (s->x, 1), s->f); } while (status == GSL_CONTINUE && iter < 100); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); return 0; }
int test_fdf(const char * desc, gsl_multimin_function_fdf *f, initpt_function initpt, const gsl_multimin_fdfminimizer_type *T) { int status; size_t iter = 0; double step_size; gsl_vector *x = gsl_vector_alloc (f->n); gsl_multimin_fdfminimizer *s; fcount = 0; gcount = 0; (*initpt) (x); step_size = 0.1 * gsl_blas_dnrm2 (x); s = gsl_multimin_fdfminimizer_alloc(T, f->n); gsl_multimin_fdfminimizer_set (s, f, x, step_size, 0.1); #ifdef DEBUG printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); printf("g "); gsl_vector_fprintf (stdout, s->gradient, "%g"); #endif do { iter++; status = gsl_multimin_fdfminimizer_iterate(s); #ifdef DEBUG printf("%i: \n",iter); printf("x "); gsl_vector_fprintf (stdout, s->x, "%g"); printf("g "); gsl_vector_fprintf (stdout, s->gradient, "%g"); printf("f(x) %g\n",s->f); printf("dx %g\n",gsl_blas_dnrm2(s->dx)); printf("\n"); #endif status = gsl_multimin_test_gradient(s->gradient,1e-3); } while (iter < 5000 && status == GSL_CONTINUE); status |= (fabs(s->f) > 1e-5); gsl_test(status, "%s, on %s: %i iters (fn+g=%d+%d), f(x)=%g", gsl_multimin_fdfminimizer_name(s),desc, iter, fcount, gcount, s->f); gsl_multimin_fdfminimizer_free(s); gsl_vector_free(x); return status; }
void MStep (Dataset *data) { double lastF; int iter, status; int numParams = data->num_labelers + data->num_beta; gsl_vector *x; gsl_multimin_fdfminimizer *s; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_function_fdf obj_func; gsl_set_error_handler_off(); // Pack parameters into a gsl_vector x = gsl_vector_alloc(numParams); packX(x, data); std::cerr << "Packed" << std::endl; // Initialize objective function obj_func.n = numParams; obj_func.f = &objective_function; obj_func.df = &get_gradients; obj_func.fdf = &set_functions; obj_func.params = data; // Initialize a minimizer T = gsl_multimin_fdfminimizer_conjugate_pr; s = gsl_multimin_fdfminimizer_alloc(T, numParams); gsl_multimin_fdfminimizer_set(s, &obj_func, x, 0.01, 0.01); iter = 0; std::cerr << "Start optimization" << std::endl; do { lastF = s->f; iter++; printf("[MStep:%d] f=%f\n", iter, s->f); status = gsl_multimin_fdfminimizer_iterate(s); if (status) { printf("Error occurred [MStep]\n"); break; } status = gsl_multimin_test_gradient(s->gradient, 1e-2); if (status == GSL_SUCCESS) { printf ("Minimum found"); } } while (lastF - s->f > 1e-5 && status == GSL_CONTINUE && iter < 25); /* Unpack alpha and beta from gsl_vector */ unpackX(s->x, data); gsl_multimin_fdfminimizer_free(s); gsl_vector_free(x); }
NativeSolver::IterationStatus GSLFDFSolver::iterate_() { int status = gsl_multimin_fdfminimizer_iterate(gslSolver_); state_.fx = gslSolver_->f; // TODO: error codes if(status == GSL_ENOPROG) return NativeSolver::ITERATION_NO_PROGRESS; else return NativeSolver::ITERATION_CONTINUE; }
double Fitting(FittinfPar *Par) { size_t iter = 0; int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; /* Starting point */ //adding on 2011.8.27 Par->Initial(); ////////////////// double a0=Error_std(Par)*0.6; double b0=a0*0.4; gsl_vector *v; v=gsl_vector_alloc(2); gsl_vector_set(v,0,a0); gsl_vector_set(v,1,b0); Par->a=a0; Par->b=b0; gsl_multimin_function_fdf my_func; my_func.f = &IntR_Res_f; my_func.df = &IntR_Res_df; my_func.fdf = &IntR_Res_fdf; my_func.n = 2; my_func.params =(void *)Par; T = gsl_multimin_fdfminimizer_vector_bfgs; s = gsl_multimin_fdfminimizer_alloc(T,2);//3 是未知数个数 gsl_multimin_fdfminimizer_set(s,&my_func,v,0.01,1e-5); do { iter++; status = gsl_multimin_fdfminimizer_iterate(s); if(status==GSL_ENOPROG) { Par->a=gsl_vector_get(s->x,0); Par->b=gsl_vector_get(s->x,1); break; } status = gsl_multimin_test_gradient(s->gradient,1e-6); if(status == GSL_SUCCESS) { Par->a=gsl_vector_get(s->x,0); Par->b=gsl_vector_get(s->x,1); } }while(status==GSL_CONTINUE&&iter<100); //printf("Iter=%d\n",iter); double breturn=IntR_Res_f(s->x,(void *)Par); gsl_multimin_fdfminimizer_free(s); gsl_vector_free(v); //cal the goodness of fitting return -breturn; }
double GSLOptimizer::optimize(unsigned int iter, const gsl_multimin_fdfminimizer_type*t, double step, double param, double min_gradient) { 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_fdfminimizer *s=gsl_multimin_fdfminimizer_alloc (t, n); gsl_vector *x= gsl_vector_alloc(get_dimension()); gsl_multimin_function_fdf f= internal::create_function_data(this); update_state(x); gsl_multimin_fdfminimizer_set (s, &f, x, step, param); try { int status; do { --iter; //update_state(x); status = gsl_multimin_fdfminimizer_iterate(s); update_states(); if (status) { IMP_LOG(TERSE, "Ending optimization because of status " << status << std::endl); break; } status = gsl_multimin_test_gradient (s->gradient, min_gradient); if (status == GSL_SUCCESS) { IMP_LOG(TERSE, "Ending optimization because of small gradient " << s->gradient << std::endl); break; } } while (status == GSL_CONTINUE && iter >0); } catch (AllDone){ } gsl_vector *ret=gsl_multimin_fdfminimizer_x (s); write_state(ret); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); return best_score_; }
void optimize_alpha(gsl_vector * x, void * data, int n, gsl_vector * x2){ size_t iter = 0; int status, j; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf my_func; my_func.n = n; my_func.f = my_f; my_func.df = my_df; my_func.fdf = my_fdf; my_func.params = data; T = gsl_multimin_fdfminimizer_conjugate_fr; s = gsl_multimin_fdfminimizer_alloc (T, n); gsl_multimin_fdfminimizer_set (s, &my_func, x, 0.01, 1e-3); do{ iter++; status = gsl_multimin_fdfminimizer_iterate (s); //printf ("status = %s\n", gsl_strerror (status)); if (status){ if (iter == 1){ for (j = 0; j < n; j++){ gsl_vector_set(x2, j, gsl_vector_get(x, j)); } } break; } status = gsl_multimin_test_gradient (s->gradient, 1e-3); if ((isnan(s->f)) || (isinf(s->f))) break; for (j = 0; j < n; j++){ gsl_vector_set(x2, j, gsl_vector_get(s->x, j)); } }while (status == GSL_CONTINUE && iter < 100); gsl_multimin_fdfminimizer_free (s); }
/** * Perform one iteration. * @return :: true to continue, false to stop. */ bool DerivMinimizer::iterate(size_t) { if (m_gslSolver == nullptr) { throw std::runtime_error("Minimizer " + this->name() + " was not initialized."); } int status = gsl_multimin_fdfminimizer_iterate(m_gslSolver); if (status) { m_errorString = gsl_strerror(status); return false; } status = gsl_multimin_test_gradient(m_gslSolver->gradient, m_stopGradient); if (status != GSL_CONTINUE) { m_errorString = gsl_strerror(status); return false; } return true; }
static void optimise_lambda_k(double *adLambdaK, struct data_t *data, double *adZ) { const int S = data->S; int i, status; size_t iter = 0; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf fdf; gsl_vector *ptLambda; /*initialise vector*/ ptLambda = gsl_vector_alloc(S); for (i = 0; i < S; i++) gsl_vector_set(ptLambda, i, adLambdaK[i]); /*initialise function to be solved*/ data->adPi = adZ; fdf.n = S; fdf.f = neg_log_evidence_lambda_pi; fdf.df = neg_log_derive_evidence_lambda_pi; fdf.fdf = neg_log_FDF_lamba_pi; fdf.params = data; T = gsl_multimin_fdfminimizer_vector_bfgs2; s = gsl_multimin_fdfminimizer_alloc(T, S); gsl_multimin_fdfminimizer_set(s, &fdf, ptLambda, 1.0e-6, 0.1); do { iter++; status = gsl_multimin_fdfminimizer_iterate(s); if (status) break; status = gsl_multimin_test_gradient(s->gradient, 1e-3); } while (status == GSL_CONTINUE && iter < MAX_GRAD_ITER); for (i = 0; i < S; i++) adLambdaK[i] = gsl_vector_get(s->x, i); gsl_vector_free(ptLambda); gsl_multimin_fdfminimizer_free(s); }
void optimize_fdf(int dim, gsl_vector* x, void* params, void (*fdf)(const gsl_vector*, void*, double*, gsl_vector*), void (*df)(const gsl_vector*, void*, gsl_vector*), double (*f)(const gsl_vector*, void*), double* f_val, double* conv_val, int* niter) { gsl_multimin_function_fdf obj; obj.f = f; obj.df = df; obj.fdf = fdf; obj.n = dim; obj.params = params; // const gsl_multimin_fdfminimizer_type * method = // gsl_multimin_fdfminimizer_vector_bfgs; const gsl_multimin_fdfminimizer_type * method = gsl_multimin_fdfminimizer_conjugate_fr; gsl_multimin_fdfminimizer * opt = gsl_multimin_fdfminimizer_alloc(method, dim); gsl_multimin_fdfminimizer_set(opt, &obj, x, 0.01, 1e-3); int iter = 0, status; double converged, f_old = 0; do { iter++; status = gsl_multimin_fdfminimizer_iterate(opt); // assert(status==0); converged = fabs((f_old - opt->f) / (dim * f_old)); // status = gsl_multimin_test_gradient(opt->gradient, 1e-3); // printf("f = %1.15e; conv = %5.3e; norm = %5.3e; niter = %03d\n", // opt->f, converged, norm(opt->gradient), iter); f_old = opt->f; } while (converged > 1e-8 && iter < MAX_ITER); // while (status == GSL_CONTINUE); *f_val = opt->f; *conv_val = converged; *niter = iter; gsl_multimin_fdfminimizer_free(opt); }
void multidim_minimization_steepest_descent() { // Position of the minimum (1,2) double par[2] = { 1.0, 2.0 }; gsl_multimin_function_fdf my_func; my_func.f = &local::my_f; my_func.df = &local::my_df; my_func.fdf = &local::my_fdf; my_func.n = 2; // the dimension of the system, i.e. the number of components of the vectors x my_func.params = (void*)∥ // Starting point, x = (5,7) gsl_vector *x = gsl_vector_alloc(2); gsl_vector_set(x, 0, 5.0); gsl_vector_set(x, 1, 7.0); const gsl_multimin_fdfminimizer_type *T = gsl_multimin_fdfminimizer_steepest_descent; gsl_multimin_fdfminimizer *s = gsl_multimin_fdfminimizer_alloc(T, 2); gsl_multimin_fdfminimizer_set(s, &my_func, x, 0.01, 1e-4); size_t iter = 0; int status; do { ++iter; status = gsl_multimin_fdfminimizer_iterate(s); if (status) break; status = gsl_multimin_test_gradient(s->gradient, 1e-7); if (status == GSL_SUCCESS) printf("Minimum found at:\n"); printf("%5d %.5f %.5f %10.5f\n", iter, gsl_vector_get(s->x, 0), gsl_vector_get(s->x, 1), s->f); } while (status == GSL_CONTINUE && iter < 1000); // gsl_multimin_fdfminimizer_free(s); gsl_vector_free(x); }
/* internal function used by get_theta_matrix(). Minimizes the function func(): e0*cos(th0) + e1*cos(th1) + e2*cos(th0+th1+phi) for th0, th1 */ void minimize_for_thetas(gsl_vector *th, struct func_params *f_params) { const int niter = 10000; const double eps = 1.e-5; const gsl_multimin_fdfminimizer_type *minimizer_type; gsl_multimin_fdfminimizer *minimizer; int status; size_t iter = 0; const size_t n = 2; gsl_multimin_function_fdf fdf = { &func, &dfunc, &funcdfunc, n, (void *)f_params }; minimizer_type = gsl_multimin_fdfminimizer_conjugate_fr; minimizer = gsl_multimin_fdfminimizer_alloc (minimizer_type, 2); gsl_multimin_fdfminimizer_set (minimizer, &fdf, th, 0.1, eps); do{ iter++; status = gsl_multimin_fdfminimizer_iterate (minimizer); if(status) break; status = gsl_multimin_test_gradient (minimizer->gradient, eps); }while(status == GSL_CONTINUE && iter < niter); if(status == GSL_CONTINUE){ fprintf(stderr," failed to find minimum in %s(), quitting\n", __func__); exit(-3); } gsl_vector_set (th, 0, gsl_vector_get (minimizer->x, 0)); gsl_vector_set (th, 1, gsl_vector_get (minimizer->x, 1)); gsl_multimin_fdfminimizer_free (minimizer); return; }
std::vector<contr_t> slater_fit(double zeta, int am, int nf, bool verbose, int method) { sto_params_t par; par.zeta=zeta; par.l=am; par.Nf=nf; par.method=method; int maxiter=1000; // Degrees of freedom int dof; if(par.method==0 && nf>=2) dof=2; else // Full optimization par.method=2; if(par.method==1 && nf>=4) dof=4; else // Full optimization par.method=2; // Full optimization if(par.method==2) dof=par.Nf; gsl_multimin_function_fdf minfunc; minfunc.n=dof; minfunc.f=eval_difference; minfunc.df=eval_difference_df; minfunc.fdf=eval_difference_fdf; minfunc.params=(void *) ∥ gsl_multimin_fdfminimizer *min; // Allocate minimizer // min=gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_vector_bfgs2,dof); min=gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_conjugate_pr,dof); gsl_vector *x; x=gsl_vector_alloc(dof); // Initialize vector gsl_vector_set_all(x,0.0); // Set starting point switch(par.method) { case(2): // Legendre - same as for even tempered case(1): // Well tempered - same initialization as for even-tempered case(0): // Even tempered, set alpha=1.0 and beta=2.0 gsl_vector_set(x,0,1.0); if(dof>1) gsl_vector_set(x,1,2.0); break; /* case(2): // Free minimization, set exponents to i for(int i=0;i<nf;i++) gsl_vector_set(x,i,i); break; */ default: ERROR_INFO(); throw std::runtime_error("Unknown Slater fitting method.\n"); } // Set minimizer gsl_multimin_fdfminimizer_set(min, &minfunc, x, 0.01, 1e-4); // Iterate int iter=0; int iterdelta=0; int status; double cost=0; if(verbose) printf("Iteration\tDelta\n"); do { iter++; iterdelta++; // Simplex status = gsl_multimin_fdfminimizer_iterate(min); if (status) { // printf("Encountered GSL error \"%s\"\n",gsl_strerror(status)); break; } // Are we converged? status = gsl_multimin_test_gradient (min->gradient, 1e-12); if (verbose && status == GSL_SUCCESS) { printf ("converged to minimum at\n"); } if(min->f!=cost) { if(verbose) printf("%i\t%e\t%e\t%e\n",iter,min->f,min->f-cost,gsl_blas_dnrm2(min->gradient)); cost=min->f; iterdelta=0; } } while (status == GSL_CONTINUE && iterdelta < maxiter); // Get best exponents and coefficients std::vector<double> optexp=get_exps(min->x,&par); arma::vec optc=solve_coefficients(optexp,par.zeta,par.l); // Free memory gsl_vector_free(x); gsl_multimin_fdfminimizer_free(min); // Return std::vector<contr_t> ret(nf); for(int i=0;i<nf;i++) { ret[i].z=optexp[i]; ret[i].c=optc[i]; } return ret; }
void GslOptimizer::minimize_with_gradient( unsigned int dim, OptimizerMonitor* monitor ) { // Set initial point gsl_vector * x = gsl_vector_alloc(dim); for (unsigned int i = 0; i < dim; i++) { gsl_vector_set(x, i, (*m_initialPoint)[i]); } // Tell GSL which solver we're using const gsl_multimin_fdfminimizer_type* type = NULL; // We use m_solver_type here because we need the enum switch(m_solver_type) { case(FLETCHER_REEVES_CG): type = gsl_multimin_fdfminimizer_conjugate_fr; break; case(POLAK_RIBIERE_CG): type = gsl_multimin_fdfminimizer_conjugate_pr; break; case(BFGS): type = gsl_multimin_fdfminimizer_vector_bfgs; break; case(BFGS2): type = gsl_multimin_fdfminimizer_vector_bfgs2; break; case(STEEPEST_DESCENT): type = gsl_multimin_fdfminimizer_steepest_descent; break; case(NELDER_MEAD): case(NELDER_MEAD2): case(NELDER_MEAD2_RAND): default: // Wat?! queso_error(); } // Init solver gsl_multimin_fdfminimizer * solver = gsl_multimin_fdfminimizer_alloc(type, dim); // Point GSL to the right functions gsl_multimin_function_fdf minusLogPosterior; minusLogPosterior.n = dim; minusLogPosterior.f = &c_evaluate; minusLogPosterior.df = &c_evaluate_derivative; minusLogPosterior.fdf = &c_evaluate_with_derivative; minusLogPosterior.params = (void *)(this); gsl_multimin_fdfminimizer_set(solver, &minusLogPosterior, x, getFdfstepSize(), getLineTolerance()); int status; size_t iter = 0; do { iter++; status = gsl_multimin_fdfminimizer_iterate(solver); if (status) { if( m_objectiveFunction.domainSet().env().fullRank() == 0 ) { std::cerr << "Error while GSL does optimisation. " << "See below for GSL error type." << std::endl; std::cerr << "Gsl error: " << gsl_strerror(status) << std::endl; } break; } status = gsl_multimin_test_gradient(solver->gradient, this->getTolerance()); if(monitor) { gsl_vector* x = gsl_multimin_fdfminimizer_x(solver); std::vector<double> x_min(dim); for( unsigned int i = 0; i < dim; i++) x_min[i] = gsl_vector_get(x,i); double f = gsl_multimin_fdfminimizer_minimum(solver); gsl_vector* grad = gsl_multimin_fdfminimizer_gradient(solver); double grad_norm = gsl_blas_dnrm2(grad); monitor->append( x_min, f, grad_norm ); } } while ((status == GSL_CONTINUE) && (iter < this->getMaxIterations())); for (unsigned int i = 0; i < dim; i++) { (*m_minimizer)[i] = gsl_vector_get(solver->x, i); } // We're being good human beings and cleaning up the memory we allocated gsl_multimin_fdfminimizer_free(solver); gsl_vector_free(x); return; }
static VALUE rb_gsl_fdfminimizer_iterate(VALUE obj) { gsl_multimin_fdfminimizer *gmf = NULL; Data_Get_Struct(obj, gsl_multimin_fdfminimizer, gmf); return INT2FIX(gsl_multimin_fdfminimizer_iterate(gmf)); }
int main (int argc, char *argv[]) { int i; int outp; int n = atoi (argv[1]); double x, y, z; gsl_vector *r = gsl_vector_alloc (3 * n); gsl_vector *dr = gsl_vector_alloc (3 * n); double uu = 0; double est; double tmp1, tmp2; FILE *in, *out; //Reading input in = fopen (argv[2], "r"); if (in != NULL) { out = fopen (argv[3], "w"); for (i = 0; i < n; i++) { outp = fscanf (in, "%lf %lf %lf", &x, &y, &z); gsl_vector_set (r, 3 * i, x); gsl_vector_set (r, 3 * i + 1, y); gsl_vector_set (r, 3 * i + 2, z); } fclose (in); //Initial energies and forces before optimization gupta_fdf (r, &n, &uu, dr); tmp1 = tmp2 = 0.0; for (i = 0; i < 3 * n; i++) { tmp1 = gsl_vector_get (dr, i); tmp2 += tmp1 * tmp1; } tmp2 = sqrt (tmp2); fprintf (stdout, "\n \nInitial Energy in file %s was E=%lf and the value of the norm of the gradient was |df|=%lf\n ", argv[2], uu, tmp2); //Setting the optimizer size_t iter = 0; int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf my_func; my_func.n = 3 * n; my_func.f = gupta_f; my_func.df = gupta_df; my_func.fdf = gupta_fdf; my_func.params = &n; T = gsl_multimin_fdfminimizer_vector_bfgs2; s = gsl_multimin_fdfminimizer_alloc (T, 3 * n); gsl_multimin_fdfminimizer_set (s, &my_func, r, 0.01, 1e-4); //The actual optimization do { iter++; status = gsl_multimin_fdfminimizer_iterate (s); if (status) break; status = gsl_multimin_test_gradient (s->gradient, 1e-6); } while (status == GSL_CONTINUE && iter < 10000); est = gsl_multimin_fdfminimizer_minimum (s); gsl_vector_memcpy (r, gsl_multimin_fdfminimizer_x (s)); //The values of the energies and forces after the optimization gupta_fdf (r, &n, &uu, dr); tmp1 = tmp2 = 0.0; for (i = 0; i < 3 * n; i++) { tmp1 = gsl_vector_get (dr, i); tmp2 += tmp1 * tmp1; } tmp2 = sqrt (tmp2); fprintf (stdout, "\n \nFinal Energy in file %s was E=%lf and the value of the norm of the gradient was |df|=%lf\n ", argv[3], uu, tmp2); for (i = 0; i < n; i++) { fprintf (out, "%.16e %.16e %.16e\n", gsl_vector_get (r, 3 * i), gsl_vector_get (r, 3 * i + 1), gsl_vector_get (r, 3 * i + 2)); } gsl_multimin_fdfminimizer_free (s); gsl_vector_free (r); } else { fprintf (stdout, "The file %s was not found\n", argv[2]); } return 0; }
int main(int argc, char *argv[]) { struct RNAfold_args_info args_info; char *string, *input_string, *structure=NULL, *cstruc=NULL; char fname[80], ffname[80], gfname[80], *ParamFile=NULL; char *ns_bases=NULL, *c; int i, j, ii, jj, mu, length, l, sym, r, pf=0, noconv=0; unsigned int input_type; double energy, min_en, kT, sfact=1.07; int doMEA=0, circular = 0, N; char *pf_struc; double dist; plist *pl; FILE * filehandle; FILE * statsfile; char* line; double tau = 0.01; /* Variance of energy parameters */ double sigma = 0.01; /* Variance of experimental constraints */ double *gradient; /* Gradient for steepest descent search epsilon[i+1]= epsilon[i] - gradient * step_size */ double initial_step_size = 0.5; /* Initial step size for steepest descent search */ double step_size; double D; /* Discrepancy (i.e. value of objective function) for the current prediction */ int iteration, max_iteration = 2000; /* Current and maximum number of iterations after which algorithm stops */ double precision = 0.1; /* cutoff used for stop conditions */ double tolerance = 0.1; /* Parameter used by various GSL minimizers */ int method_id = 1; /* Method to use for minimization, 0 and 1 are custom steepest descent, the rest are GSL implementations (see below)*/ int initial_guess_method = 0; int sample_N = 1000; double *prev_epsilon; double *prev_gradient; double DD, prev_D, sum, norm; int status; double* gradient_numeric; double* gradient_numeric_gsl; /* Minimizer vars */ const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *minimizer; gsl_vector *minimizer_x; gsl_vector *minimizer_g; gsl_multimin_function_fdf minimizer_func; minimizer_pars_struct minimizer_pars; char *constraints; char outfile[256]; char constraints_file[256]; char epsilon_file[256]; FILE* fh; double last_non_nan_lnQ; pf_overflow = 0; pf_underflow = 0; dangles=2; do_backtrack = 1; string = NULL; noPS = 0; outfile[0]='\0'; epsilon_file[0]='\0'; strcpy(psDir, "dotplots"); if(RNAfold_cmdline_parser (argc, argv, &args_info) != 0) exit(1); /* RNAbpfold specific options */ if (args_info.tau_given) tau = args_info.tau_arg; if (args_info.sigma_given) sigma = args_info.sigma_arg; if (args_info.precision_given) precision = args_info.precision_arg; if (args_info.step_given) initial_step_size = args_info.step_arg; if (args_info.maxN_given) max_iteration = args_info.maxN_arg; if (args_info.minimization_given) method_id = args_info.minimization_arg; if (args_info.init_given) initial_guess_method = args_info.init_arg; if (args_info.tolerance_given) tolerance = args_info.tolerance_arg; if (args_info.outfile_given) strcpy(outfile, args_info.outfile_arg); if (args_info.constraints_given) strcpy(constraints_file, args_info.constraints_arg); if (args_info.epsilon_given) strcpy(epsilon_file, args_info.epsilon_arg); if (args_info.sampleGradient_given) sample_conditionals=1; if (args_info.hybridGradient_given) { sample_conditionals=1; hybrid_conditionals=1; } if (args_info.numericalGradient_given) numerical=1; if (args_info.sampleStructure_given) sample_structure=1; if (args_info.psDir_given) strcpy(psDir, args_info.psDir_arg); if (args_info.sparsePS_given) sparsePS=args_info.sparsePS_arg; if (args_info.gridSearch_given) grid_search = 1; /* Generic RNAfold options */ if (args_info.temp_given) temperature = args_info.temp_arg; if (args_info.reference_given) fold_constrained=1; if (args_info.noTetra_given) tetra_loop=0; if (args_info.dangles_given) dangles = args_info.dangles_arg; if (args_info.noLP_given) noLonelyPairs = 1; if (args_info.noGU_given) noGU = 1; if (args_info.noClosingGU_given) no_closingGU = 1; if (args_info.noconv_given) noconv = 1; if (args_info.energyModel_given) energy_set = args_info.energyModel_arg; if (args_info.paramFile_given) ParamFile = strdup(args_info.paramFile_arg); if (args_info.nsp_given) ns_bases = strdup(args_info.nsp_arg); if (args_info.pfScale_given) sfact = args_info.pfScale_arg; if (args_info.noPS_given) noPS=1; /* Create postscript directory */ if (!noPS) { struct stat stat_p; if (stat (psDir, &stat_p) != 0) { if (mkdir(psDir, S_IRWXU|S_IROTH|S_IRGRP ) !=0) { fprintf(stderr, "WARNING: Could not create directory: %s", psDir); } } } if (ParamFile != NULL) { read_parameter_file(ParamFile); } if (ns_bases != NULL) { nonstandards = space(33); c=ns_bases; i=sym=0; if (*c=='-') { sym=1; c++; } while (*c!='\0') { if (*c!=',') { nonstandards[i++]=*c++; nonstandards[i++]=*c; if ((sym)&&(*c!=*(c-1))) { nonstandards[i++]=*c; nonstandards[i++]=*(c-1); } } c++; } } /*Read sequence*/ fname[0] = '\0'; while((input_type = get_input_line(&input_string, 0)) & VRNA_INPUT_FASTA_HEADER) { (void) sscanf(input_string, "%42s", fname); free(input_string); } length = (int) strlen(input_string); string = strdup(input_string); free(input_string); structure = (char *) space((unsigned) length+1); /* For testing purpose pass dot bracket structure of reference structure via -C */ if (fold_constrained) { input_type = get_input_line(&input_string, VRNA_INPUT_NOSKIP_COMMENTS); if(input_type & VRNA_INPUT_QUIT) { exit(1); } else if((input_type & VRNA_INPUT_MISC) && (strlen(input_string) > 0)) { cstruc = strdup(input_string); free(input_string); } else warn_user("-C was given but reference structure is missing"); } if(noconv) { str_RNA2RNA(string); } else { str_DNA2RNA(string); } /* Allocating space */ epsilon = (double *) space(sizeof(double)*(length+1)); exp_pert = (double **)space(sizeof(double *)*(length+1)); perturbations = (double **)space(sizeof(double *)*(length+1)); prev_epsilon = (double *) space(sizeof(double)*(length+1)); gradient = (double *) space(sizeof(double)*(length+1)); gradient_numeric = (double *) space(sizeof(double)*(length+1)); gradient_numeric_gsl = (double *) space(sizeof(double)*(length+1)); prev_gradient = (double *) space(sizeof(double)*(length+1)); q_unpaired = (double *) space(sizeof(double)*(length+1)); p_unpaired_cond = (double **)space(sizeof(double *)*(length+1)); p_unpaired_cond_sampled = (double **)space(sizeof(double *)*(length+1)); p_pp = (double **)space(sizeof(double *)*(length+1)); p_unpaired = (double *) space(sizeof(double)*(length+1)); p_unpaired_tmp = (double *) space(sizeof(double)*(length+1)); for (i=0; i <= length; i++) { epsilon[i] = gradient[i] = q_unpaired[i] = 0.0; p_unpaired_cond[i] = (double *) space(sizeof(double)*(length+1)); p_unpaired_cond_sampled[i] = (double *) space(sizeof(double)*(length+1)); p_pp[i] = (double *) space(sizeof(double)*(length+1)); exp_pert[i] = (double *) space(sizeof(double)*(length+1)); perturbations[i] = (double *) space(sizeof(double)*(length+1)); for (j=0; j <= length; j++) { p_pp[i][j]=p_unpaired_cond[i][j] = 0.0; p_unpaired_cond_sampled[i][j] = 0.0; } } /*** If file with perturbation vector epsilon is given we fold using this epsilon and are done ***/ if (args_info.epsilon_given) { plist *pl, *pl1,*pl2; filehandle = fopen (epsilon_file,"r"); if (filehandle == NULL) { nrerror("Could not open file with perturbation vector."); } i=1; while (1) { double t; line = get_line(filehandle); if (line == NULL) break; if (i>length) nrerror("Too many values in perturbation vector file."); if (sscanf(line, "%lf", &epsilon[i]) !=1) { nrerror("Error while reading perturbation vector file."); } i++; } if (i-1 != length) { nrerror("Too few values in perturbation vector file."); } init_pf_fold(length); pf_fold_pb(string, NULL); sprintf(fname,"%s/dot.ps", psDir); pl1 = make_plist(length, 1e-5); (void) PS_dot_plot_list_epsilon(string, fname, NULL, pl1, epsilon, ""); exit(0); } /*** Get constraints from reference structure or from external file ***/ /* Structure was given by -C */ if (fold_constrained) { for (i=0; i<length; i++) { if (cstruc[i] == '(' || cstruc[i] == ')') { q_unpaired[i+1] = 0.0; } else { q_unpaired[i+1] = 1.0; } } /*Read constraints from file*/ } else { filehandle = fopen (constraints_file,"r"); if (filehandle == NULL) { nrerror("No constraints given as dot bracket or wrong file name"); } i=1; while (1) { double t; line = get_line(filehandle); if (line == NULL) break; if (i>length) nrerror("Too many values in constraints.dat"); if (sscanf(line, "%lf", &q_unpaired[i]) !=1) { nrerror("Error while reading constraints.dat"); } i++; } if (i-1 != length) { nrerror("Too few values in constraints.dat"); } } /* Create file handle */ if (outfile[0] !='\0') { statsfile = fopen (outfile,"w"); } else { statsfile = fopen ("stats.dat","w"); } setvbuf(statsfile, NULL, _IONBF, 0); if (!grid_search) { fprintf(statsfile, "Iteration\tDiscrepancy\tNorm\tdfCount\tMEA\tSampled_structure\tSampled_energy\tSampled_distance\tEpsilon\ttimestamp\n"); } else { /* If we do a grid search we have a different output. */ fprintf(statsfile, "Dummy\tm\tb\tdummy\tMEA\tepsilon\n"); } if (statsfile == NULL) { nrerror("Could not open stats.dat for writing."); } fprintf(stderr, "tau^2 = %.4f; sigma^2 = %.4f; precision = %.4f; tolerance = %.4f; step-size: %.4f\n\n", tau, sigma, precision, tolerance, initial_step_size); st_back=1; min_en = fold(string, structure); (void) fflush(stdout); if (length>2000) free_arrays(); pf_struc = (char *) space((unsigned) length+1); kT = (temperature+273.15)*1.98717/1000.; /* in Kcal */ pf_scale = exp(-(sfact*min_en)/kT/length); /* Set up minimizer */ minimizer_x = gsl_vector_alloc (length+1); minimizer_g = gsl_vector_alloc (length+1); for (i=0; i <= length; i++) { epsilon[i] = 0.0; gsl_vector_set (minimizer_g, i, 0.0); gsl_vector_set (minimizer_x, i, epsilon[i]); } minimizer_pars.length=length; minimizer_pars.seq = string; minimizer_pars.tau=tau; minimizer_pars.sigma=sigma; minimizer_pars.kT=kT; minimizer_func.n = length+1; minimizer_func.f = calculate_f; minimizer_func.df = numerical ? calculate_df_numerically: calculate_df; minimizer_func.fdf = calculate_fdf; minimizer_func.params = &minimizer_pars; //min_en = fold_pb(string, structure); //fprintf(stderr, "%f", min_en); //exit(0); /* Calling test functions for debugging */ for (i=1; i <= length; i++) { if (i%2==0) { epsilon[i] = +0.2*i; } else { epsilon[i] = -0.2*i; } } //test_folding(string, length); /* //test_stochastic_backtracking(string, length); */ /* //test_gradient(minimizer_func, minimizer_pars); */ /* //test_gradient_sampling(minimizer_func, minimizer_pars); */ //exit(1); count_df_evaluations=0; /* Initial guess for epsilon */ if (initial_guess_method !=0 && initial_guess_method !=3) { /* Vars for inital guess methods */ double m,b; double* curr_epsilon; double* best_epsilon; double best_m, best_b, best_scale; double curr_D; double min_D = 999999999.0; double inc = +0.25; double cut; if (initial_guess_method == 1) fprintf(stderr, "Mathew's constant perturbations\n"); if (initial_guess_method == 2) fprintf(stderr, "Perturbations proportional to q-p\n"); curr_epsilon = (double *) space(sizeof(double)*(length+1)); best_epsilon = (double *) space(sizeof(double)*(length+1)); last_non_nan_lnQ = min_en; // Calculate p_unpaired for unperturbed state which we need later // for the proportinal method if (initial_guess_method == 2) { init_pf_fold(length); for (i=0; i <= length; i++) { epsilon[i] = 0.0; } pf_fold_pb(string, NULL); for (i = 1; i < length; i++) { for (j = i+1; j<= length; j++) { p_pp[i][j]=p_pp[j][i]=pr[iindx[i]-j]; } } get_pair_prob_vector(p_pp, p_unpaired_tmp, length, 1); free_pf_arrays(); } /* We do the same grid search as in the Mathews paper Fig. 4*/ for (m=0.25; m <=7.0; m+=0.25) { // Weird way of writing this inner loop for the grid search. We // traverse the grid without big jumps in the parameters to make // sure that the updated scaling factor is accurate all the time. inc*=-1; for (b = inc < 0.0 ? 0.0 : -3.0; inc < 0.0 ? b >= -3.0 : b<= 0.0 ; b+=inc) { // calculate cut point with x-axis and skip parameter pairs // which give a cut point outside the range of // q_unpaired (0 to 1). They gave frequently overflows and the // idea is that we both want positive and negative perturbations cut = exp( (-1) * b / m ) - 1; fprintf(stderr, "\nm = %.2f, b = %.2f, cut=%.2f\n", m, b, cut); if (cut > 1.0 || cut < 0.01) { fprintf(stderr, "\nSkipping m = %.2f, b = %.2f\n", m, b); continue; } /* Mathew's constant perturbations */ if (initial_guess_method == 1) { for (i=0; i <= length; i++) { /* We add epsilon to unpaired regions (as opposed to paired regions as in the Mathews paper) so we multiply by -1; if missing data we set it to 0.0 */ if (q_unpaired[i] < -0.5) { curr_epsilon[i] = 0.0; } else { curr_epsilon[i] = (m *(log(q_unpaired[i]+1))+b) *(-1); } gsl_vector_set (minimizer_x, i, curr_epsilon[i]); } /* Perturbations proportional to q-p */ } else { for (i=0; i <= length; i++) { curr_epsilon[i] = (m *(log(q_unpaired[i]+1)-log(p_unpaired_tmp[i]+1))+ b ) * (-1); gsl_vector_set (minimizer_x, i, curr_epsilon[i]); } } // Repeat and adjust scaling factor until we get result without over-/underflows do { // First we use default scaling factor if (pf_underflow == 0 && pf_overflow == 0) { sfact = 1.070; } if (pf_underflow) { sfact *= 0.8; fprintf(stderr,"Underflow, adjusting sfact to %.4f\n", sfact ); } if (pf_overflow) { sfact *= 1.2; fprintf(stderr,"Overflow, adjusting sfact to %.4f\n", sfact ); } pf_scale = exp(-(sfact*last_non_nan_lnQ)/kT/length); //fprintf(stderr,"Scaling factor is now: %.4e\n", pf_scale); curr_D = calculate_f(minimizer_x, (void*)&minimizer_pars); if (!isnan(last_lnQ)) last_non_nan_lnQ = last_lnQ; // Give up when even extreme scaling does not give results // (for some reason I could not get rid of overflows even with high scaling factors) if (sfact < 0.1 || sfact > 2.0) break; } while (pf_underflow == 1 || pf_overflow == 1); // We have not given up so everything is ok now if (!(sfact < 0.1 || sfact > 2.0)) { if (curr_D < min_D) { min_D = curr_D; for (i=0; i <= length; i++) { best_epsilon[i] = curr_epsilon[i]; } best_m = m; best_b = b; best_scale = pf_scale; } /*If we are interested in the grid search we misuse the print_stats function and report m and b together with MEA*/ if (grid_search) { for (i=0; i <= length; i++) { epsilon[i] = curr_epsilon[i]; } print_stats(statsfile, string, cstruc, length, 0, 0, m, 0.0, b, 0); } fprintf(stderr, "curr D: %.2f, minimum D: %.2f\n", curr_D, min_D); // Adjust pf_scale with default scaling factor but lnQ from // previous step sfact = 1.070; pf_scale = exp(-(sfact*last_lnQ)/kT/length); } else { sfact = 1.070; fprintf(stderr, "Skipping m = %.2f, b = %.2f; did not get stable result.\n", m, b); } } // for b } // for m fprintf(stderr, "Minimum found: m=%.2f, b=%.2f: %.2f\n", best_m, best_b, min_D); for (i=0; i <= length; i++) { epsilon[i] = best_epsilon[i]; gsl_vector_set (minimizer_x, i, best_epsilon[i]); } pf_scale = best_scale; } if (initial_guess_method == 3) { srand((unsigned)time(0)); for (i=0; i <= length; i++) { double r = (double)rand()/(double)RAND_MAX * 4 - 2; epsilon[i] = r; gsl_vector_set (minimizer_x, i, epsilon[i]); } } /* If we just wanted a grid search we are done now. */ if (grid_search) { exit(0); } prev_D = calculate_f(minimizer_x, (void*)&minimizer_pars); print_stats(statsfile, string, cstruc, length, 0 , count_df_evaluations , prev_D, -1.0, 0.0,1); /* GSL minimization */ if (method_id !=0) { if (method_id > 2) { char name[100]; // Available algorithms // 3 gsl_multimin_fdfminimizer_conjugate_fr // 4 gsl_multimin_fdfminimizer_conjugate_pr // 5 gsl_multimin_fdfminimizer_vector_bfgs // 6 gsl_multimin_fdfminimizer_vector_bfgs2 // 7 gsl_multimin_fdfminimizer_steepest_descent // http://www.gnu.org/software/gsl/manual/html_node/Multimin-Algorithms-with-Derivatives.html switch (method_id) { case 2: minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_conjugate_fr, length+1); strcpy(name, "Fletcher-Reeves conjugate gradient"); break; case 3: minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_conjugate_pr, length+1); strcpy(name, "Polak-Ribiere conjugate gradient"); break; case 4: minimizer = gsl_multimin_fdfminimizer_alloc ( gsl_multimin_fdfminimizer_vector_bfgs, length+1); strcpy(name, "Broyden-Fletcher-Goldfarb-Shanno"); break; case 5: minimizer = gsl_multimin_fdfminimizer_alloc ( gsl_multimin_fdfminimizer_vector_bfgs2, length+1); strcpy(name, "Broyden-Fletcher-Goldfarb-Shanno (improved version)"); break; case 6: minimizer = gsl_multimin_fdfminimizer_alloc (gsl_multimin_fdfminimizer_steepest_descent, length+1); strcpy(name, "Gradient descent (GSL implmementation)"); break; } fprintf(stderr, "Starting minimization via GSL implementation of %s...\n\n", name); // The last two parmeters are step size and tolerance (with // different meaning for different algorithms gsl_multimin_fdfminimizer_set (minimizer, &minimizer_func, minimizer_x, initial_step_size, tolerance); iteration = 1; do { status = gsl_multimin_fdfminimizer_iterate (minimizer); D = minimizer->f; norm = gsl_blas_dnrm2(minimizer->gradient); print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, D, prev_D, norm, iteration%sparsePS == 0); prev_D = D; if (status) { fprintf(stderr, "An unexpected error has occured in the iteration (status:%i)\n", status); break; } status = gsl_multimin_test_gradient (minimizer->gradient, precision); if (status == GSL_SUCCESS) fprintf(stderr, "Minimum found stopping.\n"); iteration++; } while (status == GSL_CONTINUE && iteration < max_iteration); gsl_multimin_fdfminimizer_free (minimizer); gsl_vector_free (minimizer_x); /* Custom implementation of steepest descent */ } else { if (method_id == 1) { fprintf(stderr, "Starting custom implemented steepest descent search...\n\n"); } else { fprintf(stderr, "Starting custom implemented steepest descent search with Barzilai Borwein step size...\n\n"); } iteration = 0; D = 0.0; while (iteration++ < max_iteration) { for (i=1; i <= length; i++) { gsl_vector_set (minimizer_x, i, epsilon[i]); } D = calculate_f(minimizer_x, (void*)&minimizer_pars); if (numerical) { calculate_df_numerically(minimizer_x, (void*)&minimizer_pars, minimizer_g); } else { calculate_df(minimizer_x, (void*)&minimizer_pars, minimizer_g); } for (i=1; i <= length; i++) { gradient[i] = gsl_vector_get (minimizer_g, i); } // Do line search fprintf(stderr, "\nLine search:\n"); // After the first iteration, use Barzilai-Borwain (1988) step size (currently turned off) if (iteration>1 && method_id==2) { double denominator=0.0; double numerator=0.0; for (i=1; i <= length; i++) { numerator += (epsilon[i]-prev_epsilon[i]) * (gradient[i]-prev_gradient[i]); denominator+=(gradient[i]-prev_gradient[i]) * (gradient[i]-prev_gradient[i]); } step_size = numerator / denominator; norm =1.0; } else { // Use step sized given by the user (normalize it first) step_size = initial_step_size / calculate_norm(gradient, length); } for (i=1; i <= length; i++) { prev_epsilon[i] = epsilon[i]; prev_gradient[i] = gradient[i]; } do { for (mu=1; mu <= length; mu++) { epsilon[mu] = prev_epsilon[mu] - step_size * gradient[mu]; } for (i=1; i <= length; i++) { gsl_vector_set (minimizer_x, i, epsilon[i]); } DD = calculate_f(minimizer_x, (void*)&minimizer_pars); if (step_size > 0.0001) { fprintf(stderr, "Old D: %.4f; New D: %.4f; Step size: %.4f\n", D, DD, step_size); } else { fprintf(stderr, "Old D: %.4f; New D: %.4f; Step size: %.4e\n", D, DD, step_size); } step_size /= 2; } while (step_size > 1e-12 && DD > D); norm = calculate_norm(gradient,length); if (DD > D) { fprintf(stderr, "Line search did not improve D in iteration %i. Stop.\n", iteration); if (hybrid_conditionals) { sample_conditionals=0; } else { break; } } print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, DD, prev_D, norm, iteration%sparsePS == 0); if (norm<precision && iteration>1) { fprintf(stderr, "Minimum found stopping.\n"); break; } prev_D = DD; } } /* Force last dotplot to be printed */ print_stats(statsfile, string, cstruc, length,iteration, count_df_evaluations, DD, prev_D, norm, 1); } free(pf_struc); if (cstruc!=NULL) free(cstruc); (void) fflush(stdout); free(string); free(structure); RNAfold_cmdline_parser_free (&args_info); return 0; }
/** * The best member of the population will be used as starting point for the minimisation process. The algorithm will stop * if the gradient falls below the grad_tol parameter, if the maximum number of iterations max_iter is exceeded or if * the inner GSL routine call reports an error (which will be logged on std::cout). After the end of the minimisation process, * the minimised decision vector will replace the best individual in the population, after being modified to fall within * the problem bounds if necessary. * * @param[in,out] pop population to evolve. */ void gsl_gradient::evolve(population &pop) const { // Do nothing if the population is empty. if (!pop.size()) { return; } // Useful variables. const problem::base &problem = pop.problem(); if (problem.get_f_dimension() != 1) { pagmo_throw(value_error,"this algorithm does not support multi-objective optimisation"); } if (problem.get_c_dimension()) { pagmo_throw(value_error,"this algorithm does not support constrained optimisation"); } const problem::base::size_type cont_size = problem.get_dimension() - problem.get_i_dimension(); if (!cont_size) { pagmo_throw(value_error,"the problem has no continuous part"); } // Extract the best individual. const population::size_type best_ind_idx = pop.get_best_idx(); const population::individual_type &best_ind = pop.get_individual(best_ind_idx); // GSL wrapper parameters structure. objfun_wrapper_params params; params.p = &problem; // Integer part of the temporay decision vector must be filled with the integer part of the best individual, // which will not be optimised. params.x.resize(problem.get_dimension()); std::copy(best_ind.cur_x.begin() + cont_size, best_ind.cur_x.end(), params.x.begin() + cont_size); params.f.resize(1); params.step_size = m_numdiff_step_size; // GSL function structure. gsl_multimin_function_fdf gsl_func; gsl_func.n = boost::numeric_cast<std::size_t>(cont_size); gsl_func.f = &objfun_wrapper; gsl_func.df = &d_objfun_wrapper; gsl_func.fdf = &fd_objfun_wrapper; gsl_func.params = (void *)¶ms; // Minimiser. gsl_multimin_fdfminimizer *s = 0; // This will be the starting point. gsl_vector *x = 0; // Here we start the allocations. // Recast as size_t here, in order to avoid potential overflows later. const std::size_t s_cont_size = boost::numeric_cast<std::size_t>(cont_size); // Allocate and check the allocation results. x = gsl_vector_alloc(s_cont_size); const gsl_multimin_fdfminimizer_type *minimiser = get_gsl_minimiser_ptr(); pagmo_assert(minimiser); s = gsl_multimin_fdfminimizer_alloc(minimiser,s_cont_size); // Check the allocations. check_allocs(x,s); // Fill in the starting point (from the best individual). for (std::size_t i = 0; i < s_cont_size; ++i) { gsl_vector_set(x,i,best_ind.cur_x[i]); } // Init the solver. gsl_multimin_fdfminimizer_set(s,&gsl_func,x,m_step_size,m_tol); // Iterate. std::size_t iter = 0; int status; try { do { ++iter; status = gsl_multimin_fdfminimizer_iterate(s); if (status) { break; } status = gsl_multimin_test_gradient(s->gradient,m_grad_tol); } while (status == GSL_CONTINUE && iter < m_max_iter); } catch (const std::exception &e) { // Cleanup and re-throw. cleanup(x,s); throw e; } catch (...) { // Cleanup and throw. cleanup(x,s); pagmo_throw(std::runtime_error,"unknown exception caught in gsl_gradient::evolve"); } // Free up resources. cleanup(x,s); // Check the generated individual and change it to respect the bounds as necessary. for (problem::base::size_type i = 0; i < cont_size; ++i) { if (params.x[i] < problem.get_lb()[i]) { params.x[i] = problem.get_lb()[i]; } if (params.x[i] > problem.get_ub()[i]) { params.x[i] = problem.get_ub()[i]; } } // Replace the best individual. pop.set_x(best_ind_idx,params.x); }
void IncreasingConjugateGradientStep::DisplaceParticles() { // So that initial potential energy is valid after any outer diameter update or reset. InitializeMinimization(); FLOAT_TYPE previousEnergy = minimizer->f; while (true) { int errorStatus = gsl_multimin_fdfminimizer_iterate(minimizer); FLOAT_TYPE currentEnergy = minimizer->f; bool localShouldContinue = (errorStatus == GSL_SUCCESS); // Iteration is not making progress towards solution. if (errorStatus == GSL_ENOPROG) { printf("Stop iteration. Iteration is not making progress towards solution. Inner diameter ratio: %g; Energy per particle: %g\n", innerDiameterRatio, GetEnergyPerParticle()); break; } // We should always use one of the GSL termination conditions, as when stopping just by stationary or zero energy the GSL sometimes hangs. if (localShouldContinue) { const FLOAT_TYPE globalTolerance = 1e-5; int result = gsl_multimin_test_gradient(minimizer->gradient, globalTolerance * potentialNormalizer); localShouldContinue = (result == GSL_CONTINUE); } if (!localShouldContinue) { printf("Stop iteration. Gradient too small. Inner diameter ratio: %g; Energy per particle: %g\n", innerDiameterRatio, GetEnergyPerParticle()); break; } // if (localShouldContinue) // { // bool energyStationary = (std::abs(currentEnergy - previousEnergy) / currentEnergy) < relativeEnergyTolerance; // bool energyZero = GetEnergyPerParticle() < minEnergyPerParticle; // localShouldContinue = energyStationary || energyZero; // } // if (!localShouldContinue) // { // printf("Stop iteration. Energy is stationary or zero. Inner diameter ratio: %g; Energy per particle: %g\n", innerDiameterRatio, GetEnergyPerParticle()); // break; // } previousEnergy = currentEnergy; } FLOAT_TYPE energyPerParticle = GetEnergyPerParticle(); shouldContinue = energyPerParticle < minEnergyPerParticle || energyPerParticle > 2 * minEnergyPerParticle; if (!shouldContinue) { // In this algorithm we allow particles to intersect a little bit, so we make the final inner diameters equal to the outer ones innerDiameterRatio = outerDiameterRatio; printf("Stop algorithm. Inner diameter ratio: %g; Energy per particle: %g\n", innerDiameterRatio, energyPerParticle); } else { UpdateOuterDiameterRatio(); } }
void minim(density_t * ndft){ const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf my_func; gsl_vector * grad_initial; size_t iter; ipf_t ipf_previous; int status; double minimum, g_initial, norm_initial; char * output_string; int i; params_gsl_multimin_function_t params; output_string = (char *) malloc(25*sizeof(char)); params.nDFT = density_get_val(ndft); my_func.n = ipf.npar; my_func.f = my_f; my_func.df = my_df; my_func.fdf = my_fdf; my_func.params = (void *) (¶ms); /* We use the BFGS algorithm from thee GNU Scientific Library (GSL) in its optimized version bfgs2 */ T = gsl_multimin_fdfminimizer_vector_bfgs2; messages_basic("\n\nStarting the optimization.\n\n\n"); grad_initial = gsl_vector_alloc(ipf.npar); my_fdf (ipf.gamma, ¶ms, &g_initial, grad_initial); norm_initial = gsl_blas_dnrm2(grad_initial); if(g_initial < epsilon_gvalue){ if(myid == 0) printf("The value of G for the starting gamma is %.12lg,\n", g_initial); if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_gvalue); parallel_end(EXIT_SUCCESS); } if(norm_initial < epsilon_grad){ if(myid == 0) printf("The value of the normm of the gradient of G for the starting gamma is %.12lg,\n", norm_initial); if(myid == 0) printf("which is already below the requested threshold of %.12lg\n", epsilon_grad); parallel_end(EXIT_SUCCESS); } if(myid == 0) printf(" Starting from gamma = "); if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (ipf.gamma, i));} if(myid == 0) printf("\n G(gamma) = %.12lg\n", g_initial); if(myid == 0) printf(" ||Grad G(gamma)|| = %.12lg\n\n", norm_initial); /* Initialization of the minimizer s for the function my_func starting at the x point The step for the first try is 0.1 and the convergence criteria is 0.1 */ messages_basic("\n\nInitialization of the minimizer.\n\n\n"); s = gsl_multimin_fdfminimizer_alloc (T, ipf.npar); gsl_multimin_fdfminimizer_set (s, &my_func, ipf.gamma, 0.1, 0.1); minimum = g_initial; iter = 0; do{ iter++; ipf_copy(&ipf_previous, &ipf); if(myid == 0) printf(" Iter = %d\n", (int)iter); if(myid == 0) printf(" starting gamma = "); if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));} if(myid == 0) printf("\n starting G(gamma) = %15.10f\n", minimum); /* We make an iteration of the minimizer s */ status = gsl_multimin_fdfminimizer_iterate (s); minimum = gsl_multimin_fdfminimizer_minimum(s); if (status){ if(myid == 0) printf(" Breaking. Reason: %s\n", gsl_strerror(status)); break; } if(myid == 0) printf(" ||Grad G(gamma)|| = %15.10f\n", gsl_blas_dnrm2(gsl_multimin_fdfminimizer_gradient(s))); if(myid == 0) printf(" G(gamma) = %15.10f\n", minimum); /* Checks convergence */ if(minimum < epsilon_gvalue){ status = GSL_SUCCESS; }else{ status = gsl_multimin_test_gradient (gsl_multimin_fdfminimizer_gradient(s), epsilon_grad); } gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s)); ipf_write(ipf, ipf_ref, "intermediate-pot"); /* Print the diff between initial and reference IPFs */ if(myid == 0) printf(" Diff[ IPF(previous), IPF(new) ] = %.12lg\n", ipf_diff(&ipf_previous, &ipf)); ipf_end(&ipf_previous); } while (status == GSL_CONTINUE && iter < minim_maxiter); if(myid == 0) printf("\n\nFinished optimization. status = %d (%s)\n", status, gsl_strerror(status)); if(myid == 0) printf(" Final gamma = "); if(myid == 0) {for(i = 0; i < ipf.npar; i++) printf ("%.5f ", gsl_vector_get (gsl_multimin_fdfminimizer_x(s), i));} if(myid == 0) printf("\n With value: G(gamma) = %.12lg\n\n", gsl_multimin_fdfminimizer_minimum(s)); gsl_vector_memcpy(ipf.gamma, gsl_multimin_fdfminimizer_x(s)); sprintf(output_string, "pot"); ipf_write(ipf, ipf_ref, output_string); gsl_multimin_fdfminimizer_free (s); fflush(stdout); }
int OptimizationOptions::gslOptimize( NLSFunction *F, gsl_vector* x_vec, gsl_matrix *v, IterationLogger *itLog ) { const gsl_multifit_fdfsolver_type *Tlm[] = { gsl_multifit_fdfsolver_lmder, gsl_multifit_fdfsolver_lmsder }; const gsl_multimin_fdfminimizer_type *Tqn[] = { gsl_multimin_fdfminimizer_vector_bfgs, gsl_multimin_fdfminimizer_vector_bfgs2, gsl_multimin_fdfminimizer_conjugate_fr, gsl_multimin_fdfminimizer_conjugate_pr }; const gsl_multimin_fminimizer_type *Tnm[] = { gsl_multimin_fminimizer_nmsimplex, gsl_multimin_fminimizer_nmsimplex2, gsl_multimin_fminimizer_nmsimplex2rand }; int gsl_submethod_max[] = { sizeof(Tlm) / sizeof(Tlm[0]), sizeof(Tqn) / sizeof(Tqn[0]), sizeof(Tnm) / sizeof(Tnm[0]) }; int status, status_dx, status_grad, k; double g_norm, x_norm; /* vectorize x row-wise */ size_t max_ind, min_ind; double max_val, min_val, abs_max_val = 0, abs_min_val; if (this->method < 0 || this->method > sizeof(gsl_submethod_max)/sizeof(gsl_submethod_max[0]) || this->submethod < 0 || this->submethod > gsl_submethod_max[this->method]) { throw new Exception("Unknown optimization method.\n"); } if (this->maxiter < 0 || this->maxiter > 5000) { throw new Exception("opt.maxiter should be in [0;5000].\n"); } /* LM */ gsl_multifit_fdfsolver* solverlm; gsl_multifit_function_fdf fdflm = { &(F->_f_ls), &(F->_df_ls), &(F->_fdf_ls), F->getNsq(), F->getNvar(), F }; gsl_vector *g; /* QN */ double stepqn = this->step; gsl_multimin_fdfminimizer* solverqn; gsl_multimin_function_fdf fdfqn = { &(F->_f), &(F->_df), &(F->_fdf), F->getNvar(), F }; /* NM */ double size; gsl_vector *stepnm; gsl_multimin_fminimizer* solvernm; gsl_multimin_function fnm = { &(F->_f), F->getNvar(), F }; /* initialize the optimization method */ switch (this->method) { case SLRA_OPT_METHOD_LM: /* LM */ solverlm = gsl_multifit_fdfsolver_alloc(Tlm[this->submethod], F->getNsq(), F->getNvar()); gsl_multifit_fdfsolver_set(solverlm, &fdflm, x_vec); g = gsl_vector_alloc(F->getNvar()); break; case SLRA_OPT_METHOD_QN: /* QN */ solverqn = gsl_multimin_fdfminimizer_alloc(Tqn[this->submethod], F->getNvar() ); gsl_multimin_fdfminimizer_set(solverqn, &fdfqn, x_vec, stepqn, this->tol); status_dx = GSL_CONTINUE; break; case SLRA_OPT_METHOD_NM: /* NM */ solvernm = gsl_multimin_fminimizer_alloc(Tnm[this->submethod], F->getNvar()); stepnm = gsl_vector_alloc(F->getNvar()); gsl_vector_set_all(stepnm, this->step); gsl_multimin_fminimizer_set( solvernm, &fnm, x_vec, stepnm ); break; } /* optimization loop */ Log::lprintf(Log::LOG_LEVEL_FINAL, "SLRA optimization:\n"); status = GSL_SUCCESS; status_dx = GSL_CONTINUE; status_grad = GSL_CONTINUE; this->iter = 0; switch (this->method) { case SLRA_OPT_METHOD_LM: gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); gsl_multifit_gradient(solverlm->J, solverlm->f, g); gsl_vector_scale(g, 2); { gsl_vector *g2 = gsl_vector_alloc(g->size); F->computeFuncAndGrad(x_vec, NULL, g2); gsl_vector_sub(g2, g); if (gsl_vector_max(g2) > 1e-10 || gsl_vector_min(g2) < -1e-10) { Log::lprintf(Log::LOG_LEVEL_NOTIFY, "Gradient error, max = %14.10f, min = %14.10f ...", gsl_vector_max(g2), gsl_vector_min(g2)); print_vec(g2); } gsl_vector_free(g2); } if (itLog != NULL) { itLog->reportIteration(0, solverlm->x, this->fmin, g); } break; case SLRA_OPT_METHOD_QN: this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn); if (itLog != NULL) { itLog->reportIteration(0, solverqn->x, this->fmin, solverqn->gradient); } break; case SLRA_OPT_METHOD_NM: this->fmin = gsl_multimin_fminimizer_minimum( solvernm ); if (itLog != NULL) { itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL); } break; } while (status_dx == GSL_CONTINUE && status_grad == GSL_CONTINUE && status == GSL_SUCCESS && this->iter < this->maxiter) { if (this->method == SLRA_OPT_METHOD_LM && this->maxx > 0) { if (gsl_vector_max(solverlm->x) > this->maxx || gsl_vector_min(solverlm->x) < -this->maxx ){ break; } } this->iter++; switch (this->method) { case SLRA_OPT_METHOD_LM: /* Levenberg-Marquardt */ status = gsl_multifit_fdfsolver_iterate(solverlm); gsl_multifit_gradient(solverlm->J, solverlm->f, g); gsl_vector_scale(g, 2); /* check the convergence criteria */ if (this->epsabs != 0 || this->epsrel != 0) { status_dx = gsl_multifit_test_delta(solverlm->dx, solverlm->x, this->epsabs, this->epsrel); } else { status_dx = GSL_CONTINUE; } status_grad = gsl_multifit_test_gradient(g, this->epsgrad); gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); if (itLog != NULL) { itLog->reportIteration(this->iter, solverlm->x, this->fmin, g); } break; case SLRA_OPT_METHOD_QN: status = gsl_multimin_fdfminimizer_iterate( solverqn ); /* check the convergence criteria */ status_grad = gsl_multimin_test_gradient( gsl_multimin_fdfminimizer_gradient(solverqn), this->epsgrad); status_dx = gsl_multifit_test_delta(solverqn->dx, solverqn->x, this->epsabs, this->epsrel); this->fmin = gsl_multimin_fdfminimizer_minimum(solverqn); if (itLog != NULL) { itLog->reportIteration(this->iter, solverqn->x, this->fmin, solverqn->gradient); } break; case SLRA_OPT_METHOD_NM: status = gsl_multimin_fminimizer_iterate( solvernm ); /* check the convergence criteria */ size = gsl_multimin_fminimizer_size( solvernm ); status_dx = gsl_multimin_test_size( size, this->epsx ); this->fmin = gsl_multimin_fminimizer_minimum( solvernm ); if (itLog != NULL) { itLog->reportIteration(this->iter, solvernm->x, this->fmin, NULL); } break; } } if (this->iter >= this->maxiter) { status = EITER; } switch (this->method) { case SLRA_OPT_METHOD_LM: gsl_vector_memcpy(x_vec, solverlm->x); if (v != NULL) { gsl_multifit_covar(solverlm->J, this->epscov, v); /* ??? Different eps */ } gsl_blas_ddot(solverlm->f, solverlm->f, &this->fmin); break; case SLRA_OPT_METHOD_QN: gsl_vector_memcpy(x_vec, solverqn->x); this->fmin = solverqn->f; break; case SLRA_OPT_METHOD_NM: gsl_vector_memcpy(x_vec, solvernm->x); this->fmin = solvernm->fval; break; } /* print exit information */ if (Log::getMaxLevel() >= Log::LOG_LEVEL_FINAL) { /* unless "off" */ switch (status) { case EITER: Log::lprintf("SLRA optimization terminated by reaching " "the maximum number of iterations.\n" "The result could be far from optimal.\n"); break; case GSL_ETOLF: Log::lprintf("Lack of convergence: " "progress in function value < machine EPS.\n"); break; case GSL_ETOLX: Log::lprintf("Lack of convergence: " "change in parameters < machine EPS.\n"); break; case GSL_ETOLG: Log::lprintf("Lack of convergence: " "change in gradient < machine EPS.\n"); break; case GSL_ENOPROG: Log::lprintf("Possible lack of convergence: no progress.\n"); break; } if (status_grad != GSL_CONTINUE && status_dx != GSL_CONTINUE) { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for both X and the gradient.\n"); } else { if (status_grad != GSL_CONTINUE) { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for the gradient.\n"); } else { Log::lprintf("Optimization terminated by reaching the convergence " "tolerance for X.\n"); } } } /* Cleanup */ switch (this->method) { case SLRA_OPT_METHOD_LM: /* LM */ gsl_multifit_fdfsolver_free(solverlm); gsl_vector_free(g); break; case SLRA_OPT_METHOD_QN: /* QN */ gsl_multimin_fdfminimizer_free(solverqn); break; case SLRA_OPT_METHOD_NM: /* NM */ gsl_multimin_fminimizer_free(solvernm); gsl_vector_free(stepnm); break; } return GSL_SUCCESS; /* <- correct with status */ }
int main (int argc, char *argv[]) { printf("Number of haplotypes: %d\n", atoi(argv[1]) ); int temp =0; temp = atoi(argv[1]); printf("Number of time intervals: %d\n", atoi(argv[2]) ); printf("File name: %s\n", argv[3] ); int num_haps = atoi(argv[1]); int num_times = atoi(argv[2]); //make_bins(num_haps); //readfile(argv[3]); read_binned_file(argv[3]); //make_custom_bins(num_haps); // one bin per match length // printf("num_loci = %d\n", num_loci); // printf("marker %f\n", 1.7); // printf("a;lskdjf %d\n", 3); make_times(num_haps, num_times); read_quant_file(argv[4]); precompute(num_haps, num_times); /* struct scenario the_scenario; the_scenario.num_haps = argv[1]; the_scenario.num_times = argv[2];*/ size_t iter = 0; // size_t i; // commented out to fix the problem labelled XYRQ below // there was a comparison between signed/unsiged int int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; /* Position of the minimum (1,2). */ int j=0; double par[2]; par[0] = num_haps; par[1] = num_times; gsl_vector *x; gsl_multimin_function_fdf my_func; my_func.f = &my_f; my_func.df = &my_df; my_func.fdf = &my_fdf; my_func.n = num_times; my_func.params = ∥ /* Starting point, x = (5,7) */ x = gsl_vector_alloc (num_times); for (j=0; j<num_times; j++) { if(j<=50){gsl_vector_set (x, j, 30000 );} else {gsl_vector_set (x, j, 20000 );} } T = gsl_multimin_fdfminimizer_conjugate_fr; // T = gsl_multimin_fdfminimizer_vector_bfgs2; s = gsl_multimin_fdfminimizer_alloc (T, num_times); // likelihood setting gsl_multimin_fdfminimizer_set (s, &my_func, x, 10000, .000001); // quantile setting //gsl_multimin_fdfminimizer_set (s, &my_func, x, 3000.0, .100); do { iter++; status = gsl_multimin_fdfminimizer_iterate (s); //printf("help %d\n", 3); if (status){ printf ("Iteration terminated at:\nSTART HERE\n"); //printf ("%5zu ", iter); // using %zu instead of %d b/c iter is type size_t not type int int k=0; for (k = 0; k < num_times; k++) { printf ("%f\t%10.3f\n", time[k], gsl_vector_get (s->x, k)); // problem XYRQ // using k here renders size_t i above unused } printf ("f() = %7.3f \n", s->f); // q break;} //printf("help %d\n", 4); //.likelihood setting status = gsl_multimin_test_gradient (s->gradient, 1e-10 ); // quantile setting // status = gsl_multimin_test_gradient (s->gradient, .010 ); if (status == GSL_SUCCESS) { printf ("Minimum found at:\nSTART HERE\n");} int k=0; for (k = 0; k < num_times; k++) { printf ("%f\t%10.3f\n", time[k], gsl_vector_get (s->x, k)); // problem XYRQ // using k here renders size_t i above unused } //printf ("f() = %7.3f \n", s->f); // printf ("Minimum found at:\n"); // // printf ("%5zu ", iter); // using %zu instead of %d b/c iter is type size_t not type int // int k=0; // for (k = 0; k < num_times; k++) // { // printf ("%10.3e ", gsl_vector_get (s->x, k)); // problem XYRQ // using k here renders size_t i above unused // } // printf ("%5d %.5f %.5f %10.5f\n", iter, // gsl_vector_get (s->x, 0), // gsl_vector_get (s->x, 1), // s->f); } while (status == GSL_CONTINUE && iter < 1000); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); return 0; }
// maximize each model parameter given the hidden data estimated from // last iteration void MStep() { // optimization config double step_size = .01; double tol = .1; const double epsabs = .01; gsl_vector *init_x = gsl_vector_alloc(2); int status; double low = .0001, high = gene_nu * 20; int iter = 0; const int maxiter = 10; // optimize gene rate parameters gsl_root_fsolver_set(sol_gene_rate, &opt_gene_rate, low, high); status = GSL_CONTINUE; for (iter=0; iter<maxiter && status==GSL_CONTINUE; iter++) { // do one iteration status = gsl_root_fsolver_iterate(sol_gene_rate); if (status) break; // check convergence low = gsl_root_fsolver_x_lower(sol_gene_rate); high = gsl_root_fsolver_x_upper(sol_gene_rate); status = gsl_root_test_interval(low, high, 0, 0.01); } gene_nu = gsl_root_fsolver_root(sol_gene_rate); gene_alpha = gene_nu + 1; gene_beta = gene_nu; fprintf(stderr, "nu = %f (iter=%d)\n", gene_nu, iter); // optimize each species rate parmater set for (int i=0; i<nspecies; i++) { cur_species = i; gsl_vector_set(init_x, 0, sp_alpha[i]); gsl_vector_set(init_x, 1, sp_beta[i]); gsl_multimin_fdfminimizer_set(sol_sp_rate, &opt_sp_rate, init_x, step_size, tol); status = GSL_CONTINUE; for (iter=0; iter<maxiter && status==GSL_CONTINUE; iter++) { // do one iteration status = gsl_multimin_fdfminimizer_iterate(sol_sp_rate); if (status) break; // get gradient status = gsl_multimin_test_gradient(sol_sp_rate->gradient, epsabs); } double lk = likelihood(); fprintf(stderr, "species %d %d %f\n", i, iter, lk); sp_alpha[i] = gsl_vector_get(sol_sp_rate->x, 0); sp_beta[i] = gsl_vector_get(sol_sp_rate->x, 1); //printf("sp[%d] = (%f, %f)\n", i, sp_alpha[i], sp_beta[i]); } gsl_vector_free(init_x); }
arma::vec DIIS::get_w_adiis() const { // Number of parameters size_t N=PiF.n_elem; if(N==1) { // Trivial case. arma::vec ret(1); ret.ones(); return ret; } const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_vector *x; gsl_multimin_function_fdf minfunc; minfunc.f = adiis::min_f; minfunc.df = adiis::min_df; minfunc.fdf = adiis::min_fdf; minfunc.n = N; minfunc.params = (void *) this; T=gsl_multimin_fdfminimizer_vector_bfgs2; s=gsl_multimin_fdfminimizer_alloc(T,N); // Starting point: equal weights on all matrices x=gsl_vector_alloc(N); gsl_vector_set_all(x,1.0/N); // Initial energy estimate // double E_initial=get_E(x); // Initialize the optimizer. Use initial step size 0.02, and an // orthogonality tolerance of 0.1 in the line searches (recommended // by GSL manual for bfgs). gsl_multimin_fdfminimizer_set(s, &minfunc, x, 0.02, 0.1); size_t iter=0; int status; do { iter++; // printf("iteration %lu\n",iter); status = gsl_multimin_fdfminimizer_iterate (s); if (status) { // printf("Error %i in minimization\n",status); break; } status = gsl_multimin_test_gradient (s->gradient, 1e-7); /* if (status == GSL_SUCCESS) printf ("Minimum found at:\n"); printf("%5lu ", iter); for(size_t i=0;i<N;i++) printf("%.5g ",gsl_vector_get(s->x,i)); printf("%10.5g\n",s->f); */ } while (status == GSL_CONTINUE && iter < 1000); // Final estimate // double E_final=get_E(s->x); // Form minimum arma::vec c=adiis::compute_c(s->x); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); // printf("Minimized estimate of %lu matrices by %e from %e to %e in %lu iterations.\n",D.size(),E_final-E_initial,E_initial,E_final,iter); return c; }
bool GICPOptimizer::Optimize(dgc_transform_t t, GICPOptData & opt_data) { double line_search_tol = .01; double gradient_tol = 1e-2; double step_size = 1.; // set up the gsl function_fdf struct gsl_multimin_function_fdf func; func.f = f; func.df = df; func.fdf = fdf; func.n = N; func.params = &opt_data; // initialize the starting point double tx, ty, tz, rx, ry, rz; dgc_transform_get_translation(t, &tx, &ty, &tz); dgc_transform_get_rotation(t, &rx, &ry, &rz); gsl_vector_set(x, 0, tx); gsl_vector_set(x, 1, ty); gsl_vector_set(x, 2, tz); gsl_vector_set(x, 3, rx); gsl_vector_set(x, 4, ry); gsl_vector_set(x, 5, rz); // initialize the minimizer gsl_multimin_fdfminimizer_set(gsl_minimizer, &func, x, step_size, line_search_tol); //iterate the minimization algorithm using gsl primatives status = GSL_CONTINUE; iter = 0; if(debug) { cout << "iter\t\tf-value\t\tstatus" << endl; cout << iter << "\t\t" << gsl_minimizer->f << "\t\t" << Status() << endl; } while(status == GSL_CONTINUE && iter < max_iter) { iter++; status = gsl_multimin_fdfminimizer_iterate(gsl_minimizer); if(debug) cout << iter << "\t\t" << gsl_minimizer->f << "\t\t" << Status() <<endl; if(status) break; status = gsl_multimin_test_gradient (gsl_minimizer->gradient, gradient_tol); } if(status == GSL_SUCCESS || iter == max_iter) { //set t to the converged solution dgc_transform_identity(t); // apply the current state to the base apply_state(t, gsl_minimizer->x); //dgc_transform_print(t, "converged to:"); return true; } else { // the algorithm failed to converge return false; } }
int main(int argc, char **argv) { #ifdef _OPENMP printf("ERKALE - Geometry optimization from Hel, OpenMP version, running on %i cores.\n",omp_get_max_threads()); #else printf("ERKALE - Geometry optimization from Hel, serial version.\n"); #endif print_copyright(); print_license(); #ifdef SVNRELEASE printf("At svn revision %s.\n\n",SVNREVISION); #endif print_hostname(); if(argc!=2) { printf("Usage: $ %s runfile\n",argv[0]); return 0; } // Initialize libint init_libint_base(); // Initialize libderiv init_libderiv_base(); Timer tprog; tprog.print_time(); // Parse settings Settings set; set.add_scf_settings(); set.add_string("SaveChk","File to use as checkpoint","erkale.chk"); set.add_string("LoadChk","File to load old results from",""); set.add_bool("ForcePol","Force polarized calculation",false); set.add_bool("FreezeCore","Freeze the atomic cores?",false); set.add_string("Optimizer","Optimizer to use: CGFR, CGPR, BFGS, BFGS2 (default), SD","BFGS2"); set.add_int("MaxSteps","Maximum amount of geometry steps",256); set.add_string("Criterion","Convergence criterion to use: LOOSE, NORMAL, TIGHT, VERYTIGHT","NORMAL"); set.add_string("OptMovie","xyz movie to store progress in","optimize.xyz"); set.add_string("Result","File to save optimized geometry in","optimized.xyz"); set.set_string("Logfile","erkale_geom.log"); set.parse(std::string(argv[1]),true); set.print(); bool verbose=set.get_bool("Verbose"); int maxiter=set.get_int("MaxSteps"); std::string optmovie=set.get_string("OptMovie"); std::string result=set.get_string("Result"); // Interpret optimizer enum minimizer alg; std::string method=set.get_string("Optimizer"); if(stricmp(method,"CGFR")==0) alg=gCGFR; else if(stricmp(method,"CGPR")==0) alg=gCGPR; else if(stricmp(method,"BFGS")==0) alg=gBFGS; else if(stricmp(method,"BFGS2")==0) alg=gBFGS2; else if(stricmp(method,"SD")==0) alg=gSD; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Interpret optimizer enum convergence crit; method=set.get_string("Criterion"); if(stricmp(method,"LOOSE")==0) crit=LOOSE; else if(stricmp(method,"NORMAL")==0) crit=NORMAL; else if(stricmp(method,"TIGHT")==0) crit=TIGHT; else if(stricmp(method,"VERYTIGHT")==0) crit=VERYTIGHT; else { ERROR_INFO(); throw std::runtime_error("Unknown optimization method.\n"); } // Redirect output? std::string logfile=set.get_string("Logfile"); if(stricmp(logfile,"stdout")!=0) { // Redirect stdout to file FILE *outstream=freopen(logfile.c_str(),"w",stdout); if(outstream==NULL) { ERROR_INFO(); throw std::runtime_error("Unable to redirect output!\n"); } else fprintf(stderr,"\n"); } // Read in atoms. std::string atomfile=set.get_string("System"); const std::vector<atom_t> origgeom=load_xyz(atomfile); std::vector<atom_t> atoms(origgeom); // Are any atoms fixed? std::vector<size_t> dofidx; for(size_t i=0;i<atoms.size();i++) { bool fixed=false; if(atoms[i].el.size()>3) if(stricmp(atoms[i].el.substr(atoms[i].el.size()-3),"-Fx")==0) { fixed=true; atoms[i].el=atoms[i].el.substr(0,atoms[i].el.size()-3); } // Add to degrees of freedom if(!fixed) dofidx.push_back(i); } // Read in basis set BasisSetLibrary baslib; std::string basfile=set.get_string("Basis"); baslib.load_gaussian94(basfile); printf("\n"); // Save to output save_xyz(atoms,"Initial configuration",optmovie,false); // Minimizer options opthelper_t pars; pars.atoms=atoms; pars.baslib=baslib; pars.set=set; pars.dofidx=dofidx; /* Starting point */ gsl_vector *x = gsl_vector_alloc (3*dofidx.size()); for(size_t i=0;i<dofidx.size();i++) { gsl_vector_set(x,3*i,atoms[dofidx[i]].x); gsl_vector_set(x,3*i+1,atoms[dofidx[i]].y); gsl_vector_set(x,3*i+2,atoms[dofidx[i]].z); } // GSL status int status; const gsl_multimin_fdfminimizer_type *T; gsl_multimin_fdfminimizer *s; gsl_multimin_function_fdf minimizer; minimizer.n = x->size; minimizer.f = calc_E; minimizer.df = calc_f; minimizer.fdf = calc_Ef; minimizer.params = (void *) &pars; if(alg==gCGFR) { T = gsl_multimin_fdfminimizer_conjugate_fr; if(verbose) printf("Using Fletcher-Reeves conjugate gradients.\n"); } else if(alg==gCGPR) { T = gsl_multimin_fdfminimizer_conjugate_pr; if(verbose) printf("Using Polak-Ribière conjugate gradients.\n"); } else if(alg==gBFGS) { T = gsl_multimin_fdfminimizer_vector_bfgs; if(verbose) printf("Using the BFGS minimizer.\n"); } else if(alg==gBFGS2) { T = gsl_multimin_fdfminimizer_vector_bfgs2; if(verbose) printf("Using the BFGS2 minimizer.\n"); } else if(alg==gSD) { T = gsl_multimin_fdfminimizer_steepest_descent; if(verbose) printf("Using the steepest descent minimizer.\n"); } else { ERROR_INFO(); throw std::runtime_error("Unsupported minimizer\n"); } // Run an initial calculation double oldE=calc_E(x,minimizer.params); // Turn off verbose setting pars.set.set_bool("Verbose",false); // and load from old checkpoint pars.set.set_string("LoadChk",pars.set.get_string("SaveChk")); // Initialize minimizer s = gsl_multimin_fdfminimizer_alloc (T, minimizer.n); // Use initial step length of 0.02 bohr, and a line search accuracy // 1e-1 (recommended in the GSL manual for BFGS) gsl_multimin_fdfminimizer_set (s, &minimizer, x, 0.02, 1e-1); // Store old force arma::mat oldf=interpret_force(s->gradient); fprintf(stderr,"Geometry optimizer initialized in %s.\n",tprog.elapsed().c_str()); fprintf(stderr,"Entering minimization loop with %s optimizer.\n",set.get_string("Optimizer").c_str()); fprintf(stderr,"%4s %16s %10s %10s %9s %9s %9s %9s %s\n","iter","E","dE","dE/dEproj","disp max","disp rms","f max","f rms", "titer"); std::vector<atom_t> oldgeom(atoms); bool convd=false; int iter; for(iter=1;iter<=maxiter;iter++) { printf("\nGeometry iteration %i\n",(int) iter); fflush(stdout); Timer titer; status = gsl_multimin_fdfminimizer_iterate (s); if (status) { fprintf(stderr,"GSL encountered error: \"%s\".\n",gsl_strerror(status)); break; } // New geometry is std::vector<atom_t> geom=get_atoms(s->x,pars); // Calculate displacements double dmax, drms; get_displacement(geom, oldgeom, dmax, drms); // Calculate projected change of energy double dEproj=calculate_projection(geom,oldgeom,oldf,pars.dofidx); // Actual change of energy is double dE=s->f - oldE; // Switch geometries oldgeom=geom; // Save old force // Get forces double fmax, frms; get_forces(s->gradient, fmax, frms); // Save geometry step char comment[80]; sprintf(comment,"Step %i",(int) iter); save_xyz(get_atoms(s->x,pars),comment,optmovie,true); // Check convergence bool fmaxconv=false, frmsconv=false; bool dmaxconv=false, drmsconv=false; switch(crit) { case(LOOSE): if(fmax < 2.5e-3) fmaxconv=true; if(frms < 1.7e-3) frmsconv=true; if(dmax < 1.0e-2) dmaxconv=true; if(drms < 6.7e-3) drmsconv=true; break; case(NORMAL): if(fmax < 4.5e-4) fmaxconv=true; if(frms < 3.0e-4) frmsconv=true; if(dmax < 1.8e-3) dmaxconv=true; if(drms < 1.2e-3) drmsconv=true; break; case(TIGHT): if(fmax < 1.5e-5) fmaxconv=true; if(frms < 1.0e-5) frmsconv=true; if(dmax < 6.0e-5) dmaxconv=true; if(drms < 4.0e-5) drmsconv=true; break; case(VERYTIGHT): if(fmax < 2.0e-6) fmaxconv=true; if(frms < 1.0e-6) frmsconv=true; if(dmax < 6.0e-6) dmaxconv=true; if(drms < 4.0e-6) drmsconv=true; break; default: ERROR_INFO(); throw std::runtime_error("Not implemented!\n"); } // Converged? const static char cconv[]=" *"; double dEfrac; if(dEproj!=0.0) dEfrac=dE/dEproj; else dEfrac=0.0; fprintf(stderr,"%4d % 16.8f % .3e % .3e %.3e%c %.3e%c %.3e%c %.3e%c %s\n", (int) iter, s->f, dE, dEfrac, dmax, cconv[dmaxconv], drms, cconv[drmsconv], fmax, cconv[fmaxconv], frms, cconv[frmsconv], titer.elapsed().c_str()); fflush(stderr); convd=dmaxconv && drmsconv && fmaxconv && frmsconv; if(convd) { fprintf(stderr,"Converged.\n"); break; } // Store old energy oldE=s->f; // Store old force oldf=interpret_force(s->gradient); } if(convd) save_xyz(get_atoms(s->x,pars),"Optimized geometry",result); gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); if(iter==maxiter && !convd) { printf("Geometry convergence was not achieved!\n"); } printf("Running program took %s.\n",tprog.elapsed().c_str()); return 0; }
// Relax the map void rmap_relax(rmap_t *self, int num_cycles) { int i, n; gsl_vector *x, *y; gsl_multimin_function_fdf fdf; gsl_multimin_fdfminimizer *s; double step_size, tol; rmap_scan_t *scan; // HACK step_size = 0.01; tol = 0.001; // Compute number of free variables n = 3 * self->num_key_scans; // Set the initial vector x = gsl_vector_alloc(n); for (i = 0; i < self->num_scans; i++) { scan = self->scans + i; if (scan->index >= 0) { gsl_vector_set(x, 3 * scan->index + 0, scan->pose.pos.x); gsl_vector_set(x, 3 * scan->index + 1, scan->pose.pos.y); gsl_vector_set(x, 3 * scan->index + 2, scan->pose.rot); } } // Allocate minimizer fdf.f = (double (*) (const gsl_vector*, void*)) rmap_fit_f; fdf.df = (void (*) (const gsl_vector*, void*, gsl_vector*)) rmap_fit_df; fdf.fdf = (void (*) (const gsl_vector*, void*, double*, gsl_vector*)) rmap_fit_fdf; fdf.n = n; fdf.params = self; s = gsl_multimin_fdfminimizer_alloc(gsl_multimin_fdfminimizer_vector_bfgs, n); // Initialize minimizer gsl_multimin_fdfminimizer_set(s, &fdf, x, step_size, tol); // Optimize for (i = 0; i < num_cycles; i++) { if (gsl_multimin_fdfminimizer_iterate(s) != GSL_SUCCESS) break; } self->relax_err = gsl_multimin_fdfminimizer_minimum(s); // Copy corrections back to data structures y = gsl_multimin_fdfminimizer_x(s); for (i = 0; i < self->num_scans; i++) { scan = self->scans + i; if (scan->index >= 0) { scan->delta.pos.x = gsl_vector_get(y, 3 * scan->index + 0) - scan->pose.pos.x; scan->delta.pos.y = gsl_vector_get(y, 3 * scan->index + 1) - scan->pose.pos.y; scan->delta.rot = gsl_vector_get(y, 3 * scan->index + 2) - scan->pose.rot; } } // Clean up gsl_multimin_fdfminimizer_free(s); gsl_vector_free(x); return; }
int FC_FUNC_(oct_minimize, OCT_MINIMIZE) (const int *method, const int *dim, double *point, const double *step, const double *line_tol, const double *tolgrad, const double *toldr, const int *maxiter, func_d f, const print_f_ptr write_info, double *minimum) { int iter = 0; int status; double maxgrad, maxdr; int i; double * oldpoint; double * grad; const gsl_multimin_fdfminimizer_type *T = NULL; gsl_multimin_fdfminimizer *s; gsl_vector *x; gsl_vector *absgrad, *absdr; gsl_multimin_function_fdf my_func; param_fdf_t p; p.func = f; oldpoint = (double *) malloc(*dim * sizeof(double)); grad = (double *) malloc(*dim * sizeof(double)); my_func.f = &my_f; my_func.df = &my_df; my_func.fdf = &my_fdf; my_func.n = *dim; my_func.params = (void *) &p; /* Starting point */ x = gsl_vector_alloc (*dim); for(i=0; i<*dim; i++) gsl_vector_set (x, i, point[i]); /* Allocate space for the gradient */ absgrad = gsl_vector_alloc (*dim); absdr = gsl_vector_alloc (*dim); //GSL recommends line_tol = 0.1; switch(*method){ case 1: T = gsl_multimin_fdfminimizer_steepest_descent; break; case 2: T = gsl_multimin_fdfminimizer_conjugate_fr; break; case 3: T = gsl_multimin_fdfminimizer_conjugate_pr; break; case 4: T = gsl_multimin_fdfminimizer_vector_bfgs; break; case 5: T = gsl_multimin_fdfminimizer_vector_bfgs2; break; } s = gsl_multimin_fdfminimizer_alloc (T, *dim); gsl_multimin_fdfminimizer_set (s, &my_func, x, *step, *line_tol); do { iter++; for(i=0; i<*dim; i++) oldpoint[i] = point[i]; /* Iterate */ status = gsl_multimin_fdfminimizer_iterate (s); /* Get current minimum, point and gradient */ *minimum = gsl_multimin_fdfminimizer_minimum(s); for(i=0; i<*dim; i++) point[i] = gsl_vector_get(gsl_multimin_fdfminimizer_x(s), i); for(i=0; i<*dim; i++) grad[i] = gsl_vector_get(gsl_multimin_fdfminimizer_gradient(s), i); /* Compute convergence criteria */ for(i=0; i<*dim; i++) gsl_vector_set(absdr, i, fabs(point[i]-oldpoint[i])); maxdr = gsl_vector_max(absdr); for(i=0; i<*dim; i++) gsl_vector_set(absgrad, i, fabs(grad[i])); maxgrad = gsl_vector_max(absgrad); /* Print information */ write_info(&iter, dim, minimum, &maxdr, &maxgrad, point); /* Store infomation for next iteration */ for(i=0; i<*dim; i++) oldpoint[i] = point[i]; if (status) break; if ( (maxgrad <= *tolgrad) || (maxdr <= *toldr) ) status = GSL_SUCCESS; else status = GSL_CONTINUE; } while (status == GSL_CONTINUE && iter <= *maxiter); if(status == GSL_CONTINUE) status = 1025; gsl_multimin_fdfminimizer_free (s); gsl_vector_free (x); gsl_vector_free(absgrad); gsl_vector_free(absdr); free(oldpoint); free(grad); return status; }