コード例 #1
0
ファイル: phonon.py プロジェクト: fyalcin/sisl
def _velocity(mode, hw, dDk, degenerate):
    r""" For modes in an orthogonal basis """

    # Along all directions
    v = np.empty([mode.shape[0], 3], dtype=dtype_complex_to_real(mode.dtype))

    # Decouple the degenerate modes
    if not degenerate is None:
        for deg in degenerate:
            # Set the average frequency
            hw[deg] = np.average(hw[deg])

            # Now diagonalize to find the contributions from individual modes
            # then re-construct the seperated degenerate modes
            # Since we do this for all directions we should decouple them all
            vv = conj(mode[deg, :]).dot(dDk[0].dot(mode[deg, :].T))
            S = eigh_destroy(vv)[1].T.dot(mode[deg, :])
            vv = conj(S).dot((dDk[1]).dot(S.T))
            S = eigh_destroy(vv)[1].T.dot(S)
            vv = conj(S).dot((dDk[2]).dot(S.T))
            mode[deg, :] = eigh_destroy(vv)[1].T.dot(S)

    v[:, 0] = (conj(mode.T) * dDk[0].dot(mode.T)).sum(0).real
    v[:, 1] = (conj(mode.T) * dDk[1].dot(mode.T)).sum(0).real
    v[:, 2] = (conj(mode.T) * dDk[2].dot(mode.T)).sum(0).real

    # Set everything to zero for the negative frequencies
    v[hw < 0, :] = 0

    return v * _velocity_const / (2 * hw.reshape(-1, 1))
コード例 #2
0
    def eigh(self, k=(0, 0, 0), gauge='R', eigvals_only=True, **kwargs):
        """ Returns the eigenvalues of the physical quantity

        Setup the system and overlap matrix with respect to
        the given k-point and calculate the eigenvalues.

        All subsequent arguments gets passed directly to :code:`scipy.linalg.eigh`

        Parameters
        ----------
        spin : int, optional
           the spin-component to calculate the eigenvalue spectrum of, note that
           this parameter is only valid for `Spin.POLARIZED` matrices.
        """
        spin = kwargs.pop('spin', 0)
        dtype = kwargs.pop('dtype', None)

        if self.spin.kind == Spin.POLARIZED:
            P = self.Pk(k=k, dtype=dtype, gauge=gauge, spin=spin, format='array')
        else:
            P = self.Pk(k=k, dtype=dtype, gauge=gauge, format='array')

        if self.orthogonal:
            return lin.eigh_destroy(P, eigvals_only=eigvals_only, **kwargs)

        S = self.Sk(k=k, dtype=dtype, gauge=gauge, format='array')
        return lin.eigh_destroy(P, S, eigvals_only=eigvals_only, **kwargs)
コード例 #3
0
    def eigh(self, k=(0, 0, 0), gauge='R', eigvals_only=True, **kwargs):
        """ Returns the eigenvalues of the physical quantity

        Setup the system and overlap matrix with respect to
        the given k-point and calculate the eigenvalues.

        All subsequent arguments gets passed directly to :code:`scipy.linalg.eigh`
        """
        dtype = kwargs.pop('dtype', None)
        P = self.Pk(k=k, dtype=dtype, gauge=gauge, format='array')
        if self.orthogonal:
            return lin.eigh_destroy(P, eigvals_only=eigvals_only, **kwargs)

        S = self.Sk(k=k, dtype=dtype, gauge=gauge, format='array')
        return lin.eigh_destroy(P, S, eigvals_only=eigvals_only, **kwargs)
コード例 #4
0
def degenerate_decouple(state, M):
    r""" Return `vec` decoupled via matrix `M`

    The decoupling algorithm is this recursive algorithm starting from :math:`i=0`:

    .. math::

       \mathbf p &= \mathbf V^\dagger \mathbf M_i \mathbf V
       \\
       \mathbf p \mathbf u &= \boldsymbol \lambda \mathbf u
       \\
       \mathbf V &= \mathbf u^T \mathbf V

    Parameters
    ----------
    state : numpy.ndarray or State
       states to be decoupled on matrices `M`
       The states must have C-ordering, i.e. ``[0, ...]`` is the first
       state.
    M : numpy.ndarray
       matrix to project to before disentangling the states
    """
    if isinstance(state, State):
        state.state = degenerate_decouple(state.state, M)
    else:
        # since M may be a sparse matrix, we cannot use __matmul__
        p = _conj(state) @ M.dot(state.T)
        state = eigh_destroy(p)[1].T @ state
    return state
コード例 #5
0
ファイル: test_eig.py プロジェクト: tfrederiksen/sisl
def test_eigh_d1():
    np.random.seed(1204982)
    a = np.random.rand(10, 10)
    # Symmetrize
    a = a + a.T
    xs, vs = sl.eigh(a)
    x, v = eigh_destroy(a)
    assert np.allclose(xs, x)
    assert np.allclose(vs, v)