Exemplo n.º 1
0
 def test_event(self):
     self.called = False
     def event(coords=None, energy=None, rms=None):
         self.called = True
     
     opt = LBFGS(self.x0, self.pot, events=[event])
     opt.one_iteration()
     self.assertTrue(self.called)
Exemplo n.º 2
0
    def test_event(self):
        self.called = False

        def event(coords=None, energy=None, rms=None):
            self.called = True

        opt = LBFGS(self.x0, self.pot, events=[event])
        opt.one_iteration()
        self.assertTrue(self.called)
Exemplo n.º 3
0
class TestLBFGS_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 = LBFGS(self.x, self.pot)
    
    def test_state(self):
        # do several minimization iterations
        for i in xrange(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 xrange(10):
            self.minimizer.one_iteration()
        
        # now make a new minimizer and do several iterations
        minimizer2 = LBFGS(x1, self.pot)
        minimizer2.set_state(state)
        for i in xrange(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.y == state2.y).all())
        self.assertTrue((state1.s == state2.s).all())
        self.assertTrue((state1.rho == state2.rho).all())
        self.assertTrue((state1.dXold == state2.dXold).all())
        self.assertTrue((state1.dGold == state2.dGold).all())
        self.assertEqual(state1.H0, state2.H0)
        self.assertEqual(state1.k, state2.k)
Exemplo n.º 4
0
    def test_reset(self):
        # do several minimization iterations
        m1 = LBFGS(self.x, self.pot)
        for i in xrange(10):
            m1.one_iteration()

        # reset the minimizer and do it again
        m1.reset()
        e, g = self.pot.getEnergyGradient(self.x)
        m1.update_coords(self.x, e, g)
        for i in xrange(10):
            m1.one_iteration()

        # do the same number of steps of a new minimizer
        m2 = LBFGS(self.x, self.pot)
        for i in xrange(10):
            m2.one_iteration()

        # they should be the same (more or less)
        n = min(m1.k, m1.M)
        self.assertAlmostEqual(m1.H0, m2.H0, 5)
        self.assertEqual(m1.k, m2.k)
        arrays_nearly_equal(self, m1.y[:n, :], m2.y[:n, :])
        arrays_nearly_equal(self, m1.s[:n, :], m2.s[:n, :])
        arrays_nearly_equal(self, m1.rho[:n], m2.rho[:n])

        res1 = m1.get_result()
        res2 = m2.get_result()
        self.assertNotEqual(res1.nfev, res2.nfev)
        self.assertNotEqual(res1.nsteps, res2.nsteps)
        self.assertAlmostEqual(res1.energy, res2.energy)
        arrays_nearly_equal(self, res1.coords, res2.coords)
Exemplo n.º 5
0
    def test_reset(self):
        # do several minimization iterations
        m1 = LBFGS(self.x, self.pot)
        for i in range(10):
            m1.one_iteration()

        # reset the minimizer and do it again
        m1.reset()
        e, g = self.pot.getEnergyGradient(self.x)
        m1.update_coords(self.x, e, g)
        for i in range(10):
            m1.one_iteration()

        # do the same number of steps of a new minimizer
        m2 = LBFGS(self.x, self.pot)
        for i in range(10):
            m2.one_iteration()

        # they should be the same (more or less)
        n = min(m1.k, m1.M)
        self.assertAlmostEqual(m1.H0, m2.H0, 5)
        self.assertEqual(m1.k, m2.k)
        arrays_nearly_equal(self, m1.y[:n, :], m2.y[:n, :])
        arrays_nearly_equal(self, m1.s[:n, :], m2.s[:n, :])
        arrays_nearly_equal(self, m1.rho[:n], m2.rho[:n])

        res1 = m1.get_result()
        res2 = m2.get_result()
        self.assertNotEqual(res1.nfev, res2.nfev)
        self.assertNotEqual(res1.nsteps, res2.nsteps)
        self.assertAlmostEqual(res1.energy, res2.energy)
        arrays_nearly_equal(self, res1.coords, res2.coords)
Exemplo n.º 6
0
    def test_state(self):
        # do several minimization iterations
        for i in xrange(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 xrange(10):
            self.minimizer.one_iteration()

        # now make a new minimizer and do several iterations
        minimizer2 = LBFGS(x1, self.pot)
        minimizer2.set_state(state)
        for i in xrange(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.y == state2.y).all())
        self.assertTrue((state1.s == state2.s).all())
        self.assertTrue((state1.rho == state2.rho).all())
        self.assertTrue((state1.dXold == state2.dXold).all())
        self.assertTrue((state1.dGold == state2.dGold).all())
        self.assertEqual(state1.H0, state2.H0)
        self.assertEqual(state1.k, state2.k)
Exemplo n.º 7
0
    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 = LBFGS(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.y == state2.y).all())
        self.assertTrue((state1.s == state2.s).all())
        self.assertTrue((state1.rho == state2.rho).all())
        self.assertTrue((state1.dXold == state2.dXold).all())
        self.assertTrue((state1.dGold == state2.dGold).all())
        self.assertEqual(state1.H0, state2.H0)
        self.assertEqual(state1.k, state2.k)
Exemplo n.º 8
0
class TestLBFGS_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 = LBFGS(self.x, self.pot)

    def test_state(self):
        # do several minimization iterations
        for i in xrange(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 xrange(10):
            self.minimizer.one_iteration()

        # now make a new minimizer and do several iterations
        minimizer2 = LBFGS(x1, self.pot)
        minimizer2.set_state(state)
        for i in xrange(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.y == state2.y).all())
        self.assertTrue((state1.s == state2.s).all())
        self.assertTrue((state1.rho == state2.rho).all())
        self.assertTrue((state1.dXold == state2.dXold).all())
        self.assertTrue((state1.dGold == state2.dGold).all())
        self.assertEqual(state1.H0, state2.H0)
        self.assertEqual(state1.k, state2.k)

    def test_reset(self):
        # do several minimization iterations
        m1 = LBFGS(self.x, self.pot)
        for i in xrange(10):
            m1.one_iteration()

        # reset the minimizer and do it again
        m1.reset()
        e, g = self.pot.getEnergyGradient(self.x)
        m1.update_coords(self.x, e, g)
        for i in xrange(10):
            m1.one_iteration()

        # do the same number of steps of a new minimizer
        m2 = LBFGS(self.x, self.pot)
        for i in xrange(10):
            m2.one_iteration()

        # they should be the same (more or less)
        n = min(m1.k, m1.M)
        self.assertAlmostEqual(m1.H0, m2.H0, 5)
        self.assertEqual(m1.k, m2.k)
        arrays_nearly_equal(self, m1.y[:n, :], m2.y[:n, :])
        arrays_nearly_equal(self, m1.s[:n, :], m2.s[:n, :])
        arrays_nearly_equal(self, m1.rho[:n], m2.rho[:n])

        res1 = m1.get_result()
        res2 = m2.get_result()
        self.assertNotEqual(res1.nfev, res2.nfev)
        self.assertNotEqual(res1.nsteps, res2.nsteps)
        self.assertAlmostEqual(res1.energy, res2.energy)
        arrays_nearly_equal(self, res1.coords, res2.coords)
Exemplo n.º 9
0
class _TransverseWalker(object):
    """It minimizes the energy in the direction perpendicular to a vector
    
    this class manages the minimization _TransversePotential
    
    Parameters
    ----------
    coords : float array
        the starting coordinates
    potential : Potential object
    eigenvec : float array
        energy will be minimized in the direction perpendicular to this vector
    energy, gradient : float and float array
        the energy and gradient at position coords
    minimizer_kwargs : kwargs
        these kwargs are passed to the minimizer
    
    """
    def __init__(self,
                 coords,
                 potential,
                 eigenvec,
                 energy=None,
                 gradient=None,
                 **minimizer_kwargs):
        self.tspot = _TransversePotential(potential, eigenvec)
        if energy is not None and gradient is not None:
            transverse_energy, transverse_gradient = self.tspot.projected_energy_gradient(
                energy, gradient)
        else:
            transverse_energy, transverse_gradient = None, None

        self.walker = LBFGS(coords,
                            self.tspot,
                            energy=transverse_energy,
                            gradient=transverse_gradient,
                            **minimizer_kwargs)

    def update_eigenvec(self, eigenvec, eigenval):
        """update the vecotr"""
        self.tspot.update_vector(eigenvec)

    def update_maxstep(self, maxstep):
        """update the maximum step size of the minimizer"""
        self.walker.maxstep = float(maxstep)

    def update_coords(self, coords, true_energy, true_gradient):
        """update the position of the optimizer
        
        this must be called after update_eigenvec
        """
        energy, gradient = self.tspot.projected_energy_gradient(
            true_energy, true_gradient)
        self.walker.update_coords(coords, energy, gradient)

    def stop_criterion_satisfied(self):
        """test if the stop criterion is satisfied"""
        return self.walker.stop_criterion_satisfied()

    def get_true_energy_gradient(self, coords):
        """return the true energy and gradient"""
        return self.tspot.get_true_energy_gradient(coords)

#    def get_energy(self):
#        """return the true energy
#
#        warning it's possible for this to return the wrong energy if the minimizer
#        had an aborted line search on the last iteration.
#        """
#        return self.tspot.true_energy
#
#    def get_gradient(self):
#        """return the true gradient
#
#        warning it's possible for this to return the wrong energy if the minimizer
#        had an aborted line search on the last iteration.
#        """
#        return self.tspot.true_gradient

    def get_result(self):
        """return the results object"""
        ret = self.walker.get_result()
        ret.nfev = self.tspot.nfev
        return ret

    def run(self, niter):
        """do a specified number of iterations, or until the stop criterion is satisfied"""
        for i in range(niter):
            if self.stop_criterion_satisfied():
                break
            self.walker.one_iteration()
        return self.get_result()
Exemplo n.º 10
0
class _DimerTranslator(object):
    """object to manage the translation of the dimer using an optimization algorithm
    
    Parameters
    ----------
    coords : float array
        the starting point of the dimer
    potential : Potential object
    eigenvec : float array
        the initial direction along which the dimer lies
    minimizer_kwargs : kwargs
        these kwargs are passed to the optimizer
    """
    def __init__(self, coords, potential, eigenvec, **minimizer_kwargs):
        self.dimer_potential = _DimerPotential(potential, eigenvec)
        self.minimizer = LBFGS(coords, self.dimer_potential, **minimizer_kwargs)

    def stop_criterion_satisfied(self):
        """test if the stop criterion is satisfied"""
        return self.minimizer.stop_criterion_satisfied()

    def get_true_energy_gradient(self, coords):
        """return the true energy and gradient"""
        return self.dimer_potential.get_true_energy_gradient(coords)

#    def get_energy(self):
#        """return the true energy"""
#        return self.dimer_potential.true_energy
#
#    def get_gradient(self):
#        """return the true gradient"""
#        return self.dimer_potential.true_gradient
    
    def update_eigenvec(self, eigenvec, eigenval):
        """update the direction (rotation) of the dimer"""
        self.dimer_potential.update_eigenvec(eigenvec)
    
    def update_coords(self, coords, true_energy, true_gradient):
        """update the position of the dimer
        
        this must be called after update_eigenvec
        """
        energy, gradient = self.dimer_potential.projected_energy_gradient(true_energy, true_gradient)
        self.minimizer.update_coords(coords, energy, gradient)

    def update_maxstep(self, maxstep):
        """change the maximum step size of the optimizer"""
        self.minimizer.maxstep = float(maxstep)

    def run(self, niter):
        """do a specified number of iterations, or until the stop criterion is satisfied"""
        for i in xrange(niter):
            if self.stop_criterion_satisfied():
                break
            self.minimizer.one_iteration()
        return self.get_result()
    
    def get_result(self):
        """return the results object"""
        return self.minimizer.get_result()
    
    def projected_energy_gradient(self, energy, gradient):
        """return the projected energy and gradient"""
        return self.dimer_potential.projected_energy_gradient(energy, gradient)
Exemplo n.º 11
0
class _DimerTranslator(object):
    """object to manage the translation of the dimer using an optimization algorithm
    
    Parameters
    ----------
    coords : float array
        the starting point of the dimer
    potential : Potential object
    eigenvec : float array
        the initial direction along which the dimer lies
    minimizer_kwargs : kwargs
        these kwargs are passed to the optimizer
    """
    def __init__(self, coords, potential, eigenvec, **minimizer_kwargs):
        self.dimer_potential = _DimerPotential(potential, eigenvec)
        self.minimizer = LBFGS(coords, self.dimer_potential,
                               **minimizer_kwargs)

    def stop_criterion_satisfied(self):
        """test if the stop criterion is satisfied"""
        return self.minimizer.stop_criterion_satisfied()

    def get_true_energy_gradient(self, coords):
        """return the true energy and gradient"""
        return self.dimer_potential.get_true_energy_gradient(coords)


#    def get_energy(self):
#        """return the true energy"""
#        return self.dimer_potential.true_energy
#
#    def get_gradient(self):
#        """return the true gradient"""
#        return self.dimer_potential.true_gradient

    def update_eigenvec(self, eigenvec, eigenval):
        """update the direction (rotation) of the dimer"""
        self.dimer_potential.update_eigenvec(eigenvec)

    def update_coords(self, coords, true_energy, true_gradient):
        """update the position of the dimer
        
        this must be called after update_eigenvec
        """
        energy, gradient = self.dimer_potential.projected_energy_gradient(
            true_energy, true_gradient)
        self.minimizer.update_coords(coords, energy, gradient)

    def update_maxstep(self, maxstep):
        """change the maximum step size of the optimizer"""
        self.minimizer.maxstep = float(maxstep)

    def run(self, niter):
        """do a specified number of iterations, or until the stop criterion is satisfied"""
        for i in xrange(niter):
            if self.stop_criterion_satisfied():
                break
            self.minimizer.one_iteration()
        return self.get_result()

    def get_result(self):
        """return the results object"""
        return self.minimizer.get_result()

    def projected_energy_gradient(self, energy, gradient):
        """return the projected energy and gradient"""
        return self.dimer_potential.projected_energy_gradient(energy, gradient)
Exemplo n.º 12
0
class TestLBFGS_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 = LBFGS(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 = LBFGS(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.y == state2.y).all())
        self.assertTrue((state1.s == state2.s).all())
        self.assertTrue((state1.rho == state2.rho).all())
        self.assertTrue((state1.dXold == state2.dXold).all())
        self.assertTrue((state1.dGold == state2.dGold).all())
        self.assertEqual(state1.H0, state2.H0)
        self.assertEqual(state1.k, state2.k)

    def test_reset(self):
        # do several minimization iterations
        m1 = LBFGS(self.x, self.pot)
        for i in range(10):
            m1.one_iteration()

        # reset the minimizer and do it again
        m1.reset()
        e, g = self.pot.getEnergyGradient(self.x)
        m1.update_coords(self.x, e, g)
        for i in range(10):
            m1.one_iteration()

        # do the same number of steps of a new minimizer
        m2 = LBFGS(self.x, self.pot)
        for i in range(10):
            m2.one_iteration()

        # they should be the same (more or less)
        n = min(m1.k, m1.M)
        self.assertAlmostEqual(m1.H0, m2.H0, 5)
        self.assertEqual(m1.k, m2.k)
        arrays_nearly_equal(self, m1.y[:n, :], m2.y[:n, :])
        arrays_nearly_equal(self, m1.s[:n, :], m2.s[:n, :])
        arrays_nearly_equal(self, m1.rho[:n], m2.rho[:n])

        res1 = m1.get_result()
        res2 = m2.get_result()
        self.assertNotEqual(res1.nfev, res2.nfev)
        self.assertNotEqual(res1.nsteps, res2.nsteps)
        self.assertAlmostEqual(res1.energy, res2.energy)
        arrays_nearly_equal(self, res1.coords, res2.coords)
Exemplo n.º 13
0
class _TransverseWalker(object):
    """It minimizes the energy in the direction perpendicular to a vector
    
    this class manages the minimization _TransversePotential
    
    Parameters
    ----------
    coords : float array
        the starting coordinates
    potential : Potential object
    eigenvec : float array
        energy will be minimized in the direction perpendicular to this vector
    energy, gradient : float and float array
        the energy and gradient at position coords
    minimizer_kwargs : kwargs
        these kwargs are passed to the minimizer
    
    """
    def __init__(self, coords, potential, eigenvec, energy=None, gradient=None, **minimizer_kwargs):
        self.tspot = _TransversePotential(potential, eigenvec)
        if energy is not None and gradient is not None:
            transverse_energy, transverse_gradient = self.tspot.projected_energy_gradient(energy, gradient)
        else:
            transverse_energy, transverse_gradient = None, None

        self.walker = LBFGS(coords, self.tspot,
                            energy=transverse_energy, gradient=transverse_gradient,
                            **minimizer_kwargs)
    
    def update_eigenvec(self, eigenvec, eigenval):
        """update the vecotr"""
        self.tspot.update_vector(eigenvec)
    
    def update_maxstep(self, maxstep):
        """update the maximum step size of the minimizer"""
        self.walker.maxstep = float(maxstep)
        
    def update_coords(self, coords, true_energy, true_gradient):
        """update the position of the optimizer
        
        this must be called after update_eigenvec
        """
        energy, gradient = self.tspot.projected_energy_gradient(true_energy, true_gradient)
        self.walker.update_coords(coords, energy, gradient)
    
    def stop_criterion_satisfied(self):
        """test if the stop criterion is satisfied"""
        return self.walker.stop_criterion_satisfied()

    def get_true_energy_gradient(self, coords):
        """return the true energy and gradient"""
        return self.tspot.get_true_energy_gradient(coords)

#    def get_energy(self):
#        """return the true energy
#        
#        warning it's possible for this to return the wrong energy if the minimizer
#        had an aborted line search on the last iteration.
#        """
#        return self.tspot.true_energy
#
#    def get_gradient(self):
#        """return the true gradient
#        
#        warning it's possible for this to return the wrong energy if the minimizer
#        had an aborted line search on the last iteration.
#        """
#        return self.tspot.true_gradient

    def get_result(self):
        """return the results object"""
        ret = self.walker.get_result()
        ret.nfev = self.tspot.nfev
        return ret
    
    def run(self, niter):
        """do a specified number of iterations, or until the stop criterion is satisfied"""
        for i in range(niter):
            if self.stop_criterion_satisfied():
                break
            self.walker.one_iteration()
        return self.get_result()