// $Id$ // // Copyright (C) 2004-2008 Greg Landrum and Rational Discovery LLC // // @@ All Rights Reserved @@ // This file is part of the RDKit. // The contents are covered by the terms of the BSD license // which is included in the file license.txt, found at the root // of the RDKit source tree. // #include #include #include "BFGSOpt.h" #include namespace BFGSOpt { #define CLEANUP() { delete [] grad; delete [] dGrad; delete [] hessDGrad;\ delete [] newPos; delete [] xi; delete [] invHessian; } // ------------------------------------------------------------ // an adaptation of the function dfpmin (function minimization using the BFGS // algorithm) from Chapter 10 of Numerical Recipes in C // // NOTE: the funcTol argument is *not* used. // ------------------------------------------------------------ int minimize(unsigned int dim,double *pos, double gradTol,unsigned int &numIters, double &funcVal, double (*func)(double *), double (*gradFunc)(double *,double*), double funcTol,unsigned int maxIts){ PRECONDITION(pos,"bad input array"); PRECONDITION(gradTol>0,"bad tolerance"); PRECONDITION(func,"bad function"); PRECONDITION(gradFunc,"bad function"); double sum,maxStep,fp; double *grad,*dGrad,*hessDGrad; double *newPos,*xi; double *invHessian; grad = new double[dim]; dGrad = new double[dim]; hessDGrad = new double[dim]; newPos = new double[dim]; xi = new double[dim]; invHessian = new double[dim*dim]; // evaluate the function and gradient in our current position: fp=func(pos); gradFunc(pos,grad); sum = 0.0; memset(invHessian,0,dim*dim*sizeof(double)); for(unsigned int i=0;i(dim)); for(unsigned int iter=1;iter<=maxIts;iter++){ numIters=iter; int status; // do the line search: linearSearch(dim,pos,fp,grad,xi,newPos,funcVal,func,maxStep,status); CHECK_INVARIANT(status>=0,"bad direction in linearSearch"); // save the function value for the next search: fp = funcVal; // set the direction of this line and save the gradient: double test=0.0; for(unsigned int i=0;itest) test=temp; dGrad[i] = grad[i]; } if(test sqrt(EPS*sumDGrad*sumXi)){ fac = 1.0/fac; double fad = 1.0/fae; for(unsigned int i=0;i