// run one iteration of the L-BFGS-B algorithm void SolverBase::callLBFGS (const char* cmd) { if (cmd) copyCStrToCharArray(cmd,task,60); // call appropiate fortran routine to the run the solver #ifdef _WIN32 //Windows SETULB(&n,&m,x,lb,ub,btype,f,g,&factr,&pgtol,wa,iwa,task,&iprint, csave,lsave,isave,dsave); #else //Linux setulb_(&n,&m,x,lb,ub,btype,f,g,&factr,&pgtol,wa,iwa,task,&iprint, csave,lsave,isave,dsave); #endif }
/* call the fortran library */ void LBFGSB::call(const char* cmd) { if(cmd) { // Get the length of the source C string. int nsource = strlen(cmd); // Only perform the copy if the source can fit into the destination. if (nsource < 60) { for(int i = 0; i < nsource; i++) task[i] = cmd[i]; // Fill in the rest of the string with blanks. for (int i = nsource; i < 60; i++) task[i] = ' '; } } setulb_(&n,&m,x,lb,ub,btype,&f,g,&factr,&pgtol,wa,iwa,task,&iprint, csave,lsave,isave,dsave); }
int calib(){ /* declarations */ double t_0,T_max,y_min,y_max; int gridType, choice_optim; char *name_in_optim, *name_in_data; char *name_in_sigmainit_ddl, *name_out_sigmaest_ddl; char *name_in_sigma_visu, *name_out_sigmainit_visu, *name_out_sigmaest_visu; char *name_in_calib; FILE *fic_in_sigmainit_ddl; FILE *fic_in_sigma_visu; FILE *fic_out_sigmainit_visu; double gradtol,steptol; int maxCounter,verbosity,saveSuccessiveXinFile; int nbParamSigma; double *sigma_init, *sigma_est; int i,j,k,l; int Nsigma_visu,Msigma_visu; double *Ksigma_visu, *Ysigma_visu, *Tsigma_visu; double **sigmainitVisuGrid, **sigmaestVisuGrid; int m_nbcorrec, nbwa, iprint; double costf, factr, pgtol; double sigma_min, sigma_max; double *lower_bound, *upper_bound, *gradient; double *wa; int *nbd, *iwa; char task[60], csave[60]; int lsave[4]; int isave[44]; double dsave[29]; printf("\nCalibration using a PDE Dupire simulator\n\n"); name_in_calib = "calib.in"; /* initialization of S_0, r, q,..., name_out_sigmaest_visu from the file name_in_calib */ loadParamCalib(name_in_calib,&S_0,&r,&q,&optionType,&t_0,&T_max,&y_min,&y_max,&N,&M,&gridType,&theta,&choice_optim,&name_in_optim,&name_in_data,&name_in_sigmainit_ddl,&name_out_sigmaest_ddl,&name_in_sigma_visu,&name_out_sigmainit_visu,&name_out_sigmaest_visu); /* initialization of data prices from the file name_in_data */ printf("Data are defined from the file \"%s\"\n\n",name_in_data); loadDataPrices(name_in_data,&marketOptionPrices); /* initialization of n, m, y_coarseGrid, T_coarseGrid and sigma_init from the file name_in_sigmainit_ddl */ printf("Sigma_init is defined from its degrees of freedom (see the file \"%s\")\n\n",name_in_sigmainit_ddl); loadSigmaddl(name_in_sigmainit_ddl,&n,&m,&y_coarseGrid,&T_coarseGrid,&sigma_init); nbParamSigma = (n+3)*(m+3); // i.e (n+1)*(m+1)+2*(m+1)+2*(n+1)+4 /* y_fineGrid and T_fineGrid are used by costDupire and gradDupire */ y_fineGrid = (double *) malloc((N+1)*sizeof(double)); T_fineGrid = (double *) malloc((M+1)*sizeof(double)); buildFineGrid(y_fineGrid,T_fineGrid,N,M,t_0,T_max,y_min,y_max,S_0,gridType); /* memory allocation */ sigma_est = (double *) malloc(nbParamSigma*sizeof(double)); if (choice_optim==1) // Quasi-Newton without constraints { /* initialization of gradtol, steptol, verbosity, saveSuccessiveXinFile, maxCounter and lambda from the file name_in_optim */ loadParamOptim(name_in_optim,&gradtol,&steptol,&verbosity,&saveSuccessiveXinFile,&maxCounter,&lambda); /* optimization */ printf("-------------------------------------------"); printf("-------------------------------------------\n"); printf("Optimization: computation of Sigma_est using a QuasiNewton algorithm\n"); printf("-------------------------------------------"); printf("-------------------------------------------\n"); QuasiNewton(nbParamSigma,sigma_init,costDupire,gradDupire,sigma_est,gradtol,steptol,maxCounter,verbosity,saveSuccessiveXinFile); printf("-------------------------------------------"); printf("-------------------------------------------\n"); } else if (choice_optim==2) // Quasi-Newton with bounds { m_nbcorrec = 5; // number of corrections used in the limited memory matrix /* initialization of pgtol, factr, iprint, maxCounter, sigma_min, sigma_max and lambda from the file name_in_optim */ loadParamOptim2(name_in_optim,&pgtol,&factr,&iprint,&maxCounter,&sigma_min,&sigma_max,&lambda); /* optimization */ printf("-------------------------------------------"); printf("-------------------------------------------\n"); printf("Optimization: computation of Sigma_est using a QuasiNewton algorithm with bounds\n"); printf("-------------------------------------------"); printf("-------------------------------------------\n"); /* memory allocation */ lower_bound = (double *) malloc(nbParamSigma*sizeof(double)); upper_bound = (double *) malloc(nbParamSigma*sizeof(double)); nbd = (int *) malloc(nbParamSigma*sizeof(int)); gradient = (double *) malloc(nbParamSigma*sizeof(double)); nbwa = 2*m_nbcorrec*nbParamSigma+4*nbParamSigma+12*m_nbcorrec*m_nbcorrec+12*m_nbcorrec; wa = (double *) malloc(nbwa*sizeof(double)); iwa = (int *) malloc(3*nbParamSigma*sizeof(int)); for (i=0;i<nbParamSigma;i++) { sigma_est[i] = sigma_init[i]; lower_bound[i] = sigma_min; upper_bound[i] = sigma_max; nbd[i] = 0; // nbd[i]=0 if sigma_est[i] is unbounded } // bounds for the values of sigma on the nodes (not for the derivatives) for (i=0;i<(n+1)*(m+1);i++) nbd[i] = 2; // nbd[i]=2 if sigma_est[i] has both lower and upper bounds inittask_(task); // task = 'START' setulb_(&nbParamSigma,&m_nbcorrec,sigma_est,lower_bound,upper_bound,nbd,&costf,gradient,&factr,&pgtol,wa,iwa,task,&iprint,csave,lsave,isave,dsave); while (memcmp(task,"FG",2) == 0 || memcmp(task,"NEW_X",5) == 0) { if (memcmp(task,"FG",2) == 0) // si les 2 premiers caracteres de task sont FG { costf = costDupire(sigma_est); gradDupire(sigma_est,gradient); } if (memcmp(task,"NEW_X",5) == 0 && isave[29]>=maxCounter) //isave[29] en C ou isave(30) en Fortran correspond au nb d'iter. courant { inittask2_(task); // task = 'STOP: Maximum number of iterations reached' } setulb_(&nbParamSigma,&m_nbcorrec,sigma_est,lower_bound,upper_bound,nbd,&costf,gradient,&factr,&pgtol,wa,iwa,task,&iprint,csave,lsave,isave,dsave); } printf("-------------------------------------------"); printf("-------------------------------------------\n"); } /* save the degrees of freedom of sigmaest in the file name_out_sigmaest_ddl */ if (strcmp(name_out_sigmaest_ddl,"_") != 0){ saveSigmaddl(name_out_sigmaest_ddl,sigma_est,n,m,y_coarseGrid,T_coarseGrid); printf("--> Sigma_est saved in the file \"%s\"\n\n",name_out_sigmaest_ddl); } if (strcmp(name_in_sigma_visu,"_") != 0){ if (strcmp(name_out_sigmainit_visu,"_") != 0 || strcmp(name_out_sigmaest_visu,"_") != 0){ loadSigmaGrid(name_in_sigma_visu,&Nsigma_visu,&Msigma_visu,&Ksigma_visu,&Tsigma_visu); Ysigma_visu = (double *) malloc((Nsigma_visu+1)*sizeof(double)); for (i=0;i<Nsigma_visu+1;i++) Ysigma_visu[i] = log(Ksigma_visu[i]); } if (strcmp(name_out_sigmainit_visu,"_") != 0){ printf("Computation of Sigma_init on the visualization grid defined in the file \"%s\"\n",name_in_sigma_visu); sigmainitVisuGrid = (double **) malloc((Nsigma_visu+1)*sizeof(double *)); for (i=0;i<Nsigma_visu+1;i++) sigmainitVisuGrid[i] = (double *) malloc((Msigma_visu+1)*sizeof(double)); sigmaddlToSigmaFineGrid(sigmainitVisuGrid,n,m,y_coarseGrid,T_coarseGrid,sigma_init,Ysigma_visu,Tsigma_visu,Nsigma_visu,Msigma_visu); savePriceOrSigma(name_out_sigmainit_visu,sigmainitVisuGrid,Nsigma_visu,Msigma_visu,Ksigma_visu,Tsigma_visu); printf("--> Sigma_init saved in the file \"%s\"\n\n",name_out_sigmainit_visu); } if (strcmp(name_out_sigmaest_visu,"_") != 0){ printf("Computation of Sigma_est on the visualization grid defined in the file \"%s\"\n",name_in_sigma_visu); sigmaestVisuGrid = (double **) malloc((Nsigma_visu+1)*sizeof(double *)); for (i=0;i<Nsigma_visu+1;i++) sigmaestVisuGrid[i] = (double *) malloc((Msigma_visu+1)*sizeof(double)); sigmaddlToSigmaFineGrid(sigmaestVisuGrid,n,m,y_coarseGrid,T_coarseGrid,sigma_est,Ysigma_visu,Tsigma_visu,Nsigma_visu,Msigma_visu); savePriceOrSigma(name_out_sigmaest_visu,sigmaestVisuGrid,Nsigma_visu,Msigma_visu,Ksigma_visu,Tsigma_visu); printf("--> Sigma_est saved in the file \"%s\"\n\n",name_out_sigmaest_visu); } } /* free memory */ free(sigma_init); free(sigma_est); free(y_coarseGrid); free(T_coarseGrid); free(y_fineGrid); free(T_fineGrid); return 0; }
void gp_mle(GP *gp) { int i, iter; int zero = -1; int mem = 20; int *nbd; double *l, *u; double *dwork; int *iwork; double ftol = 1.e+7; double gtol = 1.e-7; char task[60]; long tl = 60; char csave[60]; int lsave[4]; int isave[44]; double dsave[29]; double t; double fn; double *gr; gr = malloc(sizeof(double) * gp->dim); nbd = malloc(sizeof(int) * gp->dim); l = malloc(sizeof(double) * gp->dim); u = malloc(sizeof(double) * gp->dim); //printf("%d\n", (2 * mem * gp->dim + 5 * gp->dim + 11 * mem * mem + 8 * mem)); dwork = malloc(sizeof(double) * (2 * mem * gp->dim + 5 * gp->dim + 11 * mem * mem + 8 * mem)); iwork = malloc(sizeof(int) * (3 * gp->dim)); for(i=0;i<gp->dim;i++) { gr[i] = 0.0; nbd[i] = 2; l[i] = 1.e+1; u[i] = 1.e+5; } for(i=0;i<60;i++) { task[i] = '\x0'; csave[i] = '\x0'; } task[0] = 'S'; task[1] = 'T'; task[2] = 'A'; task[3] = 'R'; task[4] = 'T'; iter = 0; while(!strncmp(task, "FG", 2)||!strncmp(task, "NEW_X", 5)||!strncmp(task, "START", 5)) { setulb_(&gp->dim, &mem, gp->phi, l, u, nbd, &fn, gr, &ftol, >ol, dwork, iwork, task, &zero, csave, lsave, isave, dsave, 60, 60); printf("%s\n", task); printf("iter %d phi: ", iter); for(i=0;i<gp->dim;i++) { printf("%e ", gp->phi[i]); } printf("\n"); if(!strncmp(task, "FG", 2)) { t = omp_get_wtime(); log_lkhd(gp, NULL, &fn, gr); t = omp_get_wtime() - t; printf("ITER %d time-mle %e\n", gp->ud, t); } //printf("%e %e: %e %e %e\n", gp->phi[0], gp->phi[1], fn, gr[0], gr[1]); ++iter; } free(iwork); free(dwork); free(u); free(l); free(nbd); free(gr); }
Real LBFGSBOptimizer::optimize( Vector &results ) { int run_optimizer = 1; char task[61]; Real f; int *iwa; char csave[61]; bool lsave[4]; int isave[44]; Real dsave[29]; Real *wa; Real *lowerLimits, *upperLimits; const OptimizerSystem& sys = getOptimizerSystem(); int n = sys.getNumParameters(); int m = limitedMemoryHistory; Real *gradient; gradient = new Real[n]; iprint[0] = iprint[1] = iprint[2] = diagnosticsLevel; if( sys.getHasLimits() ) { sys.getParameterLimits( &lowerLimits, &upperLimits ); // Determine what kind of limits each parameter has. // nbd = 0, unbounded; 1, only lower; 2, both; 3 only upper for (int i=0; i < n; ++i) { if (lowerLimits[i] == -Infinity) nbd[i] = (upperLimits[i] == Infinity ? 0 : 3); else nbd[i] = (upperLimits[i] == Infinity ? 1 : 2); } } else { lowerLimits = 0; upperLimits = 0; for(int i=0;i<n;i++) nbd[i] = 0; // unbounded } iwa = new int[3*n]; wa = new Real[((2*m + 4)*n + 12*m*m + 12*m)]; Real factor; if( getAdvancedRealOption("factr", factor ) ) { SimTK_APIARGCHECK_ALWAYS(factor > 0,"LBFGSBOptimizer","optimize", "factr must be positive \n"); factr = factor; } strcpy( task, "START" ); while( run_optimizer ) { setulb_(&n, &m, &results[0], lowerLimits, upperLimits, nbd, &f, gradient, &factr, &convergenceTolerance, wa, iwa, task, iprint, csave, lsave, isave, dsave, 60, 60); if( strncmp( task, "FG", 2) == 0 ) { objectiveFuncWrapper( n, &results[0], true, &f, this); gradientFuncWrapper( n, &results[0], false, gradient, this); } else if( strncmp( task, "NEW_X", 5) == 0 ){ //objectiveFuncWrapper( n, &results[0], true, &f, (void*)this ); } else { run_optimizer = 0; if( strncmp( task, "CONV", 4) != 0 ){ delete[] gradient; delete[] iwa; delete[] wa; SimTK_THROW1(SimTK::Exception::OptimizerFailed , SimTK::String(task) ); } } } delete[] gradient; delete[] iwa; delete[] wa; return f; }