double Callback_Eval_Gradient(unsigned n, const double *x, double *grad, void *my_func_data) { memcpy(Para_List, x, sizeof(double)*n); if(grad) { CalGradient(grad); //gradient will be assigned into objGrad automatically } else { Distribute_Torsion_Parameters(); Assign_Torsion_Parameters(); Cal_E_MM_Rotamer(); CalObjectiveFunction((double*)x, 0); } Iteration++; if(ProgID==0) { fprintf(fFitting, "Iteration %4d Chi^2 = %.8lf Chi^2(1D) = %.8lf Chi^2(rotamer) = %.8lf\n", Iteration, Chi_SQ, Chi_SQ_1D, Chi_SQ_Rotamer); fflush(fFitting); } if(Chi_SQ < Chi_SQ_Min_Global) { Save_Parameters(); memcpy(Para_Best, Para_List, sizeof(double)*n); Chi_SQ_Min_Global = Chi_SQ; printf("Iteration %d : ", Iteration ); for(int i=0; i<n; i++ ) { printf("%f ", Para_Best[i]); } printf(" : %f\n", Chi_SQ ); } if(Chi_SQ < Chi_SQ_Min) { Chi_SQ_Min = Chi_SQ; if(Chi_SQ + 2.0E-5 > Chi_SQ_Min) { FailCount++; } else { FailCount = 0; } } else { FailCount++; if(FailCount > 6) { // cannot make further progress printf("Terminating..\n"); nlopt_force_stop(opt); // terminate the optimization } } return Chi_SQ; }
void Read_Parameters(char szName[]) { FILE *fIn; fIn = fopen(szName, "r"); for(int i=0; i<n_Para; i++) { fscanf(fIn, "%lf", &(Para_List[i])); } fclose(fIn); Distribute_Torsion_Parameters(); Assign_Torsion_Parameters(); Cal_E_MM_Scaned(); Cal_E_MM_Rotamer(); Output_1D_QM_MM(); }
void CalGradient(double Grad_List[]) { int i, nAtom; double Para_Save[N_PARA_MAX], Delta_Para_List[N_PARA_MAX]; double f_Left, f_Right; nAtom = Mol_ESP.nAtom; for(i=0; i<n_Para; i++) { Para_Save[i] = Para_List[i]; //save current parameters Delta_Para_List[i] = DELTA_PARA; } Delta_Para_List[n_Para - 1] *= E_Shift_0; Distribute_Torsion_Parameters(); Assign_Torsion_Parameters(); Cal_E_MM_Rotamer(); // do full optimization from the original coordinates once for(i=0; i<n_Para; i++) { if(Is_Para_Fixed[i] == 0) { Para_List[i] = Para_Save[i] - Delta_Para_List[i]; f_Left = CalObjectiveFunction(Para_List, 0); Para_List[i] = Para_Save[i] + Delta_Para_List[i]; f_Right = CalObjectiveFunction(Para_List, 0); Grad_List[i] = (f_Right-f_Left)/(2.0*Delta_Para_List[i]); Para_List[i] = Para_Save[i]; //restore save (correct) parameter } else { Grad_List[i] = 0.0; } } CalObjectiveFunction(Para_List, 0); return; }
double Optimize_Torsion_Parameters(void) { double lb[N_PARA_MAX], ub[N_PARA_MAX]; double Chi_SQ; int i, j, Pos; n_Para = 10*n_Phi + 1; memset(Is_Para_Fixed, 0, sizeof(int)*n_Para); // memset(lb, 0, sizeof(double)*n_Para); lb[n_Phi*10] = -HUGE_VAL; for(i=0; i<n_Phi; i++) { Pos = 10*i; for(j=0; j<10; j+=2) { // ten parameters lb[Pos+j] = -15.0; ub[Pos+j] = 15.0; } for(j=1; j<10; j+=2) { // ten parameters lb[Pos+j] = -M_PI; ub[Pos+j] = +M_PI; } } ub[n_Phi*10] = HUGE_VAL; opt = nlopt_create(NLOPT_LN_COBYLA, n_Para); nlopt_set_lower_bounds(opt, lb); nlopt_set_upper_bounds(opt, ub); nlopt_set_min_objective(opt, Callback_Eval_Gradient, NULL); nlopt_set_xtol_rel(opt, 1e-6); Collect_Torsion_Parameters(); Assign_Torsion_Parameters(); Cal_E_MM_Scaned(); Cal_E_MM_Rotamer(); Para_List[n_Phi*10] = E_Scan_QM_Mean-E_Scan_MM_Mean; // energy shift E_Shift_0 = fabs(E_Scan_QM_Mean-E_Scan_MM_Mean); for(i=0; i<n_Phi; i++) { Pos = 10*i; for(j=1; j<10; j+=2) { // the phase is fixed Is_Para_Fixed[Pos+j] = 1; } } Read_Parameters("saved-para.dat"); Chi_SQ_Min = 1.0E100; memcpy(Para_Best, Para_List, sizeof(double)*n_Para); Chi_SQ = CalObjectiveFunction(Para_List, 0); if(ProgID == 0) { fprintf(fFitting, "Iteration %4d Chi^2 = %.8lf Chi^2(1D) = %.8lf Chi^2(rotamer) = %.8lf\n", 0, Chi_SQ, Chi_SQ_1D, Chi_SQ_Rotamer); fflush(fFitting); } FailCount = 0; int ret= nlopt_optimize(opt, Para_List, &Chi_SQ); if (ret < 0) { printf("nlopt failed! :%d\n", ret); } else { printf("Chi_SQ_min = %lf Chi_SQ = %lf\n", Chi_SQ_Min, Chi_SQ); } memcpy(Para_List, Para_Best, sizeof(double)*n_Para); CalObjectiveFunction(Para_List, 1); nlopt_destroy(opt); return Chi_SQ_Min; }
int main(int argc, char **argv) { char ErrorMsg[256]; fFile_Run_Log = fopen(szName_Run_Log, "w"); if(fFile_Run_Log==NULL) { sprintf(ErrorMsg, "Fail to create the log file.\n\n"); Quit_With_Error_Msg(ErrorMsg); } strcpy(szName_Conf_File, argv[1]); ReadConfFile(szName_Conf_File); // MPI_Init(&argc, &argv); // MPI_Comm_rank(MPI_COMM_WORLD, &ProgID); // MPI_Comm_size(MPI_COMM_WORLD, &nProc); ForceField.ReadForceField(szName_Force_Field); Mol_ESP.ReadPSF(szName_XPSF, 0); Read_Rtf_File(); strcpy(Mol_ESP.MolName, Mol_ESP.ResName[0]); Mol_ESP.AssignForceFieldParameters(&ForceField); Read_Soft_DihedralList(); Mol_ESP.Is_Phi_Psi_Constrained = 0; Mol_ESP.E_CMap_On = 0; Read_QM_Rotamer_Data(); // Read_Tor_Para_1D_Fitting(); // Assign_Torsion_Parameters(); // Read_1D_Scan_QM_Data(); // Cal_E_MM_Scaned(); Cal_E_MM_Rotamer(); Output_Rotamer_QM_MM(); // fFitting = fopen("fitting.dat", "w"); // Fitting_Torsion_Parameters(); // fclose(fFitting); // FILE *fOut; // fOut = fopen("rotamer-E.dat", "w"); // for(i=0; i<nRotamer; i++) { // fprintf(fOut, "%d %lf %lf %lf\n", i+1, E_Rotamer_QM[i], E_Rotamer_MM[i], rmsd_Rotamer[i]); // } // fclose(fOut); // Cal_E_MM_QM_Diff(7); // for(i=0; i<n_Phi; i++) { // Cal_E_MM_QM_Diff(i); // } // Fit_Torsion_Parameters(7); // fPara = fopen("torsion-para.dat", "w"); // for(i=0; i<n_Phi; i++) { // Fit_Torsion_Parameters(i); // } // fclose(fPara); // Geoometry_Optimization_With_Constraint(&Mol_ESP); fflush(fFile_Run_Log); fclose(fFile_Run_Log); // MPI_Finalize(); return 0; }