int main () { double x[2]; Status status; x[0] = 2; x[1] = 1; SteepestDescent(x, 2, &status); SD_Print(x, 2, &status); return 0; }
int MAINENTRY () { double *x, *bl, *bu; char fname[10] = "OUTSDIF.d"; int nvar = 0, ncon = 0; int funit = 42, ierr = 0, fout = 6, io_buffer = 11; int i; Status status; int st = 0; FORTRAN_open(&funit, fname, &ierr); CUTEST_cdimen(&st, &funit, &nvar, &ncon); if (ncon > 0) { printf("ERROR: Problem is not unconstrained\n"); return 1; } x = (double *) malloc (sizeof(double) * nvar); bl = (double *) malloc (sizeof(double) * nvar); bu = (double *) malloc (sizeof(double) * nvar); CUTEST_usetup(&st, &funit, &fout, &io_buffer, &nvar, x, bl, bu); for (i = 0; i < nvar; i++) { if ( (bl[i] > -CUTE_INF) || (bu[i] < CUTE_INF) ) { printf("ERROR: Problem has bounds\n"); return 1; } } SteepestDescent(x, nvar, &status); SD_Print(x, nvar, &status); free(x); free(bl); free(bu); FORTRAN_close(&funit, &ierr); return 0; }
void OptimizeGeometry(string type) { // Initialize geometry opt parameters int opt_cycle = 1; double dE = 1000, Gnorm = 1000; //nonsense initial values double econv = 1.0e-6; double gconv = 3.0e-4; double stepsize = 0.25; bool reset; // for resetting CG algorithm // Initialize some empty vectors with same dimensions as the Gradient Vector StepDir(Cluster::cluster().GetHMBIGradient(),false); Vector Grad_current(Cluster::cluster().GetHMBIGradient(),false); Vector StepDir_old(Cluster::cluster().GetHMBIGradient(),false); Vector Grad_old(Cluster::cluster().GetHMBIGradient(),false); if (type == "SteepestDescent") { while (opt_cycle <= Params::Parameters().GetMaxOptCycles() && (fabs(dE) > econv || fabs(Gnorm) > gconv ) ) { //printf("XXX\nXXX Starting next opt cycle\n"); // before the step double E_current = Cluster::cluster().GetHMBIEnergy(); Grad_current = Cluster::cluster().GetHMBIGradient(); Vector Coords_current = Cluster::cluster().GetCurrentCoordinates(); //printf("XXX Current Gradient: %12.6f\n",Grad_current.Norm()); // If this is the first cycle, do some special printing if (opt_cycle == 1) { printf("Cycle %d: Energy = %15.9f |Grad| = %12.6f\n", 0, E_current, Grad_current.Max(true)); printf("Cycle %d: dE = %15.9f |dGrad| = %12.6f\n", 0, 0.0, 0.0); Cluster::cluster().UpdateTrajectoryFile(0,true); } // use Gradient printer to show coords if (Params::Parameters().PrintLevel() > 0 ) Cluster::cluster().PrintGradient("Original coordinates",Coords_current); // Create empty coords array with proper size Vector Coords_new(Coords_current, false); // Take optimization step //Grad_current.Scale(-1.0); SteepestDescent(Coords_new, Coords_current, Grad_current, stepsize); // use Gradient printer to show coords if (Params::Parameters().PrintLevel() > 0 ) Cluster::cluster().PrintGradient("New coordinates",Coords_new); // Update the coordinates in the cluster object Cluster::cluster().SetNewCoordinates(Coords_new); // Create the new jobs, run them, and get the HMBI energy Cluster::cluster().RunJobsAndComputeEnergy(); // Print output double E = Cluster::cluster().GetHMBIEnergy(); Vector Grad( Cluster::cluster().GetHMBIGradient() ); //printf("XXX New Gradient: %12.6f\n",Grad.Max(true)); Gnorm = Grad.Max(true); printf("Cycle %d: Energy = %15.9f |Grad| = %10.6f\n",opt_cycle, E,Gnorm); dE = E - E_current; Vector dGrad(Grad); dGrad -= Grad_current; double dG = dGrad.Max(true); printf("Cycle %d: dE = %15.9f |dGrad| = %10.6f step = %8.3f\n", opt_cycle, dE, dG, stepsize); Cluster::cluster().UpdateTrajectoryFile(opt_cycle); // Save a copy of the new geometry in a new input file. FILE *input; string input_file = "new_geom.in"; if ((input = fopen(input_file.c_str(),"w"))==NULL) { printf("OptimizeGeometry() : Cannot open file '%s'\n",input_file.c_str()); exit(1); } Cluster::cluster().PrintInputFile(input); printf("\nNew input file written to '%s'\n",input_file.c_str()); fclose(input); // Adjust step size if (opt_cycle > 1) { // if stepped too far, backup and shrink stepsize if (dE > 0.0) { printf("Cycle Back-up. Decreasing step size for next cycle.\n"); stepsize /= 1.5; // Back up Cluster::cluster().SetNewCoordinates(Coords_current); Cluster::cluster().RunJobsAndComputeEnergy(); Grad_current = Grad_old; } else { printf("Cycle Increasing step size for next cycle.\n"); stepsize *= 1.2; } if (stepsize > 2.0) stepsize = 2.0; } //stepsize = 0.5; opt_cycle++; } } else if (type == "ConjugateGradients") { // Start optimization cycles while (opt_cycle <= Params::Parameters().GetMaxOptCycles() && (fabs(dE) > econv || fabs(Gnorm) > gconv ) ) { reset = false; //printf("XXX\nXXX Starting next opt cycle\n"); // For CG optimizer, need to save previous gradient if (opt_cycle > 1) { Grad_old = Grad_current; StepDir_old = StepDir; //printf("Backing up Gradient and StepDir\n"); //printf("XXX |Grad_old| = %12.6f, |StepDir_old| = %12.6f\n", //Grad_old.Norm(),StepDir_old.Norm()); } // Grab Energy, Gradient, and XYZ coordinates for geometry // before the step double E_current = Cluster::cluster().GetHMBIEnergy(); Grad_current = Cluster::cluster().GetHMBIGradient(); Vector Coords_current = Cluster::cluster().GetCurrentCoordinates(); //printf("XXX Current Gradient: %12.6f\n",Grad_current.Norm()); // If this is the first cycle, do some special printing if (opt_cycle == 1) { printf("Cycle %d: Energy = %15.9f |Grad| = %12.6f\n", 0, E_current, Grad_current.Max(true)); printf("Cycle %d: dE = %15.9f |dGrad| = %12.6f\n", 0, 0.0, 0.0); Cluster::cluster().UpdateTrajectoryFile(0,true); } // use Gradient printer to show coords if (Params::Parameters().PrintLevel() > 0 ) Cluster::cluster().PrintGradient("Original coordinates",Coords_current); // Create empty coords array with proper size Vector Coords_new(Coords_current, false); if (opt_cycle % 20 == 0) { reset = true; //if (stepsize > 0.5) stepsize = 0.25; } // Take optimization step if (opt_cycle==1) { // Use steepest descent for first step, sets StepDir Grad_current.Scale(-1.0); SteepestDescent(Coords_new, Coords_current, Grad_current, stepsize); StepDir = Grad_current; StepDir.Scale(-1.0); } else ConjugateGradients(Coords_new, StepDir, Coords_current, Grad_current, Grad_old, StepDir_old,stepsize, reset); // use Gradient printer to show coords if (Params::Parameters().PrintLevel() > 0 ) Cluster::cluster().PrintGradient("New coordinates",Coords_new); // Update the coordinates in the cluster object Cluster::cluster().SetNewCoordinates(Coords_new); // Create the new jobs, run them, and get the HMBI energy Cluster::cluster().RunJobsAndComputeEnergy(); // Print output double E = Cluster::cluster().GetHMBIEnergy(); Vector Grad( Cluster::cluster().GetHMBIGradient() ); //printf("XXX New Gradient: %12.6f\n",Grad.Max(true)); Gnorm = Grad.Max(true); printf("Cycle %d: Energy = %15.9f |Grad| = %10.6f\n",opt_cycle, E,Gnorm); dE = E - E_current; Vector dGrad(Grad); dGrad -= Grad_current; double dG = dGrad.Max(true); printf("Cycle %d: dE = %15.9f |dGrad| = %10.6f step = %8.3f\n", opt_cycle, dE, dG, stepsize); Cluster::cluster().UpdateTrajectoryFile(opt_cycle); // Save a copy of the new geometry in a new input file. FILE *input; string input_file = "new_geom.in"; if ((input = fopen(input_file.c_str(),"w"))==NULL) { printf("OptimizeGeometry() : Cannot open file '%s'\n",input_file.c_str()); exit(1); } Cluster::cluster().PrintInputFile(input); printf("\nNew input file written to '%s'\n",input_file.c_str()); fclose(input); // Adjust step size if (opt_cycle > 1) { // if stepped too far, backup and shrink stepsize if (dE > 0.0) { printf("Cycle Back-up. Decreasing step size for next cycle.\n"); stepsize /= 1.5; // Back up Cluster::cluster().SetNewCoordinates(Coords_current); Cluster::cluster().RunJobsAndComputeEnergy(); Grad_current = Grad_old; StepDir = StepDir_old; } else { printf("Cycle Increasing step size for next cycle.\n"); stepsize *= 1.2; } if (stepsize > 2.0) stepsize = 2.0; } //stepsize = 0.5; opt_cycle++; } } printf("Cycle %d: Opt completed. dE = %15.9f, |Grad| = %10.6f\n",opt_cycle-1, dE,Gnorm); Cluster::cluster().ComputeDistanceMatrix(); // Save a copy of the new geometry in a new input file. FILE *input; string input_file = "new_geom.in"; if ((input = fopen(input_file.c_str(),"w"))==NULL) { printf("OptimizeGeometry() : Cannot open file '%s'\n",input_file.c_str()); exit(1); } Cluster::cluster().PrintInputFile(input); printf("\nNew input file written to '%s'\n",input_file.c_str()); fclose(input); }