// Cleanup allocations done during evolve. void gsl_gradient::cleanup(gsl_vector *x, gsl_multimin_fdfminimizer *s) { if (x) { gsl_vector_free(x); } if (s) { gsl_multimin_fdfminimizer_free(s); } }
GSLFDFSolver::~GSLFDFSolver() { if(gslSolver_ != NULL) { free(gslSolver_->x->block); free(gslSolver_->gradient->block); gsl_multimin_fdfminimizer_free(gslSolver_); } }
void GSLFDFSolver::doSetup_(const Function &objFunc, const vector< double > &x0, const Solver::Setup &solverSetup, const Constraints &C) { const int n = objFunc.getN(); double stepSize, tol; NativeGradientSolver::doSetup_(objFunc, x0, solverSetup, C); if(typeid(solverSetup) == typeid(Solver::DefaultSetup)) { stepSize = 1.0; tol = 0.1; } else { stepSize = dynamic_cast< const GSLFDFSolver::Setup & >(solverSetup).stepSize; tol = dynamic_cast< const GSLFDFSolver::Setup & >(solverSetup).tol; } if(gslSolver_ != NULL) { free(gslSolver_->x->block); free(gslSolver_->gradient->block); gsl_multimin_fdfminimizer_free(gslSolver_); } gslSolver_ = gsl_multimin_fdfminimizer_alloc(type_, n); // THIS IS A HACK! free(gslSolver_->x->block->data); gslSolver_->x->data = gslSolver_->x->block->data = &state_.x[0]; gslSolver_->x->owner = 0; gslSolver_->x->size = n; gslSolver_->x->stride = 1; free(gslSolver_->gradient->block->data); gslSolver_->gradient->data = gslSolver_->gradient->block->data = &state_.g[0]; gslSolver_->gradient->owner = 0; gslSolver_->gradient->size = n; gslSolver_->gradient->stride = 1; // !!!!!!!!!!!!!!! gslFunction_.n = n; gslFunction_.params = NULL; gslFunction_.f = &gslutils::f; // by using a pointer-to-member it would be something like this: // (double (*)(const gsl_vector *, void *))(gslWrapper_.*(&GSLWrapper::f)); gslFunction_.df = &gslutils::df; gslFunction_.fdf = &gslutils::fdf; gslutils::setFunction(setup_->f); gsl_vector *x0_ = gsl_vector_alloc(n); gslutils::BoostToGSLVector(x0, x0_); gsl_multimin_fdfminimizer_set(gslSolver_, &gslFunction_, x0_, stepSize, tol); gsl_vector_free(x0_); }
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; }
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; }
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); }
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); }
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; }
~RatesEM() { //gsl_root_fdfsolver_free(sol_gene_rate); gsl_root_fsolver_free(sol_gene_rate); gsl_multimin_fdfminimizer_free(sol_sp_rate); }
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; }
void multimin(size_t n,double *x,double *fun, const unsigned *type, const double *xmin,const double *xmax, void (*f) (const size_t,const double *,void *,double *), void (* df) (const size_t,const double *, void *,double *), void (* fdf) (const size_t,const double *, void *,double *,double *), void *fparams, const struct multimin_params oparams) { unsigned iter=0; int status; size_t i; double dtmp1; const gsl_multimin_fdfminimizer_type *Tfdf; const gsl_multimin_fminimizer_type *Tf; const char *Tname; gsl_vector * y = gsl_vector_alloc (n); /* set the algorithm */ switch(oparams.method){ case 0:/* Fletcher-Reeves conjugate gradient */ Tfdf = gsl_multimin_fdfminimizer_conjugate_fr; Tname = Tfdf->name; break; case 1:/* Polak-Ribiere conjugate gradient */ Tfdf = gsl_multimin_fdfminimizer_conjugate_pr; Tname = Tfdf->name; break; case 2:/* Vector Broyden-Fletcher-Goldfarb-Shanno method */ Tfdf = gsl_multimin_fdfminimizer_vector_bfgs; Tname = Tfdf->name; break; case 3:/* Steepest descent algorithm */ Tfdf =gsl_multimin_fdfminimizer_steepest_descent; Tname = Tfdf->name; break; case 4:/* Simplex */ Tf = gsl_multimin_fminimizer_nmsimplex2; Tname = Tf->name; break; case 5:/* Vector Broyden-Fletcher-Goldfarb-Shanno2 method */ Tfdf = gsl_multimin_fdfminimizer_vector_bfgs2; Tname = Tfdf->name; break; default: fprintf(stderr,"Optimization method not recognized. Try -h\n"); exit(EXIT_FAILURE); } /* --- OUPUT ---------------------------------- */ if(oparams.verbosity>0){ fprintf(stderr,"#--- MULTIMIN START\n"); fprintf(stderr,"# method %s\n",Tname); if(oparams.method<4 || oparams.method==5){ fprintf(stderr,"# initial step size %g\n", oparams.step_size); fprintf(stderr,"# line minimization tolerance %g\n",oparams.tol); fprintf(stderr,"# maximum number of iterations %u\n",oparams.maxiter); fprintf(stderr,"# precision %g\n",oparams.epsabs); } else{ fprintf(stderr,"# maximum number of iterations %u\n",oparams.maxiter); fprintf(stderr,"# maximum simplex size %g\n",oparams.maxsize); } } /* -------------------------------------------- */ /* compute values of y for initial condition */ for(i=0;i<n;i++){ if(type==NULL) SET(y,i,x[i]); else switch(type[i]){ case 0:/* (-inf,+inf) */ SET(y,i,x[i]); break; case 1:/* [a,+inf) */ SET(y,i,sqrt( x[i]-xmin[i] )); break; case 2:/* (-inf,a] */ SET(y,i,sqrt( xmax[i]-x[i] )); break; case 3:/* [a,b] */ dtmp1 = (xmax[i]>xmin[i]? (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]) : 0); /* dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]); */ SET(y,i,asin( dtmp1 )); break; case 4:/* (a,+inf) */ SET(y,i,log( x[i]-xmin[i] )); break; case 5:/* (-inf,a) */ SET(y,i,log( xmax[i]-x[i] )); break; case 6:/* (a,b) */ dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]); SET(y,i,gsl_atanh ( dtmp1 )); break; case 7:/* (a,b) second approach */ dtmp1 = (2.*x[i]-xmax[i]-xmin[i])/(xmax[i]-xmin[i]); SET(y,i, dtmp1/sqrt(1-dtmp1*dtmp1)); break; case 8:/* (a,+inf) second approach */ dtmp1 = x[i]-xmin[i]; SET(y,i, dtmp1-1./(4.*dtmp1)); break; } } /* --- OUPUT ---------------------------------- */ if(oparams.verbosity>1){ fprintf(stderr,"# - variables initial value and boundaries\n"); for(i=0;i<n;i++){ if(type==NULL) fprintf(stderr,"# x[%d]=%e (-inf,+inf) -> %e\n",(int) i,x[i],GET(y,i)); else switch(type[i]){ case 0:/* (-inf,+inf) */ fprintf(stderr,"# x[%d]=%e (-inf,+inf) -> %e\n",(int) i,x[i],GET(y,i)); break; case 1:/* [a,+inf) */ fprintf(stderr,"# x[%d]=%e [%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i)); break; case 2:/* (-inf,a] */ fprintf(stderr,"# x[%d]=%e (-inf,%g] -> %e\n",(int) i,x[i],xmax[i],GET(y,i)); break; case 3:/* [a,b] */ fprintf(stderr,"# x[%d]=%e [%g,%g] -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i)); break; case 4:/* (a,+inf) */ fprintf(stderr,"# x[%d]=%e (%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i)); break; case 5:/* (-inf,a) */ fprintf(stderr,"# x[%d]=%e (-inf,%g) -> %e\n",(int) i,x[i],xmax[i],GET(y,i)); break; case 6:/* (a,b) */ case 7: fprintf(stderr,"# x[%d]=%e (%g,%g) -> %e\n",(int) i,x[i],xmin[i],xmax[i],GET(y,i)); break; case 8:/* [a,+inf) */ fprintf(stderr,"# x[%d]=%e (%g,+inf) -> %e\n",(int) i,x[i],xmin[i],GET(y,i)); break; } } { double res; fprintf(stderr,"# - function initial value\n"); f(n,x,fparams,&res); fprintf(stderr,"# f=%e\n",res); } } /* -------------------------------------------- */ if(oparams.method<4 || oparams.method==5){/* methods with derivatives */ struct g_params gparams; gsl_multimin_function_fdf GdG; gsl_multimin_fdfminimizer *s = gsl_multimin_fdfminimizer_alloc (Tfdf,n); /* set the parameters of the new function */ gparams.n = n; gparams.type = type; gparams.xmin = xmin; gparams.xmax = xmax; gparams.f = f; gparams.df = df; gparams.fdf = fdf; gparams.fparams = fparams; /* set the function to solve */ GdG.f=g; GdG.df=dg; GdG.fdf=gdg; GdG.n=n; GdG.params=(void *) &gparams; /* initialize minimizer */ status=gsl_multimin_fdfminimizer_set(s,&GdG,y,oparams.step_size,oparams.tol); if(status) { fprintf(stderr,"#ERROR: %s\n",gsl_strerror (status)); exit(EXIT_FAILURE); } /* +++++++++++++++++++++++++++++++++++++++++++++++ */ if(oparams.verbosity>2) fprintf(stderr,"# - start minimization \n"); /* +++++++++++++++++++++++++++++++++++++++++++++++ */ do { iter++; status = gsl_multimin_fdfminimizer_iterate (s); /* +++++++++++++++++++++++++++++++++++++++++++++++ */ if(oparams.verbosity>2){ fprintf(stderr,"# [%d]",iter); fprintf(stderr," g=%+12.6e y=( ",s->f); for(i=0;i<n;i++) fprintf(stderr,"%+12.6e ",GET(s->x,i)); fprintf(stderr,") dg=( "); for(i=0;i<n;i++) fprintf(stderr,"%+12.6e ",GET(s->gradient,i)); fprintf(stderr,") |dg|=%12.6e ",gsl_blas_dnrm2 (s->gradient)); fprintf(stderr,"|dx|=%12.6e\n",gsl_blas_dnrm2 (s->dx)); } /* +++++++++++++++++++++++++++++++++++++++++++++++ */ if(status == GSL_ENOPROG){ fprintf(stderr,"# status: %s\n",gsl_strerror (status)); break; } if(status){ fprintf(stderr,"#WARNING: %s\n", gsl_strerror (status)); break; } /* { */ /* const double eps = oparams.epsabs; */ /* const double norm_x = gsl_blas_dnrm2 (s->x); */ /* const double norm_dx = gsl_blas_dnrm2 (s->dx); */ /* const double norm_g = gsl_blas_dnrm2 (s->gradient); */ /* if( norm_dx < eps && norm_dx < norm_x*eps && norm_g < eps ) */ /* status = GSL_SUCCESS; */ /* else */ /* status = GSL_CONTINUE; */ /* fprintf(stderr,"|x|=%f |dx|=%f |dg|=%f\n",norm_x,norm_dx,norm_g); */ /* } */ status = gsl_multimin_test_gradient (s->gradient,oparams.epsabs); } while (status == GSL_CONTINUE && iter < oparams.maxiter); gsl_vector_memcpy (y,s->x); *fun=s->f; gsl_multimin_fdfminimizer_free (s); } else{ /* methods without derivatives */ gsl_vector *ss = gsl_vector_alloc (n); struct g_params gparams; gsl_multimin_function G; gsl_multimin_fminimizer *s=gsl_multimin_fminimizer_alloc (Tf,n); /* set the parameters of the new function */ gparams.n = n; gparams.type = type; gparams.xmin = xmin; gparams.xmax = xmax; gparams.f = f; gparams.fparams = fparams; /* set the function to solve */ G.f=g; G.n=n; G.params=(void *) &gparams; /* Initial vertex size vector */ { /* size_t i; */ /* dg(y,&gparams,ss); */ /* gsl_vector_set_all (ss,1); */ /* for(i=0;i<n;i++) */ /* SET(ss,i,fabs(GET(ss,i))); */ /* gsl_vector_add_constant (ss,oparams.maxsize); */ gsl_vector_set_all (ss,oparams.step_size+oparams.maxsize); } /* --- OUPUT ---------------------------------- */ if(oparams.verbosity>0){ size_t i; fprintf(stderr,"# initial simplex sizes\n"); fprintf(stderr,"# "); for(i=0;i<n;i++) fprintf(stderr," %g", GET(ss,i)); fprintf(stderr,"\n"); } /* -------------------------------------------- */ /* Initialize minimizer */ status=gsl_multimin_fminimizer_set(s,&G,y,ss); do { status = gsl_multimin_fminimizer_iterate(s); const double size = gsl_multimin_fminimizer_size (s); iter++; /* +++++++++++++++++++++++++++++++++++++++++++++++ */ if(oparams.verbosity>2){ fprintf(stderr,"# g=%g y=( ",s->fval); for(i=0;i<n;i++) fprintf(stderr,"%g ",GET(s->x,i)); fprintf(stderr,") "); fprintf(stderr," simplex size=%g ",size); fprintf(stderr,"\n"); } /* +++++++++++++++++++++++++++++++++++++++++++++++ */ status=gsl_multimin_test_size (size,oparams.maxsize); } while (status == GSL_CONTINUE && iter < oparams.maxiter); gsl_vector_memcpy (y, s->x); *fun=s->fval; gsl_multimin_fminimizer_free (s); gsl_vector_free(ss); } /* compute values of x */ for(i=0;i<n;i++){ if(type==NULL) /* (-inf,+inf) */ x[i]=GET(y,i); else switch(type[i]){ case 0:/* (-inf,+inf) */ x[i]=GET(y,i); break; case 1:/* [a,+inf) */ x[i]=xmin[i]+GET(y,i)*GET(y,i); break; case 2:/* (-inf,a] */ x[i]=xmax[i]-GET(y,i)*GET(y,i); break; case 3:/* [a,b] */ dtmp1 = sin( GET(y,i) ); x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1)); break; case 4:/* (a,+inf) */ dtmp1 = exp( GET(y,i) ); x[i]=xmin[i]+dtmp1; break; case 5:/* (-inf,a) */ dtmp1 = -exp( GET(y,i) ); x[i]=xmax[i]+dtmp1; break; case 6:/* (a,b) */ dtmp1 = tanh( GET(y,i) ); x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1)); break; case 7:/* (a,b) second approach */ dtmp1 = GET(y,i) ; dtmp1 = dtmp1/sqrt(1.+dtmp1*dtmp1); x[i]=.5*(xmin[i]*(1-dtmp1) +xmax[i]*(1+dtmp1)); break; case 8:/* (a,+inf) second approach */ dtmp1 = sqrt(1.+GET(y,i)*GET(y,i)); x[i]= xmin[i] + .5*(dtmp1+GET(y,i)); break; } } /* --- OUPUT ---------------------------------- */ if(oparams.verbosity>0){ fprintf(stderr,"# - end minimization\n"); fprintf(stderr,"# iterations %u\n",iter); for(i=0;i<n;i++) fprintf(stderr,"# %e -> x[%zd]=%e\n",GET(y,i),i,x[i]); fprintf(stderr,"#--- MULTIMIN END --- \n"); } /* -------------------------------------------- */ gsl_vector_free (y); }
GslMinimizerHolder::Instance::~Instance () { gsl_multimin_fdfminimizer* &gslMinimizer( *this ); gsl_multimin_fdfminimizer_free( gslMinimizer ); gslMinimizer = NULL; }
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; }
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; }
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 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; }
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; }
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; }
int lua_multimin_minimize(lua_State * L) { bool ssdel=false; double eps=0.00001; double tol=0.0001; double step_size=0.01; int maxiter=1000; bool print=false; array<double> * x=0; array<double> * ss=0; const gsl_multimin_fminimizer_type *Tf = 0; const gsl_multimin_fdfminimizer_type *Tdf = 0; multi_param mp; mp.L=L; mp.fdf_index=-1; lua_pushstring(L,"f"); lua_gettable(L,-2); if(lua_isfunction(L,-1)) { mp.f_index=luaL_ref(L, LUA_REGISTRYINDEX); } else { luaL_error(L,"%s\n","missing function"); } lua_pushstring(L,"df"); lua_gettable(L,-2); if(lua_isfunction(L,-1)) { mp.df_index=luaL_ref(L, LUA_REGISTRYINDEX); Tdf= gsl_multimin_fdfminimizer_conjugate_fr; } else { lua_pop(L,1); Tf= gsl_multimin_fminimizer_nmsimplex2; } lua_pushstring(L,"fdf"); lua_gettable(L,-2); if(lua_isfunction(L,-1)) { mp.fdf_index=luaL_ref(L, LUA_REGISTRYINDEX); } else { lua_pop(L,1); mp.fdf_index=-1; } lua_pushstring(L,"algorithm"); lua_gettable(L,-2); if(lua_isstring(L,-1)) { if(Tf!=0) { if(!strcmp(lua_tostring(L,-1),"nmsimplex")) { Tf = gsl_multimin_fminimizer_nmsimplex; } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2rand")) { Tf = gsl_multimin_fminimizer_nmsimplex2rand; } else if(!strcmp(lua_tostring(L,-1),"nmsimplex2")) { Tf = gsl_multimin_fminimizer_nmsimplex2; } else { luaL_error(L,"%s\n","invalid algorithm"); } } else { if(!strcmp(lua_tostring(L,-1),"conjugate_pr")) { Tdf = gsl_multimin_fdfminimizer_conjugate_pr; } else if(!strcmp(lua_tostring(L,-1),"steepest_descent")) { Tdf = gsl_multimin_fdfminimizer_steepest_descent; } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs")) { Tdf = gsl_multimin_fdfminimizer_vector_bfgs; } else if(!strcmp(lua_tostring(L,-1),"vector_bfgs2")) { Tdf = gsl_multimin_fdfminimizer_vector_bfgs2; } else if(!strcmp(lua_tostring(L,-1),"conjugate_fr")) { Tdf = gsl_multimin_fdfminimizer_conjugate_fr; } else { luaL_error(L,"%s\n","invalid algorithm"); } } } lua_pop(L,1); lua_pushstring(L,"show_iterations"); lua_gettable(L,-2); if(lua_isboolean(L,-1)) { print=(lua_toboolean(L,-1)==1); } lua_pop(L,1); lua_pushstring(L,"eps"); lua_gettable(L,-2); if(lua_isnumber(L,-1)) { eps=lua_tonumber(L,-1); } lua_pop(L,1); lua_pushstring(L,"step_size"); lua_gettable(L,-2); if(lua_isnumber(L,-1)) { step_size=lua_tonumber(L,-1); } lua_pop(L,1); lua_pushstring(L,"tol"); lua_gettable(L,-2); if(lua_isnumber(L,-1)) { tol=lua_tonumber(L,-1); } lua_pop(L,1); lua_pushstring(L,"maxiter"); lua_gettable(L,-2); if(lua_isnumber(L,-1)) { maxiter=(int)lua_tonumber(L,-1); } lua_pop(L,1); lua_pushstring(L,"starting_point"); lua_gettable(L,-2); if(!lua_isuserdata(L,-1)) lua_error(L); if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&x,SWIGTYPE_p_arrayT_double_t,0))){ luaL_error(L,"%s\n","missing starting point"); } lua_pop(L,1); if(Tf) { lua_pushstring(L,"step_sizes"); lua_gettable(L,-2); if(lua_isuserdata(L,-1)) { if (!SWIG_IsOK(SWIG_ConvertPtr(L,-1,(void**)&ss,SWIGTYPE_p_arrayT_double_t,0))){ lua_error(L); } } else { ssdel=true; ss=new array<double>(x->size()); ss->set_all(1.0); if(lua_isnumber(L,-1)) { double v=lua_tonumber(L,-1); ss->set_all(v); } } lua_pop(L,1); } lua_pop(L,1); if(Tf) { gsl_multimin_fminimizer *s = NULL; gsl_vector SS, X; gsl_multimin_function minex_func; int iter = 0; int status; double size; int N=x->size(); /* Starting point */ X.size=x->size(); X.stride=1; X.data=x->data(); X.owner=0; /* Set initial step sizes */ SS.size=ss->size(); SS.stride=1; SS.data=ss->data(); SS.owner=0; /* Initialize method and iterate */ minex_func.n = N; minex_func.f = multimin_f_cb; minex_func.params = ∓ s = gsl_multimin_fminimizer_alloc (Tf, N); gsl_multimin_fminimizer_set (s, &minex_func, &X, &SS); if(print) printf ("running algorithm '%s'\n", gsl_multimin_fminimizer_name (s)); do { iter++; status = gsl_multimin_fminimizer_iterate(s); if (status) break; size = gsl_multimin_fminimizer_size (s); status = gsl_multimin_test_size (size, eps); if (status == GSL_SUCCESS) { if(print) printf ("converged to minimum at\n"); } if(print) printf ("%5d f() = %12.3f size = %.9f\n", iter, s->fval, size); } while (status == GSL_CONTINUE && iter < maxiter); for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i)); luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index); gsl_multimin_fminimizer_free (s); } else { gsl_multimin_fdfminimizer *s = NULL; gsl_vector X; gsl_multimin_function_fdf minex_func; int iter = 0; int status; double size; int N=x->size(); /* Starting point */ X.size=x->size(); X.stride=1; X.data=x->data(); X.owner=0; /* Initialize method and iterate */ minex_func.n = N; minex_func.f = multimin_f_cb; minex_func.df = multimin_df_cb; minex_func.fdf = multimin_fdf_cb; minex_func.params = ∓ s = gsl_multimin_fdfminimizer_alloc (Tdf, N); gsl_multimin_fdfminimizer_set (s, &minex_func, &X, step_size, tol); if(print) printf ("running algorithm '%s'\n", gsl_multimin_fdfminimizer_name (s)); do { iter++; status = gsl_multimin_fdfminimizer_iterate(s); if (status) break; status = gsl_multimin_test_gradient (s->gradient, eps); if (status == GSL_SUCCESS) { if(print) printf ("converged to minimum at\n"); } if(print) printf ("%5d f() = %12.3f\n", iter, s->f); } while (status == GSL_CONTINUE && iter < maxiter); for(int i=0;i<N;++i) x->set(i,gsl_vector_get(s->x,i)); luaL_unref(L, LUA_REGISTRYINDEX, mp.f_index); luaL_unref(L, LUA_REGISTRYINDEX, mp.df_index); gsl_multimin_fdfminimizer_free (s); } if(mp.fdf_index>=0) { luaL_unref(L, LUA_REGISTRYINDEX, mp.fdf_index); } if(ssdel) { delete ss; } return 0; }
/** * Destructor. */ DerivMinimizer::~DerivMinimizer() { if (m_gslSolver != nullptr) { gsl_multimin_fdfminimizer_free(m_gslSolver); gsl_vector_free(m_x); } }
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 */ }
// 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 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; }