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 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)))
def calculate_update(self, h, a): """ Calculate new amplitudes """ t2names = ['xlam', 'x1', 'x2', 'x3', 'x4'] t2x = [a.t2[key] for key in t2names] t3names = ['xlam', 'x1', 'x2', 'x3', 'x4', 'x5', 'x6'] t3x = [a.t3[key] for key in t3names] # Running residuals with symmetrized amplitudes. # Symmetrization done inside calc_residuals r = self.calc_residuals( h, Tensors(t1=a.t1, t2=Tensors(zip(t2names, t2x)), t3=Tensors(zip(t3names, t3x)))) t1 = a.t1 - r.t1 * (cc_denom(h.f, 2, 'dir', 'full')) # Build symmetric residual r2 = 1 / 2 * (r.t2 + r.t2.transpose([1, 0, 3, 2])) # Solve r2_d = -r2 * cc_denom(h.f, 4, 'dir', 'full') # symmetrize initial T2 t2x_sym = ncpd_symmetrize(t2x, {(1, 0, 3, 2): ('ident', )}) t2 = [f for f in t2x] for idx in range(len(t2)): g = (als_contract_dense(t2, r2_d, idx, tensor_format='ncpd') + als_contract_cpd(t2, t2x_sym, idx, tensor_format='ncpd')) s = als_pseudo_inverse(t2, t2, idx) f = np.dot(g, s) t2[idx] = f # Build symmetric residual r3 = ((+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])) / 6) # Solve r3_d = -r3 * cc_denom(h.f, 6, 'dir', 'full') # symmetrize initial 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] ] 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_sym, idx, tensor_format='ncpd') - als_contract_cpd(t3, t3x_sym_a, idx, tensor_format='ncpd')) s = als_pseudo_inverse(t3, t3, idx) f = np.dot(g, s) t3[idx] = f return Tensors(t1=t1, t2=Tensors(zip(t2names, t2)), t3=Tensors(zip(t3names, t3)))