Ejemplo n.º 1
0
    def do_no_stepsearch(self, obj, one, two, orb, **kwargs):
        '''Scale step size with factor self.alpha

           **Arguments:**

           obj
                A class instance containing the objective function.

           one, two
                One- and Two-electron integrals (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                An Expansion instance. Contains the MO coefficients

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')

        #
        # Scale current optimization step, rotate orbitals
        #
        kappa.iscale(self.alpha)
        rotation = obj.compute_rotation_matrix(kappa)
        rotate_orbitals(orb, rotation)

        #
        # Solve for wfn/population model
        #
        try:
            obj.solve_model(one, two, orb, **kwargs)
        except:
            pass
Ejemplo n.º 2
0
    def do_no_stepsearch(self, obj, one, two, orb, **kwargs):
        '''Scale step size with factor self.alpha

           **Arguments:**

           obj
                A class instance containing the objective function.

           one, two
                One- and Two-electron integrals (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                An Expansion instance. Contains the MO coefficients

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')

        #
        # Scale current optimization step, rotate orbitals
        #
        kappa.iscale(self.alpha)
        rotation = obj.compute_rotation_matrix(kappa)
        rotate_orbitals(orb, rotation)

        #
        # Solve for wfn/population model
        #
        try:
            obj.solve_model(one, two, orb, **kwargs)
        except:
            pass
Ejemplo n.º 3
0
    def do_trust_region(self, obj, one, two, orb, **kwargs):
        '''Do trust-region optimization.

           **Arguments:**

           obj
                A class instance containing the objective function.

           one/two
                One and Two-body Hamiltonian (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                (Expansion instance) An MO expansion

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
                :gradient: Orbital gradient (OneIndex instance)
                :hessian: Orbital Hessian (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')
        gradient = kwargs.get('gradient')
        hessian = kwargs.get('hessian')

        iteri = 1
        ofun_ref = obj.compute_objective_function()
        De = 0.0

        stepn = kappa.copy()
        while True:
            norm = stepn.norm()
            #
            # If ||kappa||_2 is outside the trust region, find a new Newton
            # step inside the trust region:
            #
            if norm > self.trustradius:
                #
                # Preconditioned conjugate gradient
                #
                if self.optimizer == 'pcg':
                    optimizer = TruncatedCG(self.lf, gradient, hessian, self.trustradius)
                    optimizer(**{'niter': self.maxiterinner, 'abstol': self.threshold})
                    stepn = optimizer.step
                #
                # Powell's dogleg optimization:
                #
                elif self.optimizer == 'dogleg':
                    optimizer = Dogleg(kappa, gradient, hessian, self.trustradius)
                    optimizer()
                    stepn = optimizer.step
                #
                # Powell's double dogleg optimization:
                #
                elif self.optimizer == 'ddl':
                    optimizer = DoubleDogleg(kappa, gradient, hessian, self.trustradius)
                    optimizer()
                    stepn = optimizer.step
            #
            # New rotation
            #
            rotation = obj.compute_rotation_matrix(stepn)
            orb_ = orb.copy()
            rotate_orbitals(orb_, rotation)

            #
            # Solve for wfn/population model if required
            #
            try:
                obj.solve_model(one, two, orb_, **kwargs)
            except:
                pass

            #
            # Calculate objective function after rotation
            #
            ofun = obj.compute_objective_function()

            #
            # Determine ratio for a given step:
            #
            hstep = hessian.new()
            hessian.mult(stepn, hstep)
            Destimate = gradient.dot(stepn)+0.5*stepn.dot(hstep)
            De = ofun-ofun_ref
            rho = De/Destimate

            #
            # For a given ratio, adjust trust radius and accept or reject
            # Newton step:
            #
            if rho > self.maxeta and De <= 0.0:
                #
                # Enlarge trust radius:
                #
                new = min(self.upscale*self.trustradius,self.maxtrustradius)
                self.update_trustradius(new)
                orb.assign(orb_)
                break
            elif rho >= self.mineta and rho <= self.maxeta and De <= 0.0:
                #
                # Do nothing with trust radius:
                #
                orb.assign(orb_)
                break
            elif rho > 0 and rho < self.mineta and De <= 0.0:
                #
                # Decrease trust radius:
                #
                self.update_trustradius(self.downscale*self.trustradius)
                orb.assign(orb_)
                break
            else:
                #
                # Bad step! Reject Newton step and repeat with smaller trust
                # radius
                #
                self.update_trustradius(self.downscale*self.trustradius)

            iteri = iteri+1
            if iteri > self.maxiterouter:
                log('Warning: Trust region search not converged after %i iterations. Trust region search aborted.' %self.maxiterouter)
                orb.assign(orb_)
                break
Ejemplo n.º 4
0
    def do_backtracking(self, obj, one, two, orb, **kwargs):
        '''Backtracking line search.

           **Arguments:**

           obj
                A class instance containing the objctive function.

           one, two
                One- and Two-electron integrals (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                An Expansion instance. Contains the MO coefficients

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
                :gradient: Orbital gradient (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')
        gradient = kwargs.get('gradient')

        #
        # Update scaling factor to initial value
        #
        self.update_alpha(self.alpha0)

        #
        # Calculate objective function
        #
        ofun_ref = obj.compute_objective_function()

        #
        # Copy current orbitals
        #
        orb_ = orb.copy()
        #
        # Initial rotation
        #
        kappa.iscale(self.alpha)
        rotation = obj.compute_rotation_matrix(kappa)
        rotate_orbitals(orb_, rotation)

        #
        # Solve for wfn/population model if required
        #
        try:
            obj.solve_model(one, two, orb_, **kwargs)
        except:
            pass

        #
        # Calculate objective function for rotated orbitals
        #
        ofun = obj.compute_objective_function()

        #
        # reduce step size until line search condition is satisfied
        #
        while self.check_line_search_condition(ofun, ofun_ref, kappa, gradient):
            self.update_alpha(self.alpha*self.downscale)
            #
            # New rotation
            #
            kappa.iscale(self.alpha)
            rotation = obj.compute_rotation_matrix(kappa)
            orb_ = orb.copy()
            rotate_orbitals(orb_, rotation)
            #
            # Solve for wfn/population model if required
            #
            try:
                obj.solve_model(one, two, orb_, **kwargs)
            except:
                pass
            #
            # Calculate objective function for scaled rotation
            #
            ofun = obj.compute_objective_function()
            #
            # Abort if scaling factor falls below threshold
            #
            if self.alpha < self.minalpha:
                break
        orb.assign(orb_)
Ejemplo n.º 5
0
    def do_trust_region(self, obj, one, two, orb, **kwargs):
        '''Do trust-region optimization.

           **Arguments:**

           obj
                A class instance containing the objective function.

           one/two
                One and Two-body Hamiltonian (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                (Expansion instance) An MO expansion

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
                :gradient: Orbital gradient (OneIndex instance)
                :hessian: Orbital Hessian (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')
        gradient = kwargs.get('gradient')
        hessian = kwargs.get('hessian')

        iteri = 1
        ofun_ref = obj.compute_objective_function()
        De = 0.0

        stepn = kappa.copy()
        while True:
            norm = stepn.norm()
            #
            # If ||kappa||_2 is outside the trust region, find a new Newton
            # step inside the trust region:
            #
            if norm > self.trustradius:
                #
                # Preconditioned conjugate gradient
                #
                if self.optimizer == 'pcg':
                    optimizer = TruncatedCG(self.lf, gradient, hessian,
                                            self.trustradius)
                    optimizer(**{
                        'niter': self.maxiterinner,
                        'abstol': self.threshold
                    })
                    stepn = optimizer.step
                #
                # Powell's dogleg optimization:
                #
                elif self.optimizer == 'dogleg':
                    optimizer = Dogleg(kappa, gradient, hessian,
                                       self.trustradius)
                    optimizer()
                    stepn = optimizer.step
                #
                # Powell's double dogleg optimization:
                #
                elif self.optimizer == 'ddl':
                    optimizer = DoubleDogleg(kappa, gradient, hessian,
                                             self.trustradius)
                    optimizer()
                    stepn = optimizer.step
            #
            # New rotation
            #
            rotation = obj.compute_rotation_matrix(stepn)
            orb_ = orb.copy()
            rotate_orbitals(orb_, rotation)

            #
            # Solve for wfn/population model if required
            #
            try:
                obj.solve_model(one, two, orb_, **kwargs)
            except:
                pass

            #
            # Calculate objective function after rotation
            #
            ofun = obj.compute_objective_function()

            #
            # Determine ratio for a given step:
            #
            hstep = hessian.new()
            hessian.mult(stepn, hstep)
            Destimate = gradient.dot(stepn) + 0.5 * stepn.dot(hstep)
            De = ofun - ofun_ref
            rho = De / Destimate

            #
            # For a given ratio, adjust trust radius and accept or reject
            # Newton step:
            #
            if rho > self.maxeta and De <= 0.0:
                #
                # Enlarge trust radius:
                #
                new = min(self.upscale * self.trustradius, self.maxtrustradius)
                self.update_trustradius(new)
                orb.assign(orb_)
                break
            elif rho >= self.mineta and rho <= self.maxeta and De <= 0.0:
                #
                # Do nothing with trust radius:
                #
                orb.assign(orb_)
                break
            elif rho > 0 and rho < self.mineta and De <= 0.0:
                #
                # Decrease trust radius:
                #
                self.update_trustradius(self.downscale * self.trustradius)
                orb.assign(orb_)
                break
            else:
                #
                # Bad step! Reject Newton step and repeat with smaller trust
                # radius
                #
                self.update_trustradius(self.downscale * self.trustradius)

            iteri = iteri + 1
            if iteri > self.maxiterouter:
                log('Warning: Trust region search not converged after %i iterations. Trust region search aborted.'
                    % self.maxiterouter)
                orb.assign(orb_)
                break
Ejemplo n.º 6
0
    def do_backtracking(self, obj, one, two, orb, **kwargs):
        '''Backtracking line search.

           **Arguments:**

           obj
                A class instance containing the objctive function.

           one, two
                One- and Two-electron integrals (TwoIndex and FourIndex/Cholesky
                instances)

           orb
                An Expansion instance. Contains the MO coefficients

           **Keywords:**
                :kappa: Initial step size (OneIndex instance)
                :gradient: Orbital gradient (OneIndex instance)
        '''
        kappa = kwargs.get('kappa')
        gradient = kwargs.get('gradient')

        #
        # Update scaling factor to initial value
        #
        self.update_alpha(self.alpha0)

        #
        # Calculate objective function
        #
        ofun_ref = obj.compute_objective_function()

        #
        # Copy current orbitals
        #
        orb_ = orb.copy()
        #
        # Initial rotation
        #
        kappa.iscale(self.alpha)
        rotation = obj.compute_rotation_matrix(kappa)
        rotate_orbitals(orb_, rotation)

        #
        # Solve for wfn/population model if required
        #
        try:
            obj.solve_model(one, two, orb_, **kwargs)
        except:
            pass

        #
        # Calculate objective function for rotated orbitals
        #
        ofun = obj.compute_objective_function()

        #
        # reduce step size until line search condition is satisfied
        #
        while self.check_line_search_condition(ofun, ofun_ref, kappa,
                                               gradient):
            self.update_alpha(self.alpha * self.downscale)
            #
            # New rotation
            #
            kappa.iscale(self.alpha)
            rotation = obj.compute_rotation_matrix(kappa)
            orb_ = orb.copy()
            rotate_orbitals(orb_, rotation)
            #
            # Solve for wfn/population model if required
            #
            try:
                obj.solve_model(one, two, orb_, **kwargs)
            except:
                pass
            #
            # Calculate objective function for scaled rotation
            #
            ofun = obj.compute_objective_function()
            #
            # Abort if scaling factor falls below threshold
            #
            if self.alpha < self.minalpha:
                break
        orb.assign(orb_)