コード例 #1
0
ファイル: ml.py プロジェクト: vINyLogY/minimisTN
    def _solve_ode(self, diff, y0, ode_inter, reformer, updater):
        OdeSolver = getattr(integrate, self.ode_method)
        in_real = self.ode_in_real
        t0 = self.time
        if t0 is None:
            t0 = 0.0
        t1 = t0 + ode_inter
        if in_real:
            y0 = np.array((y0.real, y0.imag), dtype='float64')
            complex_diff = diff

            def diff(t, x):
                xc = np.array(x[0] + 1.0j * x[1], dtype='complex128')
                yc = complex_diff(t, xc)
                y = np.array((yc.real, yc.imag), dtype='float64')
                return y

        ode_solver = OdeSolver(diff, t0, y0, t1, vectorized=False)
        cmf_steps = self.cmf_steps
        for n in count(1):
            if ode_solver.status != 'running':
                logging.debug(
                    __('* Propagation done.  Average CMF steps: {}',
                       n // cmf_steps))
                break
            if n % cmf_steps == 0:
                if n >= self.max_ode_steps:
                    msg = __('Reach ODE limit {}', n)
                    logging.warning(msg)
                    raise RuntimeWarning(msg)
                if reformer is not None:
                    reformer()
            ode_solver.step()
            updater(ode_solver.y)
        return
コード例 #2
0
ファイル: mctdh.py プロジェクト: vINyLogY/minimisTN
    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
コード例 #3
0
 def __init__(self, **kwargs):
     r"""
     Parameters
     ----------
     e_list : [float]
         n  :=  len(e_list) in the following context.
     omega_list : [float]
         m  :=  len(omega_list)
     kappa_list : [[float]]
         (2D) n * m array such that kappa_list[i][j] = 
         :math:`\kappa^{(i)}_j`.
     gamma_list : [[float]]
         (2D) n * m array such that kappa_list[i][j] = 
         :math:`\gamma^{(i)}_j`.
     lambda_list : [[[float]]]
         (3D) n * n * m array such that kappa_list[i][j][k] = 
         :math:`\lambda^{(ij)}_k`.
     """
     valid_attributes = self.ELEC + self.VIB
     for name, value in kwargs.items():
         if name in valid_attributes:
             setattr(self, name, value)
         else:
             logging.warning(__('Parameter {} unexpected, ignored.', name))
     return
コード例 #4
0
ファイル: propagate.py プロジェクト: vINyLogY/minimisTN
    def _split_prop(self, tensor, tau=0.01, imaginary=False, cache=False):

        def diff(t, y):
            """This function will not change the arrays in tensor network.
            """
            origin = tensor.array
            tensor.set_array(np.reshape(y, tensor.shape))
            ans = np.zeros_like(y)
            self.time = t if not imaginary else None
            for n in self.term_visitor(use_cache=True):
                ans += np.reshape(self._single_eom(tensor, n, cache=cache), -1)
            if self.init_energy is not None:
                ans -= self.init_energy * y
            ans /= self.coefficient()
            tensor.set_array(origin)
            return ans

        def reformer():
            self._form_env(update=True)
            return

        def updater(y):
            tensor.set_array(np.reshape(y, tensor.shape))
            tensor.normalize(forced=(not imaginary))

        if tensor.axis is None:
            self.root = tensor
        else:
            raise RuntimeError("Cannot propagate on Tensor {}" "which is not a root node!".format(tensor))
        logging.debug(__("* Propagating at {} ({}) for {}", tensor, tensor.shape, tau))
        y0 = np.reshape(tensor.array, -1)
        _re = None if self.f_list is None else reformer
        with self.log_inner_product(level=logging.DEBUG):
            self._solve_ode(diff, y0, tau, _re, updater)
        return tensor
コード例 #5
0
 def __init__(self, including_bath=False, relaxation_list=None, **kwargs):
     """ Needed parameters:
     - (for electronic part)
         'e1', 'e2', 'v',
     - (for inner part)
         'omega_list', 'lambda_list', 'dim_list',
     - (for outer part)
         'stop', 'n', 'dim', 'lambda_g', 'omega_g', 'lambda_d', 'omega_d'
     """
     # FIXME: including_bath=True case
     valid_attributes = self.ELEC + self.INNER + self.OUTER + self.FIELD
     for name, value in kwargs.items():
         if name in valid_attributes:
             setattr(self, name, value)
         else:
             logging.warning(__('Parameter {} unexpected, ignored.', name))
     self.elec_leaf = None
     self.inner_prefix = None
     self.outer_prefix = None
     self.leaves = []
     self.dimensions = {}
     self.including_bath = including_bath
     h_list = self.electron_hamiltonian()
     all_vibriations = (self.inner_hamiltonian() + self.outer_hamiltonian()
                        if including_bath else self.inner_hamiltonian())
     h_list.extend(all_vibriations)
     if relaxation_list is not None:
         h_list.extend(
             self.relaxation_hamiltonian(coupling_list=relaxation_list,
                                         prefix='I'))
     self.h_list, self.f_list = self.collect_electric_terms(h_list)
     return
コード例 #6
0
ファイル: numerical.py プロジェクト: vINyLogY/minimisTN
 def _restart(self):
     logging.debug('Search space too large, restart.')
     logging.debug(__('ritz vals: {}', self._ritz_vals))
     ritz_vals = self._ritz_vals
     self.__init__(
         matvec=self._matvec, init_vecs=self._get_ritz_vecs(),
         n_vals=self._n_vals
     )
     self._ritz_vals = ritz_vals
     return
コード例 #7
0
ファイル: propagate.py プロジェクト: vINyLogY/minimisTN
 def log_inner_product(self, level=logging.DEBUG):
     root = self.root
     if logging.root.isEnabledFor(level):
         shape_dict = {}
         init = root.vectorize(shape_dict=shape_dict)
     try:
         yield self
     except:
         pass
     else:
         if logging.root.isEnabledFor(level):
             root.tensorize(np.conj(init), use_aux=True, shape_dict=shape_dict)
             ip = root.global_inner_product()
             logging.log(level, __("<|>:{}", ip))
コード例 #8
0
ファイル: mctdh.py プロジェクト: vINyLogY/minimisTN
 def _normalizer(vec):
     ans = []
     for i in range(self.rank + 1):
         vec_i = self.get_sub_vec(i, vec)
         vec_i = np.reshape(vec_i, -1)
         if i == self.rank:
             std_norm = sqrt(1.0)
         else:
             std_norm = sqrt(self.shape_list[i][1])
         norm = (linalg.norm(vec_i) / std_norm)
         logging.debug(__('norm {}: {}', i, norm))
         ans.append(vec_i / norm)
     ans = np.concatenate(ans, axis=None)
     return ans
コード例 #9
0
 def unlink_to(self, i, fast=False):
     """
     Return
     ------
     child : Tensor
     j : int
     """
     try:
         if not fast:
             self.check_linkage(i)
     except KeyError:
         logging.info(__('No {0}-th linkage info of {1}', i, self))
     else:
         child, j = self._access[i]
         self.unlink(self, i, child, j)
     return child, j
コード例 #10
0
 def check_completness(self, strict=False):
     """
     Parameters
     ----------
     strict : bool
         Whether to check the compatibility of arrays.
     """
     if self.order is None:
         raise RuntimeError('No specific array at {0}'.format(self))
     elif set(self._access) != set(range(self.order)):
         raise RuntimeError('Incomplete linkages info at {0}'.format(self))
     else:
         for i in range(self.order):
             self.check_linkage(i, strict=strict)
         logging.info(__('Checked linkage completeness of {0}{1}', self, ' (strict)' if strict else ''))
         return
コード例 #11
0
ファイル: numerical.py プロジェクト: vINyLogY/minimisTN
    def config(cls, **kwargs):
        """Global configuration.

        Parameters
        ----------
        tol : float, optional
            Tolerance of energy.
        max_cycle : int, optional
        max_space : int, optional
        lin_dep_lim : float, optional
        """
        for key, value in kwargs.items():
            try:
                setattr(cls, key, value)
            except AttributeError:
                logging.warning(__('No configuration "{}"!', key))
        return
コード例 #12
0
    def link(a, i, b, j):
        r"""Add a linkage info between i-th order of a and j-th order of b.

        Parameters
        ----------
        a : Tensor
        i : int
        b : Tensor
        j : int
        """
        # Logging info
        for k, tensor in ((i, a), (j, b)):
            if k in tensor._access:
                logging.info(__('Overwrite the {0}-th linkage info of {1}', k, tensor))

        a._access[i] = (b, j)
        b._access[j] = (a, i)
        return
コード例 #13
0
 def check_linkage(self, i, strict=False):
     """
     Parameters
     ----------
     i : int
     strict : bool
         Whether to check the compatibility of arrays.
     """
     child, j = self._access[i]  # raise KeyError if no such linkage
     condition = (child._access[j] == (self, i))
     if strict:
         condition = condition and (
             (isinstance(self, Leaf) and self._array is None) or
             (isinstance(child, Leaf) and child._array is None) or
             (not (self._array is None or child._array is None) and self.shape[i] == child.shape[j]))
     if condition:
         logging.debug(__('Checked {0}-th linkage info of {1}{2}', i, self, ' (strict)' if strict else ''))
         return
     else:
         raise RuntimeError('Wrong {0}-th linkage info of {1}'.format(i, self))
コード例 #14
0
ファイル: mctdh.py プロジェクト: vINyLogY/minimisTN
 def term_hamiltonian(self, r, vec):
     """
     Parameters
     ----------
     r : int
     vec : (self.size,) ndarray
     """
     logging.debug(__('Hamiltonian term {}...', r))
     h_term = self.h_terms[r]
     mod_term = self.mod_terms[r]
     steps = len(self.shape_list)
     ans = []
     for i in range(steps):
         v_i = self.get_sub_vec(i, vec)
         if i < steps - 1:
             h_list = [h for j, h in h_term if j == i]
             v_i = self._sp_op(i, v_i, h_list, mod_term)
         else:
             v_i = self._coeff_op(v_i, mod_term)
         v_i = np.reshape(v_i, -1)
         ans.append(v_i)
     ans = np.concatenate(ans, axis=None)
     return ans
コード例 #15
0
ファイル: numerical.py プロジェクト: vINyLogY/minimisTN
    def _is_converged(self):
        if (
            self._last_ritz_vals is None or
            len(self._last_ritz_vals) != len(self._ritz_vals)
        ):
            self._convergence = [False] * len(self._ritz_vals)
            return False

        self._last_convergence = self._convergence
        diff_ritz_vals = np.abs(self._last_ritz_vals - self._ritz_vals)
        self._convergence = [
            norm_ ** 2 < self.tol and diff_ritz_vals[i] < self.tol
            for i, norm_ in enumerate(self._residual_norms)
        ]
        if self._debug:
            for _i, _norm in enumerate(self._residual_norms):
                if self._convergence[_i] and not self._last_convergence[_i]:
                    logging.debug(
                        __('Root {} converged, norm = {:.8f}', _i, _norm)
                    )
        if all(self._convergence):
            return True
        else:
            return False
コード例 #16
0
ファイル: dvr.py プロジェクト: vINyLogY/minimisTN
    def propagation(self,
                    init=None,
                    start=0.,
                    stop=5.,
                    max_inter=0.01,
                    const_energy=None,
                    updater=None,
                    normalizer=None):
        """A generator doing the propagation.

        Parameters
        ----------
        init : (N,) ndarray, optional
            Real initial vector at t = t_0.
        start : float, optional
            Time starting point t_0.
        stop : float, optional
            End point t_1.
        max_inter : float, optional
            Maximum of time gap.
        const_enengy : bool, optional
            Whether to keep energy as a constant
        updater : -> a, optional
            Action after computing one step.
        normalizer : (N,) ndarray -> (N,) ndarray

        Yields
        ------
        tuple : (float, ((N,) ndarray, (N,) ndarray))
            (time, (real_vector, imaginary_vector))
        """
        if init is None:
            init = self.init_state()
        h_op = self.h_mat()
        e0 = self.energy_expection(init)
        length = len(init)
        init = init.astype(complex)
        factor = 1.0 / self.hbar

        def propagator(t, y):
            real, imag = y.real, y.imag
            real, imag = factor * h_op(imag), -factor * h_op(real)
            y = real + 1.0j * imag
            return y

        solver = RK45(propagator, start, init, stop, max_step=max_inter)
        while True:
            # Normalization
            if normalizer is not None:
                solver.y = normalizer(solver.y)

            t = solver.t
            y = solver.y
            real, imag = y.real, y.imag
            e = self.energy_expection(y)
            logging.info(__("t: {:.3f}, E: {:.8f}, |v|^2: {:.8f}", t, e, scipy.linalg.norm(y)**2))
            if abs(e - e0) > 1.e-8:
                logging.warning('Energy is not conserved. ')
                if const_energy and abs(e - e0) > const_energy:
                    logging.warning(__('Propagation stopped at t = {:.3f}.', solver.t))
                    raise StopIteration
            yield t, (real, imag)
            try:
                solver.step()
            except RuntimeError:
                logging.debug('Iterator normal terminated.')
                raise StopIteration
            else:
                if updater is not None:
                    updater(solver)
コード例 #17
0
ファイル: mctdh.py プロジェクト: vINyLogY/minimisTN
 def _coeff_op(self, tensor, mod_term):
     logging.debug(__('> OP on A tensor...'))
     for i, mat in mod_term:
         tensor = MCTDH._partial_transform(i, tensor, mat)
     return tensor