def mylbfgs(coords, pot, **kwargs): if not hasattr(pot, "getEnergyGradient"): # for compatibility with old quenchers. # assume pot is a getEnergyGradient function pot = _getEnergyGradientWrapper(pot) lbfgs = MYLBFGS(coords, pot, **kwargs) return lbfgs.run()
def __init__(self, coords, pot, eigenvec0=None, orthogZeroEigs=0, dx=1e-6, first_order=True, gradient=None, **minimizer_kwargs): self.minimizer_kwargs = minimizer_kwargs if eigenvec0 is None: # this random vector should be distributed uniformly on a hypersphere. eigenvec0 = rotations.vec_random_ndim(coords.shape) eigenvec0 = eigenvec0 / np.linalg.norm(eigenvec0) # change some default in the minimizer unless manually set if "nsteps" not in minimizer_kwargs: minimizer_kwargs["nsteps"] = 500 if "logger" not in minimizer_kwargs: minimizer_kwargs["logger"] = logging.getLogger( "pele.connect.findTS.leig_quench") self.eigpot = LowestEigPot(coords, pot, orthogZeroEigs=orthogZeroEigs, dx=dx, gradient=gradient, first_order=first_order) self.minimizer = MYLBFGS(eigenvec0, self.eigpot, rel_energy=True, **self.minimizer_kwargs)
def setUp1(self, verbose=False, **kwargs): np.random.seed(0) natoms = 18 self.system = LJCluster(natoms) self.pot = self.system.get_potential() x = self.system.get_random_configuration() ret = lbfgs_py(x, self.pot, tol=10) self.x = ret.coords self.kwargs = kwargs self.verbose = verbose self.M = 4 if self.verbose: iprint = 1 else: iprint = -1 self.myo = MYLBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M) self.o = LBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M, **self.kwargs)
def _mylbfgs(coords, pot, **kwargs): lbfgs = MYLBFGS(coords, pot, **kwargs) ret = lbfgs.run() coords = ret.coords e = ret.energy rms = ret.rms funcalls = ret.nfev return coords, e, rms, funcalls, ret
def update_coords(self, coords, energy=None, gradient=None): """update the position at which to compute the eigenvector""" self.eigpot.update_coords(coords, gradient=gradient) state = self.minimizer.get_state() ret = self.get_result() self.minimizer = MYLBFGS(ret.eigenvec, self.eigpot, rel_energy=True, **self.minimizer_kwargs) self.minimizer.set_state(state)
def test_state(self): # do several minimization iterations for i in range(10): self.minimizer.one_iteration() # get the state and save it ret = self.minimizer.get_result() state = self.minimizer.get_state() x1 = ret.coords.copy() # do several more iteration steps for i in range(10): self.minimizer.one_iteration() # now make a new minimizer and do several iterations minimizer2 = MYLBFGS(x1, self.pot) minimizer2.set_state(state) for i in range(10): minimizer2.one_iteration() # test that the two minimizers are in the same state ret1 = self.minimizer.get_result() ret2 = minimizer2.get_result() self.assertEqual(ret1.energy, ret2.energy) self.assertTrue((ret1.coords == ret2.coords).all()) state1 = self.minimizer.get_state() state2 = minimizer2.get_state() self.assertTrue((state1.W == state2.W).all()) self.assertTrue((state1.dXold == state2.dXold).all()) self.assertTrue((state1.dGold == state2.dGold).all()) self.assertEqual(state1.H0, state2.H0) self.assertEqual(state1.point, state2.point) self.assertEqual(state1.iter, state2.iter)
def __init__( self, coords, pot, eigenvec0=None, orthogZeroEigs=0, dx=1e-6, first_order=True, gradient=None, **minimizer_kwargs ): self.minimizer_kwargs = minimizer_kwargs if eigenvec0 is None: # this random vector should be distributed uniformly on a hypersphere. eigenvec0 = rotations.vec_random_ndim(coords.shape) eigenvec0 = eigenvec0 / np.linalg.norm(eigenvec0) # change some default in the minimizer unless manually set if "nsteps" not in minimizer_kwargs: minimizer_kwargs["nsteps"] = 500 if "logger" not in minimizer_kwargs: minimizer_kwargs["logger"] = logging.getLogger("pele.connect.findTS.leig_quench") self.eigpot = LowestEigPot( coords, pot, orthogZeroEigs=orthogZeroEigs, dx=dx, gradient=gradient, first_order=first_order ) self.minimizer = MYLBFGS(eigenvec0, self.eigpot, rel_energy=True, **self.minimizer_kwargs)
def setUp1(self, verbose=False, **kwargs): np.random.seed(0) natoms = 18 self.system = LJCluster(natoms) self.pot = self.system.get_potential() x = self.system.get_random_configuration() ret = lbfgs_py(x, self.pot, tol=10) self.x = ret.coords self.kwargs = kwargs self.verbose = verbose self.M = 4 if self.verbose: iprint=1 else: iprint = -1 self.myo = MYLBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M) self.o = LBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M, **self.kwargs)
class TestMYLBFGS_State(unittest.TestCase): def setUp(self): self.system = LJCluster(13) self.x = self.system.get_random_configuration() self.pot = self.system.get_potential() self.minimizer = MYLBFGS(self.x, self.pot) def test_state(self): # do several minimization iterations for i in range(10): self.minimizer.one_iteration() # get the state and save it ret = self.minimizer.get_result() state = self.minimizer.get_state() x1 = ret.coords.copy() # do several more iteration steps for i in range(10): self.minimizer.one_iteration() # now make a new minimizer and do several iterations minimizer2 = MYLBFGS(x1, self.pot) minimizer2.set_state(state) for i in range(10): minimizer2.one_iteration() # test that the two minimizers are in the same state ret1 = self.minimizer.get_result() ret2 = minimizer2.get_result() self.assertEqual(ret1.energy, ret2.energy) self.assertTrue((ret1.coords == ret2.coords).all()) state1 = self.minimizer.get_state() state2 = minimizer2.get_state() self.assertTrue((state1.W == state2.W).all()) self.assertTrue((state1.dXold == state2.dXold).all()) self.assertTrue((state1.dGold == state2.dGold).all()) self.assertEqual(state1.H0, state2.H0) self.assertEqual(state1.point, state2.point) self.assertEqual(state1.iter, state2.iter)
def _minimize_transverse(self, nsteps, transverse_energy=None, transverse_gradient=None): # must update minimizer = MYLBFGS(self.coords, self.transverse_potential, nsteps=self.nsteps_tangent, energy=transverse_energy, gradient=transverse_gradient, **self.transverse_kwargs) if self._transverse_walker_state is not None: minimizer.set_state(self._transverse_walker_state) ret = minimizer.run() self._transverse_walker_state = minimizer.get_state() self._stop_criterion_satisfied = minimizer.stop_criterion_satisfied() return ret
def mylbfgs(coords, pot, **kwargs): lbfgs = MYLBFGS(coords, pot, **kwargs) return lbfgs.run()
class FindLowestEigenVector(object): """A class to compute the lowest eigenvector of the Hessian using Rayleigh-Ritz minimization Parameters ---------- coords : float array the point in space at which to compute the lowest eigenvector pot : Potential object the potential energy function eigenvec0 : float array the initial guess for the lowest eigenvector orthogZeroEigs : callable The function which makes a vector orthogonal to the known eigenvectors with zero eigenvalues. The default assumes global translational and rotational symmetry dx : float the local curvature is approximated using points separated by dx first_order : bool use the first order forward finite differences approximation for the curvature rather than the second order central differences approximation. This is less accurate, but requires one fewer potential call per iteration. gradient : float array the true gradient at coords. If first_order is true and gradient is not None then one potential call will be saved. minimizer_kwargs : kwargs these kwargs are passed to the optimizer which finds the direction of least curvature """ def __init__(self, coords, pot, eigenvec0=None, orthogZeroEigs=0, dx=1e-6, first_order=True, gradient=None, **minimizer_kwargs): self.minimizer_kwargs = minimizer_kwargs if eigenvec0 is None: # this random vector should be distributed uniformly on a hypersphere. eigenvec0 = rotations.vec_random_ndim(coords.shape) eigenvec0 = eigenvec0 / np.linalg.norm(eigenvec0) # change some default in the minimizer unless manually set if "nsteps" not in minimizer_kwargs: minimizer_kwargs["nsteps"] = 500 if "logger" not in minimizer_kwargs: minimizer_kwargs["logger"] = logging.getLogger( "pele.connect.findTS.leig_quench") self.eigpot = LowestEigPot(coords, pot, orthogZeroEigs=orthogZeroEigs, dx=dx, gradient=gradient, first_order=first_order) self.minimizer = MYLBFGS(eigenvec0, self.eigpot, rel_energy=True, **self.minimizer_kwargs) def stop_criterion_satisfied(self): """test if the stop criterion is satisfied""" return self.minimizer.stop_criterion_satisfied() def update_coords(self, coords, energy=None, gradient=None): """update the position at which to compute the eigenvector""" self.eigpot.update_coords(coords, gradient=gradient) state = self.minimizer.get_state() ret = self.get_result() self.minimizer = MYLBFGS(ret.eigenvec, self.eigpot, rel_energy=True, **self.minimizer_kwargs) self.minimizer.set_state(state) def one_iteration(self): """do one iteration of the minimizer""" self.minimizer.one_iteration() def run(self, niter=None): """do niter iterations, or until the stop criterion is satisfied""" if niter is None: self.minimizer.run() return self.get_result() else: for i in xrange(niter): if self.minimizer.stop_criterion_satisfied(): break self.one_iteration() return self.get_result() def get_result(self): """return the results object""" res = self.minimizer.get_result() res.eigenval = res.energy res.eigenvec = res.coords / np.linalg.norm(res.coords) delattr(res, "energy") delattr(res, "coords") # res.minimizer_state = self.minimizer.get_state() res.nfev = self.eigpot.nfev return res
def setUp(self): self.system = LJCluster(13) self.x = self.system.get_random_configuration() self.pot = self.system.get_potential() self.minimizer = MYLBFGS(self.x, self.pot)
class FindLowestEigenVector(object): """A class to compute the lowest eigenvector of the Hessian using Rayleigh-Ritz minimization Parameters ---------- coords : float array the point in space at which to compute the lowest eigenvector pot : Potential object the potential energy function eigenvec0 : float array the initial guess for the lowest eigenvector orthogZeroEigs : callable The function which makes a vector orthogonal to the known eigenvectors with zero eigenvalues. The default assumes global translational and rotational symmetry dx : float the local curvature is approximated using points separated by dx first_order : bool use the first order forward finite differences approximation for the curvature rather than the second order central differences approximation. This is less accurate, but requires one fewer potential call per iteration. gradient : float array the true gradient at coords. If first_order is true and gradient is not None then one potential call will be saved. minimizer_kwargs : kwargs these kwargs are passed to the optimizer which finds the direction of least curvature """ def __init__(self, coords, pot, eigenvec0=None, orthogZeroEigs=0, dx=1e-6, first_order=True, gradient=None, **minimizer_kwargs): self.minimizer_kwargs = minimizer_kwargs if eigenvec0 is None: # this random vector should be distributed uniformly on a hypersphere. eigenvec0 = rotations.vec_random_ndim(coords.shape) eigenvec0 = eigenvec0 / np.linalg.norm(eigenvec0) # change some default in the minimizer unless manually set if "nsteps" not in minimizer_kwargs: minimizer_kwargs["nsteps"] = 500 if "logger" not in minimizer_kwargs: minimizer_kwargs["logger"] = logging.getLogger("pele.connect.findTS.leig_quench") self.eigpot = LowestEigPot(coords, pot, orthogZeroEigs=orthogZeroEigs, dx=dx, gradient=gradient, first_order=first_order) self.minimizer = MYLBFGS(eigenvec0, self.eigpot, rel_energy=True, **self.minimizer_kwargs) def stop_criterion_satisfied(self): """test if the stop criterion is satisfied""" return self.minimizer.stop_criterion_satisfied() def update_coords(self, coords, energy=None, gradient=None): """update the position at which to compute the eigenvector""" self.eigpot.update_coords(coords, gradient=gradient) state = self.minimizer.get_state() ret = self.get_result() self.minimizer = MYLBFGS(ret.eigenvec, self.eigpot, rel_energy=True, **self.minimizer_kwargs) self.minimizer.set_state(state) def one_iteration(self): """do one iteration of the minimizer""" self.minimizer.one_iteration() def run(self, niter=None): """do niter iterations, or until the stop criterion is satisfied""" if niter is None: self.minimizer.run() return self.get_result() else: for i in xrange(niter): if self.minimizer.stop_criterion_satisfied(): break self.one_iteration() return self.get_result() def get_result(self): """return the results object""" res = self.minimizer.get_result() res.eigenval = res.energy res.eigenvec = res.coords / np.linalg.norm(res.coords) delattr(res, "energy") delattr(res, "coords") # res.minimizer_state = self.minimizer.get_state() res.nfev = self.eigpot.nfev return res
class TestMYLBFGS_LBFGS(unittest.TestCase): def setUp(self): self.setUp1(verbose=False) def setUp1(self, verbose=False, **kwargs): np.random.seed(0) natoms = 18 self.system = LJCluster(natoms) self.pot = self.system.get_potential() x = self.system.get_random_configuration() ret = lbfgs_py(x, self.pot, tol=10) self.x = ret.coords self.kwargs = kwargs self.verbose = verbose self.M = 4 if self.verbose: iprint = 1 else: iprint = -1 self.myo = MYLBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M) self.o = LBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M, **self.kwargs) def test(self): N = self.x.size M = self.M myo = self.myo o = self.o # do one iteration for i in range(3 * self.M): myo.one_iteration() o.one_iteration() if self.verbose: print("") print("H0", myo.H0, o.H0) print("rho ", o.rho[:]) print("myrho", myo.W[N:N + M]) myret = myo.get_result() ret = o.get_result() self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6) # do a second iteration for i in range(1): myo.one_iteration() o.one_iteration() myret = myo.get_result() ret = o.get_result() if self.verbose: print("H0", myret.H0, ret.H0) print("rho ", o.rho[:]) print("myrho", myo.W[N:N + M]) self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6) def test_complete(self): myret = self.myo.run() ret = self.o.run() self.assertEqual(ret.nfev, myret.nfev) self.assertEqual(ret.nsteps, myret.nsteps) self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6)
class TestMYLBFGS_LBFGS(unittest.TestCase): def setUp(self): self.setUp1(verbose=False) def setUp1(self, verbose=False, **kwargs): np.random.seed(0) natoms = 18 self.system = LJCluster(natoms) self.pot = self.system.get_potential() x = self.system.get_random_configuration() ret = lbfgs_py(x, self.pot, tol=10) self.x = ret.coords self.kwargs = kwargs self.verbose = verbose self.M = 4 if self.verbose: iprint=1 else: iprint = -1 self.myo = MYLBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M) self.o = LBFGS(self.x, self.pot, iprint=iprint, debug=True, M=self.M, **self.kwargs) def test(self): N = self.x.size M = self.M myo = self.myo o = self.o # do one iteration for i in xrange(3 * self.M): myo.one_iteration() o.one_iteration() if self.verbose: print "" print "H0", myo.H0, o.H0 print "rho ", o.rho[:] print "myrho", myo.W[N:N+M] myret = myo.get_result() ret = o.get_result() self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6) # do a second iteration for i in xrange(1): myo.one_iteration() o.one_iteration() myret = myo.get_result() ret = o.get_result() if self.verbose: print "H0", myret.H0, ret.H0 print "rho ", o.rho[:] print "myrho", myo.W[N:N+M] self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6) def test_complete(self): myret = self.myo.run() ret = self.o.run() self.assertEqual(ret.nfev, myret.nfev) self.assertEqual(ret.nsteps, myret.nsteps) self.assertAlmostEqual(ret.energy, myret.energy, 4) self.assertLess(np.max(np.abs(myret.coords - ret.coords)), 1e-6)