예제 #1
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')
        nocc = self.mos.nocc
        nvir = self.mos.nvir

        t1 = ham.f.ov.transpose().conj() * (- e_ai)
        v_vovo = einsum("pia,pjb->aibj", ham.l.pov, ham.l.pov).conj()

        t2_full = v_vovo.transpose([0, 2, 1, 3]) * (- e_abij)
        t2names = ['x1', 'x2', 'x3', 'x4']
        t3names = ['x1', 'x2', 'x3', 'x4', 'x5', 'x6']

        t2x = cpd_initialize(t2_full.shape, self.rankt.t2)
        t2x = als_dense(t2x, t2_full, max_cycle=100,
                        tensor_format='cpd')

        t3x = cpd_initialize((nvir,) * 3 + (nocc,) * 3,
                             self.rankt.t3, init_function=np.zeros)

        return Tensors(t1=t1, t2=Tensors(zip(t2names, t2x)),
                       t3=Tensors(zip(t3names, t3x)))
예제 #2
0
파일: rccsdt_ri.py 프로젝트: qbit-/tcc
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """

        # Symmetrize T3 RHS
        g3 = ((+g.t3 + g.t3.transpose([1, 2, 0, 4, 5, 3]) + g.t3.transpose(
            [2, 0, 1, 5, 3, 4]) + g.t3.transpose([0, 2, 1, 3, 5, 4]) +
               g.t3.transpose([2, 1, 0, 5, 4, 3]) +
               g.t3.transpose([1, 0, 2, 4, 3, 5])) / 12)

        # Symmetrize T2 RHS
        g2 = 1 / 2 * (g.t2 + g.t2.transpose([1, 0, 3, 2]))

        # Solve
        t2 = g2 * (-cc_denom(h.f, g.t2.ndim, 'dir', 'full'))
        t3 = g3 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full'))

        # Symmetrize amplitudes
        t2 = 1 / 2 * (t2 + t2.transpose([1, 0, 3, 2]))
        t3 = ((+t3 + t3.transpose([1, 2, 0, 4, 5, 3]) + t3.transpose(
            [2, 0, 1, 5, 3, 4]) + t3.transpose([0, 2, 1, 3, 5, 4]) +
               t3.transpose([2, 1, 0, 5, 4, 3]) +
               t3.transpose([1, 0, 2, 4, 3, 5])) / 6)

        return Tensors(t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
                       t2=t2,
                       t3=t3)
예제 #3
0
파일: rccsdt_ri.py 프로젝트: qbit-/tcc
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """

        # Apply n_body symmetry, which builds all
        # other spin parts of the unitary group residual
        g3s = (+g.t3 - g.t3.transpose([0, 1, 2, 3, 5, 4]) +
               g.t3.transpose([0, 1, 2, 4, 5, 3]))
        g3 = ((+g.t3 + g.t3.transpose([1, 2, 0, 4, 5, 3]) + g.t3.transpose(
            [2, 0, 1, 5, 3, 4]) + g.t3.transpose([0, 2, 1, 3, 5, 4]) +
               g.t3.transpose([2, 1, 0, 5, 4, 3]) +
               g.t3.transpose([1, 0, 2, 4, 3, 5]) + 2 * g3s) / 12)

        g2 = 1 / 2 * (g.t2 + g.t2.transpose([1, 0, 3, 2]))

        t2 = g2 * (-cc_denom(h.f, g.t2.ndim, 'dir', 'full'))
        t3 = g3 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full'))

        # Symmetrize
        t2 = 1 / 2 * (t2 + t2.transpose([1, 0, 3, 2]))
        t3 = ((+t3 + t3.transpose([1, 2, 0, 4, 5, 3]) + t3.transpose(
            [2, 0, 1, 5, 3, 4]) + t3.transpose([0, 2, 1, 3, 5, 4]) +
               t3.transpose([2, 1, 0, 5, 4, 3]) +
               t3.transpose([1, 0, 2, 4, 3, 5])) / 6)

        return Tensors(t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
                       t2=t2,
                       t3=t3)
예제 #4
0
    def calculate_update(self, h, a):
        """
        Calculate new amplitudes
        """

        names_abij = ['x1', 'x2', 'x3', 'x4']
        xs = [a.t2[key] for key in names_abij]

        # symmetrize t2 before feeding into res
        xs_sym = cpd_symmetrize(xs, {(1, 0, 3, 2): ('ident', )})

        r = self.calc_residuals(
            h, Tensors(t1=a.t1, t2=Tensors(zip(names_abij, xs_sym))))

        # Solve T1
        t1 = a.t1 - r.t1 * (cc_denom(h.f, 2, 'dir', 'full'))

        # Symmetrize T2 residuals
        r2 = 1 / 2 * (r.t2 + r.t2.transpose([1, 0, 3, 2]))

        # Solve T2
        r2_d = -r2 * cc_denom(h.f, 4, 'dir', 'full')

        t2 = [f for f in xs]
        for idx in range(len(t2)):
            g = (als_contract_dense(t2, r2_d, idx, tensor_format='cpd') +
                 als_contract_cpd(t2, xs_sym, idx, tensor_format='cpd'))
            s = als_pseudo_inverse(t2, t2, idx)
            f = np.dot(g, s)
            t2[idx] = f

        return Tensors(t1=t1, t2=Tensors(zip(names_abij, t2)))
예제 #5
0
    def calculate_update(self, h, a):
        """
        Calculate new amplitudes
        """
        names_abij = sorted(a.t2.keys())
        xs = [elem for elem in a.t2.to_generator()]

        # symmetrize t2 before feeding into res
        xs_sym = cpd_symmetrize(xs, {(1, 0, 3, 2): ('ident', )})
        a_sym = Tensors(t1=a.t1, t2=Tensors(zip(names_abij, xs_sym)))

        # Calculate residuals
        r1 = _rccsd_cpd_ls_t_true_calc_r1(h, a_sym)

        # Solve T1
        t1 = a.t1 - r1 * (cc_denom(h.f, 2, 'dir', 'full'))

        namesd_abij = ['d1', 'd2', 'd3', 'd4']
        d = Tensors(
            t2=Tensors(zip(namesd_abij, cc_denom(h.f, 4, 'dir', 'cpd'))))

        new_a = Tensors(t1=t1, t2=Tensors(zip(names_abij, xs)))

        for idx, name in enumerate(sorted(a_sym.t2.keys())):
            g = (-self._calculate_r2d_projection(name, h, a_sym, new_a, d) +
                 als_contract_cpd(new_a.t2.to_list(),
                                  a_sym.t2.to_list(),
                                  idx,
                                  tensor_format='cpd'))
            s = als_pseudo_inverse(new_a.t2.to_list(), new_a.t2.to_list(), idx)
            f = np.dot(g, s)
            new_a.t2[name] = f

        return new_a
예제 #6
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """
        # Solve T2 (see RCCSD_UNIT)
        t2 = ((2 * g.t2 + g.t2.transpose([0, 1, 3, 2])) / (-6) *
              cc_denom(h.f, 4, 'dir', 'full'))

        # Symmetrize
        t2 = (+t2 + t2.transpose([1, 0, 3, 2])) / 2

        # Solve T3
        t3 = (g.t3 / 12 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full')))

        # Symmetrize
        t3 = ((+t3 + t3.transpose([1, 2, 0, 4, 5, 3]) + t3.transpose(
            [2, 0, 1, 5, 3, 4]) + t3.transpose([0, 2, 1, 3, 5, 4]) +
               t3.transpose([2, 1, 0, 5, 4, 3]) +
               t3.transpose([1, 0, 2, 4, 3, 5])) / 6)

        return Tensors(t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
                       t2=t2,
                       t3=t3)
예제 #7
0
 def update_rhs(self, h, a, r):
     """
     Updates right hand side of the CC equations, commonly referred as G
     """
     return Tensors(t1=r.t1 - a.t1 / cc_denom(h.f, 2, 'dir', 'full'),
                    t2=r.t2 - cpd_rebuild(
                        (a.t2.x1, a.t2.x2, a.t2.x3, a.t2.x4)) /
                    cc_denom(h.f, 4, 'dir', 'full'))
예제 #8
0
 def update_rhs(self, h, a, r):
     """
     Calculates right hand side of CC equations
     """
     return Tensors(t1=r.t1 - a.t1 / cc_denom(h.f, 2, 'dir', 'full'),
                    t2=r.t2 - a.t2 / cc_denom(h.f, 4, 'dir', 'full'),
                    t3=r.t3 - (a.t3 - a.t3.transpose([0, 1, 2, 4, 3, 5])) /
                    cc_denom(h.f, 6, 'dir', 'full'))
예제 #9
0
    def update_rhs(self, h, a, r):
        """
        Calculates RHS of the fixed point iteration of CC equations
        """

        return Tensors(t1=r.t1 - 2 * a.t1 / cc_denom(h.f, 2, 'dir', 'full'),
                       t2=r.t2 - 2 *
                       (2 * a.t2 - a.t2.transpose([0, 1, 3, 2])) /
                       cc_denom(h.f, 4, 'dir', 'full'))
예제 #10
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')

        t1 = ham.f.ov.transpose().conj() * (-e_ai)
        t2 = ham.v.oovv.transpose([2, 3, 0, 1]).conj() * (-e_abij)

        return Tensors(t1=t1, t2=t2)
예제 #11
0
 def update_rhs(self, h, a, r):
     """
     Calculates right hand side of CC equations
     """
     return Tensors(
         t1=r.t1 - a.t1 / cc_denom(h.f, 2, 'dir', 'full'),
         t2=r.t2 - a.t2 / cc_denom(h.f, 4, 'dir', 'full'),
         t3=r.t3 - (ncpd_rebuild(
             (a.t3.xlam, a.t3.x1, a.t3.x2, a.t3.x3, a.t3.x4, a.t3.x5,
              a.t3.x6)) - ncpd_rebuild(
                  (a.t3.xlam, a.t3.x1, a.t3.x2, a.t3.x3, a.t3.x5, a.t3.x4,
                   a.t3.x6))) / cc_denom(h.f, 6, 'dir', 'full'))
예제 #12
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """

        # Symmetrize T3 RHS - see RCCSDT code
        g3 = (+g.t3 + g.t3.transpose([1, 2, 0, 4, 5, 3]) + g.t3.transpose(
            [2, 0, 1, 5, 3, 4]) + g.t3.transpose([0, 2, 1, 3, 5, 4]) +
              g.t3.transpose([2, 1, 0, 5, 4, 3]) +
              g.t3.transpose([1, 0, 2, 4, 3, 5])) / 6

        # Solve T3
        t3 = g3 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full'))

        # Symmetrize
        t3 = (+t3 + t3.transpose([1, 2, 0, 4, 5, 3]) + t3.transpose(
            [2, 0, 1, 5, 3, 4]) + t3.transpose([0, 2, 1, 3, 5, 4]) +
              t3.transpose([2, 1, 0, 5, 4, 3]) +
              t3.transpose([1, 0, 2, 4, 3, 5])) / 6

        # Symmetrize T2 RHS
        g2 = 1 / 2 * (g.t2 + g.t2.transpose([1, 0, 3, 2]))

        # Solve T2
        t2 = g2 * (-cc_denom(h.f, g.t2.ndim, 'dir', 'full'))

        # Symmetrize
        t2 = 1 / 2 * (t2 + t2.transpose([1, 0, 3, 2]))

        # Solve for factors
        t2x = als_dense([a.t2.xlam, a.t2.x1, a.t2.x2, a.t2.x3, a.t2.x4],
                        t2,
                        max_cycle=1,
                        tensor_format='ncpd')
        t3x = als_dense(
            [a.t3.xlam, a.t3.x1, a.t3.x2, a.t3.x3, a.t3.x4, a.t3.x5, a.t3.x6],
            t3,
            max_cycle=1,
            tensor_format='ncpd')
        return Tensors(
            t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
            t2=Tensors(xlam=t2x[0], x1=t2x[1], x2=t2x[2], x3=t2x[3],
                       x4=t2x[4]),
            t3=Tensors(xlam=t3x[0],
                       x1=t3x[1],
                       x2=t3x[2],
                       x3=t3x[3],
                       x4=t3x[4],
                       x5=t3x[5],
                       x6=t3x[6]),
        )
예제 #13
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')

        t1 = ham.f.ov.transpose().conj() * (-e_ai)

        v_vvoo = np.einsum("pia,pjb->abij", ham.l.pov, ham.l.pov).conj()
        t2 = v_vvoo * (-e_abij)

        return Tensors(t1=t1, t2=t2)
예제 #14
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """
        # Solve
        t2 = ((2 * g.t2 + g.t2.transpose([0, 1, 3, 2])) / (-6) *
              cc_denom(h.f, 4, 'dir', 'full'))
        # Symmetrize
        t2 = 1 / 2 * (t2 + t2.transpose([1, 0, 3, 2]))

        return Tensors(t1=g.t1 / (-2) * cc_denom(h.f, 2, 'dir', 'full'), t2=t2)
예제 #15
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')
        nocc = self.mos.nocc
        nvir = self.mos.nvir

        t1 = ham.f.ov.transpose().conj() * (-e_ai)
        t2 = ham.v.oovv.transpose([2, 3, 0, 1]).conj() * (-e_abij)
        t3 = np.zeros((nvir, ) * 3 + (nocc, ) * 3)

        return Tensors(t1=t1, t2=t2, t3=t3)
예제 #16
0
 def update_rhs(self, h, a, r):
     """
     Calculates right hand side of CC equations
     """
     return Tensors(
         t1=r.t1 - a.t1 / cc_denom(h.f, 2, 'dir', 'full'),
         t2=r.t2 - 2 * (2 * a.t2 - a.t2.transpose([0, 1, 3, 2])) /
         cc_denom(h.f, 4, 'dir', 'full'),
         t3=r.t3 -
         (+4 * a.t3.transpose([0, 1, 2, 4, 3, 5]) + 4 * a.t3.transpose(
             [0, 1, 2, 5, 4, 3]) + 4 * a.t3.transpose([0, 1, 2, 3, 5, 4]) -
          2 * a.t3.transpose([0, 1, 2, 5, 3, 4]) -
          2 * a.t3.transpose([0, 1, 2, 4, 5, 3]) - 8 * a.t3) /
         cc_denom(h.f, 6, 'dir', 'full'))
예제 #17
0
파일: rccsd_thc.py 프로젝트: qbit-/tcc
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """

        t1 = g.gt1 / (-cc_denom(h.f, 2, 'mul', 'full'))

        A1 = gen_A1(a.x1, a.x2, a.x3, a.x4, a.x5)
        A2 = gen_A2(a.x1, a.x2, a.x3, a.x4, a.x5)
        A3 = gen_A3(a.x1, a.x2, a.x3, a.x4, a.x5)
        A4 = gen_A4(a.x1, a.x2, a.x3, a.x4, a.x5)
        AZl = gen_AZl(a.x1, a.x2, a.x3, a.x4, a.x5)
        AZr = gen_AZr(a.x1, a.x2, a.x3, a.x4, a.x5)

        a_new = [
            -dot(g.gx1, pinv(A1, rcond=1e-10)) + a.x1,
            -dot(g.gx2, pinv(A2, rcond=1e-10)) + a.x2,
            -dot(g.gx3, pinv(A3, rcond=1e-10)) + a.x3,
            -dot(g.gx4, pinv(A4, rcond=1e-10)) + a.x4,
            -dot(dot(pinv(AZl, rcond=1e-10), g.gx5), pinv(AZr, rcond=1e-10)) +
            a.x5
        ]
        # Normalize columns to 1 in X factors, Hermitize Z
        a_new = [factor / norm(factor, axis=0) for factor in a_new[:4]] + [
            1 / 2 * (a_new[4] + a_new[4].T),
        ]

        return self.types.AMPLITUDES_TYPE(t1, *a_new)
예제 #18
0
파일: rccsdt_ri.py 프로젝트: qbit-/tcc
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')
        nocc = self.mos.nocc
        nvir = self.mos.nvir

        t1 = ham.f.ov.transpose().conj() * (-e_ai)
        v_vovo = einsum("pia,pjb->aibj", ham.l.pov, ham.l.pov).conj()

        t2 = v_vovo.transpose([0, 2, 1, 3]) * (-e_abij)
        t3 = np.zeros((nvir, ) * 3 + (nocc, ) * 3)

        return Tensors(t1=t1, t2=t2, t3=t3)
예제 #19
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """

        # Form symmetric RHS for T2
        g2 = 1 / 2 * (g.t2 + g.t2.transpose([1, 0, 3, 2]))

        # Solve T2
        t2 = g2 * (-cc_denom(h.f, g.t2.ndim, 'dir', 'full'))

        # Symmetrize
        t2 = (t2 + t2.transpose([1, 0, 3, 2])) / 2

        # This version coincides with So
        # Hirata. To do full unitary residuals uncomment blocks
        # %1 and %2 below

        # g3s = (+ g.t3     # %1
        #        - g.t3.transpose([0, 1, 2, 3, 5, 4])
        #        + g.t3.transpose([0, 1, 2, 4, 5, 3]))

        # Apply n_body symmetry, which builds all
        # "opposite spin" parts of the unitary group residual
        g3 = ((
            +g.t3 + g.t3.transpose([1, 2, 0, 4, 5, 3]) + g.t3.transpose(
                [2, 0, 1, 5, 3, 4]) + g.t3.transpose([0, 2, 1, 3, 5, 4]) +
            g.t3.transpose([2, 1, 0, 5, 4, 3]) +
            g.t3.transpose([1, 0, 2, 4, 3, 5])
            # + 2 * g3s) / 12   # %2
        ) / 6)

        # Solve T3
        t3 = g3 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full'))

        # Symmetrize
        t3 = ((+t3 + t3.transpose([1, 2, 0, 4, 5, 3]) + t3.transpose(
            [2, 0, 1, 5, 3, 4]) + t3.transpose([0, 2, 1, 3, 5, 4]) +
               t3.transpose([2, 1, 0, 5, 4, 3]) +
               t3.transpose([1, 0, 2, 4, 3, 5])) / 6)

        return Tensors(t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
                       t2=t2,
                       t3=t3)
예제 #20
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')

        t1 = 2 * ham.f.ov.transpose().conj() * (-e_ai)
        v_vovo = einsum("pia,pjb->aibj", ham.l.pov, ham.l.pov).conj()

        t2_full = 2 * v_vovo.transpose([0, 2, 1, 3]) * (-e_abij)
        xs = cpd_initialize(t2_full.shape, self.rankt.t2)
        xs = als_dense(xs, t2_full, max_cycle=100)

        names = ['x1', 'x2', 'x3', 'x4']

        return Tensors(t1=t1, t2=Tensors(zip(names, xs)))
예제 #21
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')

        t1 = ham.f.ov.transpose().conj() * (-e_ai)
        v_vovo = einsum("pia,pjb->aibj", ham.l.pov, ham.l.pov).conj()

        t2_full = v_vovo.transpose([0, 2, 1, 3]) * (-e_abij)
        xs = ncpd_initialize(t2_full.shape, self.rankt.t2)
        xs = als_dense(xs, t2_full, max_cycle=100, tensor_format='ncpd')
        # xs_sym = cpd_symmetrize(xs, {(1, 0, 3, 2): ('ident',)})

        names = ['xlam', 'x1', 'x2', 'x3', 'x4']

        return Tensors(t1=t1, t2=Tensors(zip(names, xs)))
예제 #22
0
    def solve_amps(self, h, a, g):
        """
        Solve for new amplitudes using RHS and denominator
        """

        t1 = g.t1 * (-cc_denom(h.f, 2, 'dir', 'full'))

        # Symmetrize T2 HS
        g2 = 1 / 2 * (g.t2 + g.t2.transpose([1, 0, 3, 2]))

        # Solve T2
        t2_full = g2 * (-cc_denom(h.f, 4, 'dir', 'full'))

        xs = als_dense([a.t2.x1, a.t2.x2, a.t2.x3, a.t2.x4],
                       t2_full,
                       max_cycle=1,
                       tensor_format='cpd')

        return Tensors(t1=t1,
                       t2=Tensors(x1=xs[0], x2=xs[1], x3=xs[2], x4=xs[3]))
예제 #23
0
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'dir', 'full')
        e_abij = cc_denom(ham.f, 4, 'dir', 'full')
        nocc = self.mos.nocc
        nvir = self.mos.nvir

        t1 = ham.f.ov.transpose().conj() * (-e_ai)
        v_vovo = einsum("pia,pjb->aibj", ham.l.pov, ham.l.pov).conj()

        t2_full = v_vovo.transpose([0, 2, 1, 3]) * (-e_abij)
        t3names = ['xlam', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6']

        t3x = ncpd_initialize(
            (nvir, ) * 3 + (nocc, ) * 3,
            self.rankt.t3,
            init_function=(lambda x: 0.001 * np.random.rand(*x)))

        return Tensors(t1=t1, t2=t2_full, t3=Tensors(zip(t3names, t3x)))
예제 #24
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """
        t1 = g.t1 / (-2) * cc_denom(h.f, 2, 'dir', 'full')

        # Build unit RHS
        g2 = (2 * g.t2 + g.t2.transpose([0, 1, 3, 2])) / 6

        # Symmetrize RHS
        g2 = 1 / 2 * (g2 + g2.transpose([1, 0, 3, 2]))

        # Solve
        t2_full = g2 * (-cc_denom(h.f, 4, 'dir', 'full'))
        xs = als_dense([a.t2.x1, a.t2.x2, a.t2.x3, a.t2.x4],
                       t2_full,
                       max_cycle=1)

        names = ['x1', 'x2', 'x3', 'x4']
        return Tensors(t1=t1, t2=Tensors(zip(names, xs)))
예제 #25
0
    def solve_amps(self, h, a, g):
        """
        Solving for new T amlitudes using RHS and denominator
        It is assumed that the order of fields in the RHS
        is consistent with the order in amplitudes
        """
        # Solve
        t3 = g.t3 / 24 * (-cc_denom(h.f, g.t3.ndim, 'dir', 'full'))
        # Antisymmetrize over all indices (upper and lower separately)
        t3 = 1 / 6 * (+t3 - t3.transpose([1, 0, 2, 3, 4, 5]) + t3.transpose(
            [1, 2, 0, 3, 4, 5]) - t3.transpose([2, 1, 0, 3, 4, 5]) +
                      t3.transpose([2, 0, 1, 3, 4, 5]) -
                      t3.transpose([0, 2, 1, 3, 4, 5]))
        t3 = 1 / 6 * (+t3 - t3.transpose([0, 1, 2, 4, 3, 5]) + t3.transpose(
            [0, 1, 2, 4, 5, 3]) - t3.transpose([0, 1, 2, 5, 4, 3]) +
                      t3.transpose([0, 1, 2, 5, 3, 4]) -
                      t3.transpose([0, 1, 2, 3, 5, 4]))

        return Tensors(t1=g.t1 * (-cc_denom(h.f, g.t1.ndim, 'dir', 'full')),
                       t2=(2 * g.t2 + g.t2.transpose([0, 1, 3, 2])) / 6 *
                       (-cc_denom(h.f, 4, 'dir', 'full')),
                       t3=t3)
예제 #26
0
파일: rccsd_thc.py 프로젝트: qbit-/tcc
    def update_rhs(self, h, a, r):
        """
        Updates right hand side of the CC equations, commonly referred as G
        """
        # Here we simply copy the residuals of T2 factors
        # to the RHS arrays

        return self.types.RHS_TYPE(gt1=r.rt1 -
                                   a.t1 / cc_denom(h.f, 2, 'mul', 'full'),
                                   gx1=r.rx1,
                                   gx2=r.rx2,
                                   gx3=r.rx3,
                                   gx4=r.rx4,
                                   gx5=r.rx5)
예제 #27
0
파일: rccsd_thc.py 프로젝트: qbit-/tcc
    def init_amplitudes(self, ham):
        """
        Initialize amplitudes from interaction
        """
        e_ai = cc_denom(ham.f, 2, 'mul', 'full')

        t1 = ham.f.ov.transpose().conj() * (-e_ai)

        no = self.mos.nocc
        nv = self.mos.nvir

        v_vovo_factors = (ham.v.x1.v, ham.v.x2.o, ham.v.x3.v, ham.v.x4.o,
                          ham.v.x5)

        v_vovo_norm = thc_contract_thc(v_vovo_factors, v_vovo_factors)

        x1, x2, x3, x4, x5 = thc_initialize((nv, no, nv, no),
                                            self.rankt,
                                            scale_to_norm=1.0)

        return self.types.AMPLITUDES_TYPE(t1, x1, x2, x3, x4, x5)
예제 #28
0
파일: rccsd_thc.py 프로젝트: qbit-/tcc
    def calc_residuals(self, h, a):
        """
        Calculates CC residuals for CC equations
        """
        rt1 = gen_R1(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                     a.x2, a.x3, a.x4, a.x5)

        d = cc_denom(h.f, 4, ordering='mul', kind='cpd')

        rx1 = gen_RY1(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                      a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3])
        rx2 = gen_RY2(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                      a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3])
        rx3 = gen_RY3(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                      a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3])
        rx4 = gen_RY4(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                      a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3])
        rx5 = gen_RZ(h.f, h.v.x1, h.v.x2, h.v.x3, h.v.x4, h.v.x5, a.t1, a.x1,
                     a.x2, a.x3, a.x4, a.x5, d[0], d[1], d[2], d[3])

        return self.types.RESIDUALS_TYPE(rt1, rx1, rx2, rx3, rx4, rx5)
예제 #29
0
 def divide_by_inverse(x):
     return x / (cc_denom(h.f, x.ndim, 'dir', 'full'))
예제 #30
0
    def calculate_update(self, h, a):
        """
        Calculate new amplitudes
        """

        t3names = ['xlam', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6']
        t3x = [a.t3[key] for key in t3names]

        # Running residuals with symmetrized amplitudes.
        # symmetrizetion is done inside calc_residuals
        r = self.calc_residuals(
            h,
            Tensors(t1=a.t1, t2=a.t2,
                    t3=Tensors(zip(t3names, t3x)))
        )

        t1 = a.t1 - r.t1 * (cc_denom(h.f, 2, 'dir', 'full'))

        # Solve T2
        r2_d = - r.t2 * cc_denom(h.f, 4, 'dir', 'full')
        t2 = a.t2 + r2_d

        # Symmetrize
        t2 = 1 / 2 * (t2 + t2.transpose([1, 0, 3, 2]))

        # Build full unit residual
        r3s = (+ r.t3
               - r.t3.transpose([0, 1, 2, 3, 5, 4])
               + r.t3.transpose([0, 1, 2, 4, 5, 3]))
        r3u = ((+ r.t3
                + r.t3.transpose([1, 2, 0, 4, 5, 3])
                + r.t3.transpose([2, 0, 1, 5, 3, 4])
                + r.t3.transpose([0, 2, 1, 3, 5, 4])
                + r.t3.transpose([2, 1, 0, 5, 4, 3])
                + r.t3.transpose([1, 0, 2, 4, 3, 5])
                + 2 * r3s) / 12)

        # Solve
        r3_d = - r3u * cc_denom(h.f, 6, 'dir', 'full')

        # symmetrize inital T3
        t3x_sym = ncpd_symmetrize(t3x, {(1, 2, 0, 4, 5, 3): ('ident',),
                                        (2, 0, 1, 5, 3, 4): ('ident',),
                                        (0, 2, 1, 3, 5, 4): ('ident',),
                                        (2, 1, 0, 5, 4, 3): ('ident',),
                                        (1, 0, 2, 4, 3, 5): ('ident',)})
        # 0 1 2 4 3 5 permutation of t3
        t3x_sym_a = [t3x_sym[0], t3x_sym[1], t3x_sym[2], t3x_sym[3],
                     t3x_sym[5], t3x_sym[4], t3x_sym[6]]

        # Build combinations of T for unitary residual
        t3x_u = ncpd_symmetrize(
            t3x_sym,
            {(0, 1, 2, 4, 3, 5): ('neg',),
             (0, 1, 2, 5, 4, 3): ('neg',),
             (0, 1, 2, 3, 5, 4): ('neg',),
             (0, 1, 2, 5, 3, 4): ('ident',),
             (0, 1, 2, 4, 5, 3): ('ident',), },
            weights=[2 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 6, 1 / 6])

        t3x_au = ncpd_symmetrize(
            t3x_sym_a,
            {(0, 1, 2, 4, 3, 5): ('neg',),
             (0, 1, 2, 5, 4, 3): ('neg',),
             (0, 1, 2, 3, 5, 4): ('neg',),
             (0, 1, 2, 5, 3, 4): ('ident',),
             (0, 1, 2, 4, 5, 3): ('ident',), },
            weights=[2 / 3, 1 / 3, 1 / 3, 1 / 3, 1 / 6, 1 / 6])

        t3 = [f for f in t3x]
        for idx in range(len(t3)):
            g = (als_contract_dense(t3, r3_d, idx,
                                    tensor_format='ncpd')
                 + als_contract_cpd(t3, t3x_u, idx,
                                    tensor_format='ncpd')
                 - als_contract_cpd(t3, t3x_au, idx,
                                    tensor_format='ncpd')
                 )

            s = als_pseudo_inverse(t3, t3, idx)
            f = np.dot(g, s)
            t3[idx] = f

        return Tensors(t1=t1, t2=t2,
                       t3=Tensors(zip(t3names, t3)))