Exemple #1
0
 def _calculate_dvr(self):
     # calculate grid points
     step_length = self.length / (self.n + 1)
     self.grid_points = np.array([self.a + step_length * i for i in range(1, self.n + 1)])
     # calculate U matrix
     j = np.arange(1, self.n + 1)[:, None]
     a = np.arange(1, self.n + 1)[None, :]
     self._u_mat = (np.sqrt(2 / (self.n + 1)) * np.sin(j * a * np.pi / (self.n + 1)))
     return self.grid_points, self._u_mat
Exemple #2
0
    def plot_dvr(self, x_min, x_max, npts=None, indices=None):
        r"""Plot DVR basis.

        Parameters
        ----------
        x_min : float
        x_max : float
        npts : int, optional
            Number of points to calculate on a single state.
        indices : (int), optional
            An iterable object containing the indices of DVR to be plotted.
        """
        if npts is None:
            npts = self.n
        if indices is None:
            indices = np.arange(self.n)
        x = np.linspace(x_min, x_max, npts)
        y_min = 0.
        y_max = 0.
        with figure() as fig:
            plt.subplots_adjust(left=0.1, right=0.9, bottom=0.1, top=0.9)
            for i in indices:
                x_i = self.grid_points[i]
                plt.plot([x_i, x_i], [-10., 10.], '--', color='gray')
                chi = (self.dvr_func(i))(x)
                if (self.dvr_func(i))(x_i) < 0.:
                    chi = -1. * chi
                y_max = max(y_max, max(chi))
                y_min = min(y_min, min(chi))
                plt.plot(x, chi)
            plt.plot([x_min, x_max], [0., 0.], 'k-')
            plt.xlim(x_min, x_max)
            plt.ylim(y_min * 1.05, y_max * 1.05)
            plt.savefig('dvr_functions-{}.pdf'.format(self.comment))
        return
Exemple #3
0
    def spectrum(self, init=None, length=5., max_inter=0.01, window=None, **kwargs):
        """Power spectrum.

        Parameters
        ----------
        init : (N,) ndarray, optional
        cut : float
        max_inter : float
        window : float -> float
            Window function with length.

        Returns
        -------
        freq : [float]
        sigma : [complex]
        """
        t, auto = zip(*self.autocorrelation(init=init, stop=length, max_inter=max_inter, **kwargs))
        n = len(t)
        tau = (t[-1] - t[0]) / (n - 1)
        uniform = all(abs(t_i - i * tau) < 1.e-8 for i, t_i in enumerate(t))

        if window is not None:
            zipped = zip(t, auto)
            auto = [a_i * window(t) for t, a_i in zipped]

        if uniform:
            omega = 2 * np.pi / n / tau
            freq = np.arange(n) * omega
            sigma = fftpack.ifft(auto)
            return freq, sigma
        else:
            raise NotImplementedError("Need NUDFT, or use smaller max_inter.")
Exemple #4
0
    def number_operator(self):
        if self.dense:
            ans = np.diag(np.arange(self.dim))
        else:

            def matvec(x):
                return self.raising(self.lowering(x))

            ans = self.operator(matvec=matvec)
        return ans
Exemple #5
0
    def hamiltonian(self):
        coeff = self.hbar * self.omega
        if self.dense:
            ans = np.diag(coeff * (0.5 + np.arange(self.dim)))
        else:

            def matvec(x):
                return coeff * (self.raising(self.lowering(x)) + 0.5 * x)

            ans = self.operator(matvec=matvec)
        return ans
Exemple #6
0
    def t_mat(self):
        """Return the kinetic energy matrix in DVR.

        Returns
        -------
        (n, n) np.ndarray
            A 2-d matrix.
        """
        factor = -self.hbar**2 / (2 * self.m_e)
        j = np.arange(1, self.n + 1)
        t_matrix = np.diag(-(j * np.pi / self.length)**2)
        t_matrix = factor * self.fbr2dvr_mat(t_matrix)
        return t_matrix
Exemple #7
0
    def h_mat(self):
        """Return the Hamiltonian energy matrix in DVR.

        Returns
        -------
        Hamitonian : LinearOperator
            A 2-d matrix.
        """

        class _Hamiltonian(LinearOperator):
            """
            Parameters
            ----------
            v_diag : (n,) ndarray
                In DVR
            t_diag : (n,) ndarray
                In FBR
            """

            def __init__(self, v_diag, t_diag):
                n = len(v_diag)
                self.v = v_diag
                self.t = t_diag / (2. * (n + 1.))
                super(_Hamiltonian, self).__init__('d', (n, n))

            def _matvec(self, vec):
                vec1 = self.v * vec
                vec2 = fftpack.dst(self.t * fftpack.dst(vec, type=1), type=1)
                return vec1 + vec2

            def _rmatvec(self, vec):
                return self._matvec(vec)

        if self._h_mat is not None:
            return self._h_mat
        v = self.v_func(self.grid_points)
        j = np.arange(1, self.n + 1)
        t = (self.hbar * j * np.pi / self.length)**2 / (2 * self.m_e)
        return _Hamiltonian(v, t)
Exemple #8
0
 def annihilation_operator(self):
     if self.dense:
         ans = np.diag(np.sqrt(np.arange(1, self.dim)), 1)
     else:
         ans = self.operator(matvec=self.lowering, rmatvec=self.raising)
     return ans
Exemple #9
0
 def numberer(self, k):
     """Acting on 0-th index"""
     return np.diag(np.arange(self.n_dims[k]))
Exemple #10
0
 def annihilator(self, k):
     """Acting on 0-th index"""
     dim = self.n_dims[k]
     lower = np.eye(dim, k=-1)
     sqrt_n = np.diag(np.sqrt(np.arange(dim)))
     return sqrt_n @ lower
Exemple #11
0
 def creator(self, k):
     """Acting on 0-th index"""
     dim = self.n_dims[k]
     raiser = np.eye(dim, k=1)
     sqrt_n = np.diag(np.sqrt(np.arange(dim)))
     return raiser @ sqrt_n
Exemple #12
0
 def _numberer(self, k):
     return np.diag(np.arange(self.n_dims[k], dtype=DTYPE))
Exemple #13
0
 def _lower(self, k):
     """Acting on 0-th index"""
     dim = self.n_dims[k]
     sqrt_n = np.diag(np.sqrt(np.arange(dim, dtype=DTYPE)))
     return sqrt_n @ np.eye(dim, k=-1, dtype=DTYPE)
Exemple #14
0
 def _sqrt_numberer(self, k, start=0):
     return np.diag(
         np.sqrt(np.arange(start, start + self.n_dims[k], dtype=DTYPE)))
Exemple #15
0
 def _numberer(self, k, start=0):
     return np.diag(np.arange(start, start + self.n_dims[k]))