Beispiel #1
0
    def buildHessian(self, coords, cutoff=15.0, gamma=1.0, **kwargs):
        """Build Hessian matrix for given coordinate set.
        
        :arg coords: a coordinate set or anything with getCoordinates method
        :type coords: :class:`~numpy.ndarray` or :class:`~prody.atomic.Atomic`
        
        :arg cutoff: cutoff distance (Å) for pairwise interactions,
            default is 15.0 Å, minimum is 4.0 Å 
        :type cutoff: float
        
        :arg gamma: spring constant, default is 1.0 
        :type gamma: float, :class:`Gamma`
        
        :arg sparse: slect to use sparse matrices. Default is ``False``. If 
            Scipy is not found, :class:`ImportError` is raised.
        :type sparse: bool
        
        Instances of :class:`Gamma` classes and custom functions are
        accepted as *gamma* argument.        
    
        When Scipy is available, user can select to use sparse matrices for
        efficient usage of memory at the cost of computation speed."""

        slow = kwargs.get("slow", False)
        try:
            from KDTree import KDTree
        except ImportError:
            KDTree = False
        if not slow and not KDTree:
            LOGGER.info("Using a slower method for building the Hessian " "matrix.")
        if not isinstance(coords, np.ndarray):
            try:
                coords = coords.getCoords()
            except AttributeError:
                raise TypeError("coords must be a Numpy array or must have " "getCoordinates attribute")
        coords = checkCoords(coords, "coords")
        cutoff, g, gamma = checkENMParameters(cutoff, gamma)
        self._reset()
        self._cutoff = cutoff
        self._gamma = g
        n_atoms = coords.shape[0]
        dof = n_atoms * 3
        start = time.time()

        if kwargs.get("sparse", False):
            try:
                from scipy import sparse as scipy_sparse
            except ImportError:
                raise ImportError("failed to import scipy.sparse, which  is " "required for sparse matrix calculations")
            kirchhoff = scipy_sparse.lil_matrix((n_atoms, n_atoms))
            hessian = scipy_sparse.lil_matrix((dof, dof))
        else:
            kirchhoff = np.zeros((n_atoms, n_atoms), "d")
            hessian = np.zeros((dof, dof), float)
        if not slow and KDTree:
            kdtree = getKDTree(coords)
            kdtree.all_search(cutoff)
            for i, j in kdtree.all_get_indices():
                i2j = coords[j] - coords[i]
                dist2 = np.dot(i2j, i2j)
                g = gamma(dist2, i, j)
                super_element = np.outer(i2j, i2j) * (-g / dist2)
                res_i3 = i * 3
                res_i33 = res_i3 + 3
                res_j3 = j * 3
                res_j33 = res_j3 + 3
                hessian[res_i3:res_i33, res_j3:res_j33] = super_element
                hessian[res_j3:res_j33, res_i3:res_i33] = super_element
                hessian[res_i3:res_i33, res_i3:res_i33] = hessian[res_i3:res_i33, res_i3:res_i33] - super_element
                hessian[res_j3:res_j33, res_j3:res_j33] = hessian[res_j3:res_j33, res_j3:res_j33] - super_element
                kirchhoff[i, j] = -g
                kirchhoff[j, i] = -g
                kirchhoff[i, i] = kirchhoff[i, i] - g
                kirchhoff[j, j] = kirchhoff[j, j] - g
        else:
            cutoff2 = cutoff * cutoff
            for i in range(n_atoms):
                res_i3 = i * 3
                res_i33 = res_i3 + 3
                xyz_i = coords[i, :]
                for j in range(i + 1, n_atoms):
                    i2j = coords[j, :] - xyz_i
                    dist2 = np.dot(i2j, i2j)
                    if dist2 > cutoff2:
                        continue
                    g = gamma(dist2, i, j)
                    res_j3 = j * 3
                    res_j33 = res_j3 + 3
                    super_element = np.outer(i2j, i2j) * (-g / dist2)
                    hessian[res_i3:res_i33, res_j3:res_j33] = super_element
                    hessian[res_j3:res_j33, res_i3:res_i33] = super_element
                    hessian[res_i3:res_i33, res_i3:res_i33] = hessian[res_i3:res_i33, res_i3:res_i33] - super_element
                    hessian[res_j3:res_j33, res_j3:res_j33] = hessian[res_j3:res_j33, res_j3:res_j33] - super_element
                    kirchhoff[i, j] = -g
                    kirchhoff[j, i] = -g
                    kirchhoff[i, i] = kirchhoff[i, i] - g
                    kirchhoff[j, j] = kirchhoff[j, j] - g
        LOGGER.info("Hessian was built in {0:.2f}s.".format(time.time() - start))
        self._kirchhoff = kirchhoff
        self._hessian = hessian
        self._n_atoms = n_atoms
        self._dof = dof
Beispiel #2
0
    def buildHessian(self, coords, cutoff=15., gamma=1., **kwargs):
        """Build Hessian matrix for given coordinate set.
        
        :arg coords: a coordinate set or an object with ``getCoords`` method
        :type coords: :class:`numpy.ndarray`
        
        :arg cutoff: cutoff distance (Å) for pairwise interactions,
            default is 15.0 Å, minimum is 4.0 Å 
        :type cutoff: float
        
        :arg gamma: spring constant, default is 1.0 
        :type gamma: float, :class:`Gamma`
        
        :arg sparse: elect to use sparse matrices, default is **False**. If 
            Scipy is not found, :class:`ImportError` is raised.
        :type sparse: bool
        
        :arg kdtree: elect to use KDTree for building Hessian matrix, 
            default is **False** since KDTree method is slower
        :type kdtree: bool

        
        Instances of :class:`Gamma` classes and custom functions are
        accepted as *gamma* argument.        
    
        When Scipy is available, user can select to use sparse matrices for
        efficient usage of memory at the cost of computation speed."""
        
        try:
            coords = (coords._getCoords() if hasattr(coords, '_getCoords') else
                      coords.getCoords()) 
        except AttributeError:
            try:
                checkCoords(coords)
            except TypeError:
                raise TypeError('coords must be a Numpy array or an object '
                                'with `getCoords` method')
        
        cutoff, g, gamma = checkENMParameters(cutoff, gamma)
        self._reset()
        self._cutoff = cutoff
        self._gamma = g
        n_atoms = coords.shape[0]
        dof = n_atoms * 3
        start = time.time()
        
        if kwargs.get('sparse', False):
            try:
                from scipy import sparse as scipy_sparse
            except ImportError:    
                raise ImportError('failed to import scipy.sparse, which  is '
                                  'required for sparse matrix calculations')
            kirchhoff = scipy_sparse.lil_matrix((n_atoms, n_atoms))
            hessian = scipy_sparse.lil_matrix((dof, dof))
        else:
            kirchhoff = np.zeros((n_atoms, n_atoms), 'd')
            hessian = np.zeros((dof, dof), float)
            
        if kwargs.get('kdtree', False):
            LOGGER.info('Using KDTree for building the Hessian.')
            kdtree = KDTree(coords) 
            kdtree.search(cutoff)
            for i, j in kdtree.getIndices():
                i2j = coords[j] - coords[i]
                dist2 = np.dot(i2j, i2j)
                g = gamma(dist2, i, j)
                super_element = np.outer(i2j, i2j) * (- g / dist2)  
                res_i3 = i*3
                res_i33 = res_i3+3
                res_j3 = j*3
                res_j33 = res_j3+3
                hessian[res_i3:res_i33, res_j3:res_j33] = super_element
                hessian[res_j3:res_j33, res_i3:res_i33] = super_element
                hessian[res_i3:res_i33, res_i3:res_i33] = \
                    hessian[res_i3:res_i33, res_i3:res_i33] - super_element
                hessian[res_j3:res_j33, res_j3:res_j33] = \
                    hessian[res_j3:res_j33, res_j3:res_j33] - super_element
                kirchhoff[i, j] = -g
                kirchhoff[j, i] = -g
                kirchhoff[i, i] = kirchhoff[i, i] - g
                kirchhoff[j, j] = kirchhoff[j, j] - g
        else:
            cutoff2 = cutoff * cutoff 
            for i in range(n_atoms):
                res_i3 = i*3
                res_i33 = res_i3+3
                i_p1 = i+1
                i2j_all = coords[i_p1:, :] - coords[i]
                for j, dist2 in enumerate((i2j_all ** 2).sum(1)):
                    if dist2 > cutoff2:
                        continue             
                    i2j = i2j_all[j]
                    j += i_p1
                    g = gamma(dist2, i, j)
                    res_j3 = j*3
                    res_j33 = res_j3+3
                    super_element = np.outer(i2j, i2j) * (- g / dist2) 
                    hessian[res_i3:res_i33, res_j3:res_j33] = super_element 
                    hessian[res_j3:res_j33, res_i3:res_i33] = super_element
                    hessian[res_i3:res_i33, res_i3:res_i33] = \
                        hessian[res_i3:res_i33, res_i3:res_i33] - super_element
                    hessian[res_j3:res_j33, res_j3:res_j33] = \
                        hessian[res_j3:res_j33, res_j3:res_j33] - super_element
                    kirchhoff[i, j] = -g
                    kirchhoff[j, i] = -g
                    kirchhoff[i, i] = kirchhoff[i, i] - g
                    kirchhoff[j, j] = kirchhoff[j, j] - g
        LOGGER.info('Hessian was built in {0:.2f}s.'.format(time.time()-start))
        self._kirchhoff = kirchhoff
        self._hessian = hessian
        self._n_atoms = n_atoms
        self._dof = dof