Exemple #1
0
 def prepare_opt(self):
     if self.is_cos and self.align:
         procrustes(self.geometry)
     # Calculate initial forces before the first iteration
     self.coords.append(self.geometry.coords)
     self.forces.append(self.geometry.forces)
     self.energies.append(self.geometry.energy)
Exemple #2
0
    def optimize(self):
        if self.is_cos and self.align:
            procrustes(self.geometry)

        self.forces.append(self.geometry.forces)

        step = self.alpha*self.forces[-1]
        step = self.scale_by_max_step(step)
        return step
Exemple #3
0
    def optimize(self):
        if self.is_cos and self.align:
            procrustes(self.geometry)

        self.forces.append(self.geometry.forces)
        self.energies.append(self.geometry.energy)

        if self.cur_cycle > 0:
            self.skip = self.backtrack(self.forces[-1], self.forces[-2])

        step = self.alpha*self.forces[-1]
        step = self.scale_by_max_step(step)
        return step
Exemple #4
0
def align(geoms):
    """Align all geometries onto the first using partical procrustes."""
    cos = ChainOfStates.ChainOfStates(geoms)
    procrustes(cos)
    return [geom for geom in cos.images]
    def optimize(self):
        new_image_inds = self.geometry.new_image_inds
        string_size_changed = len(new_image_inds) > 0

        if self.align and string_size_changed and self.is_cart_opt:
            procrustes(self.geometry)
            self.log("Aligned string.")

        forces = self.geometry.forces
        self.energies.append(self.geometry.energy)
        self.forces.append(forces)

        cur_size = self.geometry.string_size
        add_to_list = (
            self.keep_last >
            0  # Only add to s_list and y_list if we want to keep
            and self.cur_cycle >
            0  # cycles and if we can actually calculate differences.
            and
            (not self.
             lbfgs_when_full  # Add when LBFGS is allowed before fully grown.
             or self.lbfgs_when_full and self.geometry.fully_grown and
             not string_size_changed  # Don't add when string has to be fully grown
             # but grew fully in this cycle.
             ))
        if add_to_list:
            inds = list(range(cur_size))
            try:
                y = self.forces[-2] - forces
                s = self.coords[-1] - self.coords[-2]
            # Will be raised when the string grew in the previous cycle.
            except ValueError:
                cur_forces = np.delete(forces.reshape(cur_size, -1),
                                       new_image_inds,
                                       axis=0).flatten()
                y = self.forces[-2] - cur_forces
                cur_coords = np.delete(self.coords[-1].reshape(cur_size, -1),
                                       new_image_inds,
                                       axis=0).flatten()
                s = self.coords[-2] - cur_coords
                inds = np.delete(inds, new_image_inds)

            if self.double_damp:
                s, y = double_damp(s,
                                   y,
                                   s_list=self.s_list,
                                   y_list=self.y_list)

            self.s_list.append(s)
            self.y_list.append(y)
            self.inds.append(inds)
            # Drop oldest vectors
            self.s_list = self.s_list[-self.keep_last:]
            self.y_list = self.y_list[-self.keep_last:]
            self.inds = self.inds[-self.keep_last:]

        # Results in steepest descent step for empty s_list & y_list
        step = bfgs_multiply(self.s_list,
                             self.y_list,
                             forces,
                             gamma_mult=self.gamma_mult,
                             inds=self.inds,
                             cur_size=cur_size,
                             logger=self.logger)

        # When keep_last == 0 or LBFGS is not yet enabled then s_list and y_list will
        # be empty and step will be a simple SD step. We try to improve it via CG.
        if ((self.keep_last == 0 and self.cur_cycle > 0
             and not string_size_changed)
                and (len(self.s_list) == 0 and len(self.y_list) == 0)):
            prev_forces = self.forces[-2]
            # Fletcher-Reeves
            beta = forces.dot(forces) / prev_forces.dot(prev_forces)
            # Polar-Ribiere
            # beta = forces.dot(forces - prev_forces) / prev_forces.dot(prev_forces)
            beta = min(beta, 1)
            step = forces + beta * self.steps[-1]
            self.log(f"Conjugate gradient correction, β={beta:.6f}")

        if self.scale_step == "global":
            step = scale_by_max_step(step, self.max_step)
        elif self.scale_step == "per_image":
            for image_step in step.reshape(len(self.geometry.images), -1):
                scale_by_max_step(image_step, self.max_step)
        else:
            raise Exception("Invalid scale_step={self.scale_step}!")

        return step
 def prepare_opt(self):
     if self.align and self.is_cart_opt:
         procrustes(self.geometry)