Ejemplo n.º 1
0
    def __init__(self, n_dims, sys_hamiltonian, sys_op, corr):
        """
        Parameters
        ----------
        n_dims : np.ndarray
            a vector representing the possible n
        sys_hamiltionian : np.ndarray
            H_s
        sys_op :
            X_s in in H_sb X_s (x) X_b 
        corr : Correlation
            Correlation caused by X_b
        """
        self.n_dims = n_dims
        self.k_max = len(n_dims)
        assert isinstance(corr, Correlation)
        assert self.k_max == corr.k_max
        self._q = len(n_dims)
        self._p = len(n_dims) + 1

        self.corr = corr
        assert sys_op.ndim == 2
        assert sys_op.shape == sys_hamiltonian.shape
        self.n_states = sys_op.shape[0]
        self.op = np.transpose(sys_op)
        self.h = np.transpose(sys_hamiltonian)
        return
Ejemplo n.º 2
0
    def _diff_k(self, k):
        c_k = self.corr.symm_coeff[k] + 1.0j * self.corr.asymm_coeff[k]
        numberer = self._numberer(k)
        raiser = self._raiser(k)
        lower = self._lower(k)

        return [
            [(self._i, -1.0j / self.hbar * np.transpose(self.op)), (k, lower)],
            [(self._j, 1.0j / self.hbar * self.op), (k, lower)],
            [(self._i, -1.0j / self.hbar * c_k * np.transpose(self.op)),
             (k, raiser @ numberer)],
            [(self._j, 1.0j / self.hbar * np.conj(c_k) * self.op),
             (k, raiser @ numberer)],
        ]
Ejemplo n.º 3
0
 def _orthonormalize(self, use_svd=True):
     if use_svd and self._trial_vecs:
         trial_mat = np.transpose(np.array(self._trial_vecs))
         trial_mat = orth(trial_mat)
         self._trial_vecs = list(np.transpose(trial_mat))
     elif self._trial_vecs:
         vecs = []
         for vec_i in self._trial_vecs:
             for vec_j in vecs:
                 vec_i -= vec_j * np.dot(vec_j.conj(), vec_i)
             norm_ = norm(vec_i)
             if norm_ > 1.e-7:
                 vecs.append(vec_i / norm_)
         self._trial_vecs = vecs
     return self._trial_vecs
Ejemplo n.º 4
0
    def _move_left(mat, mat_prev, _trunc):
        shape = np.shape(mat)
        mat = np.reshape(
            np.transpose(mat, (1, 0, 2)),  # mat[i, s, j]
            (shape[1], shape[0] * shape[2]))  # SVD on mat[i, sj]
        U, S, V = np.linalg.svd(mat, full_matrices=0)

        # truncated to compress.
        U, S, V, compress_error = compress_svd(U, S, V, _trunc)
        mat = np.reshape(V, (-1, shape[0], shape[2]))  # V[m, sj]
        mat = np.transpose(mat, (1, 0, 2))  # mat[s, m, j]
        US = np.matmul(U, np.diag(S))
        mat_prev = np.einsum('rhi,im->rhm', mat_prev, US)

        return mat, mat_prev
Ejemplo n.º 5
0
    def solve(self, n_state=1, davidson=False):
        r"""Solve the TISE with the potential energy given.

        Parameters
        ----------
        n_state : int, optional
            Number of states to be calculated, sorted by energy from low to
            high.
        davidson : bool, optional
            Whether use Davidson method.

        Returns
        -------
        energy : [float]
        eigenstates : np.ndarray
        """
        h_op = self.h_mat()
        v = self.init_state()
        if davidson:
            solver = DavidsonAlgorithm(h_op.dot, [v], n_vals=n_state)
            self.energy, self.eigenstates = solver.kernel()
        else:
            self.energy, v = eigsh(h_op, k=n_state, which='SA', v0=v)
            self.eigenstates = np.transpose(v)
        return self.energy, self.eigenstates
Ejemplo n.º 6
0
    def propagator(self, tau=0.1, method='Trotter'):
        r"""Construct the propagator

        Parameters
        ----------
        tau : float
            Time interval at each step.

        Returns
        -------
        p1 : (n, n) ndarray
            :math:`e^{-iV\tau/2}`
        p2 : (n, n) ndarray
            :math:`e^{-iV\tau}`
        p3 : (n, n) ndarray
            :math:`e^{-iT\tau}`
        """
        hbar = self.hbar
        if 'Trotter' in method:
            diag, v = scipy.linalg.eigh(self.t_mat())
            p3 = np.exp(-1.0j * hbar * tau * diag)
            p3 = np.dot(v, np.dot(np.diag(p3), np.transpose(v)))
            p2 = np.exp(-1.0j * hbar * tau * np.diag(self.v_mat()))
            p2 = np.diag(p2)
            p1 = np.exp(-1.0j * hbar * tau * np.diag(0.5 * self.v_mat()))
            p1 = np.diag(p1)
            return p1, p2, p3
Ejemplo n.º 7
0
    def init_state(self):
        r"""Form the initial vector according to shape list::

            n_0|   |   |n_p-1
              C_0 ... C_p-1
                 \ | /
              m_0 \|/ m_p-1
                   A

        Returns
        -------
        init : (self.size,) ndarray
            Formally, init = np.concatenate([C_0, ..., C_p-1, A], axis=None),
            where C_i is a (n_i * m_i,) ndarray, i <- {0, ..., p-1},
            A is a (M,) ndarray, and M = m_0 * ... * m_p-1, m_i < n_i.
        """
        dvr_list = self.dvr_list
        c_list = []
        for i, (_, m_i) in enumerate(self.shape_list[:-1]):
            _, v_i = dvr_list[i].solve(n_state=m_i)
            v_i = np.transpose(v_i)
            c_list.append(np.reshape(v_i, -1))
        vec_a = np.zeros(self.size_list[-1])
        vec_a[0] = 1.0
        vec_list = c_list + [vec_a]
        init = np.concatenate(vec_list, axis=None)
        self.vec = init
        self.update_mod_terms()
        return init
Ejemplo n.º 8
0
    def _sp_op(self, i, mat, h_list, mod_term, err=1.e-6):
        if not h_list:
            return np.zeros((mat.shape))

        logging.debug(__('> OP on mat {}...', i))

        n, m = mat.shape
        partial_transform = self._partial_transform
        a = self.get_sub_vec(-1)
        a_h = np.conj(a)
        density = self._partial_product(i, a, a_h)
        inv_density = linalg.inv(density + np.identity(m) * err)
        sp = self.get_sub_vec(i)
        sp_h = np.conj(np.transpose(sp))
        projection = np.identity(n) - np.dot(sp, sp_h)

        tmp = partial_transform(i, a, mat)
        for mat_j in h_list:
            tmp = partial_transform(i, tmp, mat_j)
        for j, mat_j in mod_term:
            if j != i:
                tmp = partial_transform(j, tmp, mat_j)
        tmp = self._partial_product(i, tmp, a_h)
        ans = np.dot(projection, np.dot(tmp, inv_density))

        return ans
Ejemplo n.º 9
0
    def solve(self, n_state=None):
        r"""Solve the TISE with the potential energy given.

        Parameters
        ----------
        n_state : int, optional
            Number of states to be calculated, sorted by energy from low to
            high.

        Returns
        -------
        energy : [float]
        eigenstates : np.ndarray

        See Also
        ________
        DVR : Definition of all attributes.
        """
        if n_state is None:
            n_state = self.n - 1
        self._h_mat = self.h_mat()
        self.energy, v = eigsh(self._h_mat, k=n_state, which='SA')
        # self.energy, v = scipy.linalg.eigh(
        #     self._h_mat, eigvals=(0, n_state - 1))
        tmp = np.transpose(v)
        es = []
        for i in tmp:
            vi = i if i[0] >= 0.0 else -i
            es.append(vi)
        self.eigenstates = np.array(es)
        return self.energy, self.eigenstates
Ejemplo n.º 10
0
def fine_grain_mps(C, dims, direction, _trunc=False):
    """Fine-graining of one-site MPS into three site by SVD.::

            |st         |s    |t
        -i- C -k- = -i- A -m- B -k-

    Parameters
    ----------
    C : (st, i, k) ndarray
        A MPS matrix.
    dims : (int, int)
        [s, t].
    direction : {'>', '<'}
        '>': move to right; '<'  move to left
    _trunc : int, optional
        Set m in compress_svd to _trunc. Not compressed if not _trunc.

    Returns
    -------
    A : (s, i, m) ndarray
        A MPS matrix.
    B : (t, m, k) ndarray
        A MPS matrix.

    Notes
    -----
    If direction == '>', A is (left-)canonical;
    if direction == '<', B is (right-)canonical.
    """
    sh = dims + [C.shape[1], C.shape[2]]  # [s, t, i, k]
    mat = np.reshape(C, sh)
    mat = np.transpose(mat, (0, 2, 1, 3))  # mat[s, i, t, k]
    mat = np.reshape(mat, (sh[0] * sh[2], sh[1] * sh[3]))  # mat[si, tk]
    U, S, V = np.linalg.svd(mat, full_matrices=0)
    if _trunc:
        U, S, V, compress_error = compress_svd(U, S, V, _trunc)
    if direction == '>':
        A = U
        B = np.matmul(np.diag(S), V)  # [m, tk]
    elif direction == '<':
        A = np.matmul(U, np.diag(S))
        B = V
    A = np.reshape(A, (sh[0], sh[2], -1))  # [s, i, m]
    B = np.reshape(B, (-1, sh[1], sh[3]))  # [m, t, k]
    B = np.transpose(B, (1, 0, 2))  # [t, m, k]

    return A, B
Ejemplo n.º 11
0
def get_ext_wfns(n_states, wfns, op, search_method='krylov'):
    wfns = np.array(wfns)
    n_states = np.shape(wfns)[1]
    space = np.transpose(np.array(wfns))
    vecs = np.transpose(np.array(wfns))
    assert np.shape(space)[1] <= n_states
    if search_method == 'krylov':
        while True:
            space = linalg.orth(vecs)
            if np.shape(space)[0] >= n_states:
                break
            vecs = list(op @ vecs)
            np.concatenate((space, vecs), axis=1)
        psi = space[:, :n_states]
        return np.transpose(psi)
    else:
        raise NotImplementedError
Ejemplo n.º 12
0
 def _diff_ij(self):
     # delta = self.corr.delta_coeff
     return [
         [(self._i, -1.0j * np.transpose(self.h))],
         [(self._j, 1.0j * self.h)],
         # [(self._i, -delta * np.transpose(self.op @ self.op))],
         # [(self._i, np.sqrt(2.0) * delta * np.transpose(self.op)),
         #  (self._j, np.sqrt(2.0) * delta * self.op)],
         # [(self._j, -delta * (self.op @ self.op))],
     ]
Ejemplo n.º 13
0
    def dvr2fbr_mat(self, mat):
        r"""Transform a matrix from DVR to FBR.

        Parameters
        ----------
        mat : (n, n) ndarray

        Returns
        -------
        (n, n) ndarray
        """
        return np.dot(self._u_mat, np.dot(mat, np.transpose(self._u_mat)))
Ejemplo n.º 14
0
    def fbr2dvr_mat(self, mat):
        r"""Transform a matrix from FBR to DVR.

        Parameters
        ----------
        mat : (n, n) ndarray

        Returns
        -------
        (n, n) ndarray
        """
        return np.dot(np.transpose(self._u_mat), np.dot(mat, self._u_mat))
Ejemplo n.º 15
0
    def fbr2dvr_vec(self, vec):
        r"""Transform a vector from FBR to DVR.

        Parameters
        ----------
        mat : (n,) ndarray

        Returns
        -------
        (n,) ndarray
        """
        vec = np.reshape(vec, -1)
        return np.dot(np.transpose(self._u_mat), vec)
Ejemplo n.º 16
0
    def _calc_ritz_pairs(self):
        def _trans_vec(vec, basis):
            new_vec = sum(map(lambda x, y: x * y, vec, basis))
            return new_vec

        n_space = len(self._search_space)
        n_state = min(n_space, self._n_vals)
        self._ritz_vals, v = eigh(
            self._submatrix[:n_space, :n_space], eigvals=(0, n_state - 1)
        )
        v = np.transpose(v)
        self._get_ritz_vecs = (
            lambda: (_trans_vec(v_i, self._search_space) for v_i in v)
        )
        self._get_col_ritz_vecs = (
            lambda: (_trans_vec(v_i, self._column_space) for v_i in v)
        )
        return self._ritz_vals, self._get_ritz_vecs
Ejemplo n.º 17
0
    def projector(self, comp=False):
        """[Deprecated] Return the projector corresponding to self.

        Returns
        -------
        ans : ndarray
        """
        axis = self.axis
        if axis is not None:
            array = self.array
            shape = self.shape
            dim = shape.pop(self.axis)
            comp_dim = np.prod(shape)
            array = np.moveaxis(array, axis, -1)
            array = np.reshape(array, (-1, dim))
            array_h = np.conj(np.transpose(array))
            ans = np.dot(array, array_h)
            if comp:
                identity = np.identity(comp_dim)
                ans = identity - ans
            ans = np.reshape(ans, shape * 2)
            return ans
        else:
            raise RuntimeError('Need to specific the normalization axis!')
Ejemplo n.º 18
0
 def _diff_ij(self):
     # delta = self.corr.delta_coeff
     return [
         [(self._i, -1.0j * np.transpose(self.h))],
         [(self._j, 1.0j * self.h)],
     ]
Ejemplo n.º 19
0
 def _eval(op, vec):
     vec_h = np.conj(np.transpose(vec))
     mod_op = np.dot(vec_h, np.dot(op, vec))
     return mod_op