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)))
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)
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)
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)))
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
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)
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'))
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'))
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'))
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)
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'))
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]), )
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)
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)
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)
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'))
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)
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)
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)
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)))
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)))
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]))
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)))
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)))
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)
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)
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)
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)
def divide_by_inverse(x): return x / (cc_denom(h.f, x.ndim, 'dir', 'full'))
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)))