diff --git a/.coveragerc b/.coveragerc index 94b0e55..d750bd8 100644 --- a/.coveragerc +++ b/.coveragerc @@ -18,10 +18,20 @@ include = exclude_lines = # Have to re-enable the standard pragma pragma: no cover + pragma: deprecated + + # Code related to Vectorize b_loop + pragma: vectorize_b_loop + + # Code related to hot bands or thermal, not implemented + pragma: hot_bands_or_thermal + + # Code related ansatz restriction of only using t1 op + pragma: t1_truncation # Don't complain if tests don't hit defensive assertion code: raise NotImplementedError - + # raise Exception("Should not get here") # Don't complain if non-runnable code isn't run: if 0: if __name__ == .__main__.: @@ -36,6 +46,7 @@ exclude_lines = def old_print_wrapper old_print_wrapper new_t_list = t_list + if False: # currently unused functions # full cc latex diff --git a/.github/workflows/testing_coverage.yml b/.github/workflows/testing_coverage.yml index dd780d9..dd5fff6 100644 --- a/.github/workflows/testing_coverage.yml +++ b/.github/workflows/testing_coverage.yml @@ -5,7 +5,9 @@ on: # on pull requests yet. push: branches: - - ci_testing #change to test_* or *test etc later + - dev_* + - fix_* + - test_* workflow_dispatch: env: diff --git a/termfactory/code_eT_zhz.py b/termfactory/code_eT_zhz.py index 3fefceb..f77030f 100644 --- a/termfactory/code_eT_zhz.py +++ b/termfactory/code_eT_zhz.py @@ -79,17 +79,18 @@ def _eT_zhz_einsum_electronic_components(t_list, z_right, b_loop_flag=False): return electronic_components # otherwise + else: # pragma: vectorize_b_loop - # for each t term add 1 electronic label - electronic_components += ['a', ] * len(t_list) + # for each t term add 1 electronic label + electronic_components += ['a', ] * len(t_list) - # the H term always has 2 - electronic_components.append('ac') + # the H term always has 2 + electronic_components.append('ac') - # we assume Z always contributes - electronic_components.append('c') + # we assume Z always contributes + electronic_components.append('c') - return electronic_components + return electronic_components def _eT_zhz_einsum_electronic_components_lhs(t_list, dT, z_right, b_loop_flag=False): @@ -123,17 +124,18 @@ def _eT_zhz_einsum_electronic_components_lhs(t_list, dT, z_right, b_loop_flag=Fa return electronic_components # otherwise + else: # pragma: vectorize_b_loop - # for each t term add 1 electronic label - electronic_components += ['a', ] * len(t_list) + # for each t term add 1 electronic label + electronic_components += ['a', ] * len(t_list) - # the dT term has 1 electronic components - electronic_components.append('a') + # the dT term has 1 electronic components + electronic_components.append('a') - # we assume Z always contributes - electronic_components.append('c') + # we assume Z always contributes + electronic_components.append('c') - return electronic_components + return electronic_components # ----------------------------------------------------------------------------------------------- # # handle all the vibrational einsum string component @@ -162,7 +164,7 @@ def _build_z_term_python_labels(z_right, offset_dict): offset_dict['unlinked_count'] += z_right.m_lhs # subscript indices - if (z_right.n > 0): + if (z_right.n > 0): # pragma: hot_bands_or_thermal b = offset_dict['unlinked_count'] # record the characters we will place on the h term @@ -253,7 +255,7 @@ def _build_t_term_python_labels(term, offset_dict): offset_dict['unlinked_count'] += term.n_lhs # superscript indices - if (term.m > 0): + if (term.m > 0): # pragma: hot_bands_or_thermal a, b = offset_dict['summation_count'], offset_dict['unlinked_count'] # determine the summation indices @@ -420,7 +422,12 @@ def _eT_zhz_einsum_prefactor(term): # pragma: no cover return string # ----------------------------------------------------------------------------------------------- # -# all three are dealing with prefactor determination +# ----------------------------------------------------------------------------------------------- # +# helper functions for _write_third_eTz_einsum_python + + +# ----------------------------------------------------------------------------------------------- # +# all four are dealing with prefactor determination def _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list): @@ -440,18 +447,19 @@ def _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list): else: intersection = numerator_set & denominator_set + # count number of appearances numerator_dict = dict([(key, 0) for key in numerator_set]) for string in numerator_list: numerator_dict[string] += 1 - old_print_wrapper('nnnn', numerator_dict) + log.debug('nnnn', numerator_dict) denominator_dict = dict([(key, 0) for key in denominator_set]) for string in denominator_list: denominator_dict[string] += 1 - old_print_wrapper('dddd', denominator_dict) - + log.debug('dddd', denominator_dict) + # loop over each unique prefactor for key in intersection: a, b = numerator_dict[key], denominator_dict[key] if a > b: @@ -465,18 +473,21 @@ def _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list): numerator_dict[key] = 0 # make updated lists - numerator_list, denominator_list = [], [] + new_numerator_list, new_denominator_list = [], [] for k, v in numerator_dict.items(): - numerator_list.extend([k, ]*v) + new_numerator_list.extend([k, ]*v) for k, v in denominator_dict.items(): - denominator_list.extend([k, ]*v) + new_denominator_list.extend([k, ]*v) + + new_numerator_list.sort() + new_denominator_list.sort() if len(numerator_list) > 2 or len(denominator_list) > 2: - old_print_wrapper('xxxx', numerator_list) - old_print_wrapper('yyyy', denominator_list) + log.debug('xxxx', new_numerator_list) + log.debug('yyyy', new_denominator_list) - return numerator_list, denominator_list + return new_numerator_list, new_denominator_list def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): @@ -497,11 +508,11 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): """ # temporary, we need to redo this whole function anyways - if t_list == []: + if t_list == []: # pragma: no cover, never happens? return '' # special case, single h - if len(t_list) == 1 and t_list[0] == disconnected_namedtuple(0, 0, 0, 0): + if len(t_list) == 1 and t_list[0] == disconnected_namedtuple(0, 0, 0, 0): # pragma: no cover, never happens? return '' # initialize @@ -519,7 +530,7 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): denominator_list.append(f'factorial({h.m})') if extra_flag: - # to account for the permutations of eT-H internal labels around + # to account for the permutations of eT-H internal labels around the external labels external_perms = math.comb(h.m, h.m_lhs) if external_perms > 1: numerator_value *= external_perms @@ -530,7 +541,7 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): # to account for the permutations of H-Z internal labels around the external labels internal_perms = math.comb(new_max, h.m_r) - if internal_perms > 1: + if internal_perms > 1: # pragma: no cover, probably bc only ground state numerator_value *= internal_perms numerator_list.append(f'({internal_perms})') @@ -550,7 +561,7 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): if extra_flag: # to account for the permutations of eT-H internal labels around external_perms = math.comb(h.n, h.n_lhs) - if external_perms > 1: + if external_perms > 1: # pragma: hot_bands_or_thermal numerator_value *= external_perms numerator_list.append(f'({external_perms})') @@ -559,7 +570,7 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): # to account for the permutations of H-Z internal labels around the external labels internal_perms = math.comb(new_max, h.n_r) - if internal_perms > 1: + if internal_perms > 1: # pragma: hot_bands_or_thermal numerator_value *= internal_perms numerator_list.append(f'({internal_perms})') @@ -619,7 +630,7 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): numerator_value *= number numerator_list.append(f'{number}') - if z_right.n > 1: + if z_right.n > 1: # pragma: hot_bands_or_thermal denominator_value *= math.factorial(z_right.n) denominator_list.append(f'factorial({z_right.n})') @@ -653,12 +664,12 @@ def _build_eT_zhz_python_prefactor(t_list, h, z_right, simplify_flag=True): # denominator_list.append(f'factorial({len(t_list)})') for t in t_list: - if t.m > 1: + if t.m > 1: # pragma: t1_truncation # by definition denominator_value *= math.factorial(t.m) denominator_list.append(f'{t.m}!') - if t.n > 1: + if t.n > 1: # pragma: t1_truncation # by definition denominator_value *= math.factorial(t.n) denominator_list.append(f'{t.n}!') @@ -739,161 +750,268 @@ def _multiple_perms_logic(term, print_indist_perms: bool = False): # old_print_wrapper([unique_permutations(range(v)) for k, v in unique_dict.items()]) # return dict([(k, list(*unique_permutations(range(v)))) for k, v in unique_dict.items()]), unique_dict - raise Exception("Shouldn't get here") -# ----------------------------------------------------------------------------------------------- # -# big boy function that does most of the work + raise Exception("Should not get here") # pragma: no cover -def _write_third_eTz_einsum_python(rank, operators, t_term_list, lhs_rhs, trunc_obj_name='truncation', b_loop_flag=False, suppress_empty_if_checks=True): - """ Still being written +def compute_prefactor_adjustment(h, z_right): # pragma: deprecated + """ x """ - the flag `suppress_empty_if_checks` is to toggle the "suppression" of code such as - ``` - if truncation.singles: - pass - ``` - which doesn't actually do anything. - """ + adjustment = 1 + bottom = 1 - master_omega, H, Z, eT_taylor_expansion = operators - log.info("Starting this function") + if h.m > 1: + bottom *= math.factorial(h.m) - if t_term_list == []: - return ["pass # no valid terms here", ] + # to account for the permutations of eT-H internal labels around + external_perms = math.comb(h.m, h.m_lhs) + if external_perms > 1: + adjustment *= external_perms - return_list = [] + # like drawing cards from a deck we remove the permutations of the Proj + new_max = h.m - h.m_lhs - hamiltonian_rank_list = [] - for i in range(H.maximum_rank+1): - hamiltonian_rank_list.append(dict([(i, {}) for i in range(master_omega.maximum_rank+1)])) + # to account for the permutations of H-Z internal labels around the external labels + internal_perms = math.comb(new_max, h.m_r) + if internal_perms > 1: + adjustment *= internal_perms - def compute_prefactor_adjustment(h, z_right): - """ x """ + # to account for the permutations of eT-Z internal labels with themselves + # as we should have accounted for all permutations by + # moving H-Z and external labels prior + count_t = sum(h.m_t) + if count_t > 1: + # account for permutations among the internal labels + adjustment *= math.factorial(count_t) - adjustment = 1 - bottom = 1 + if h.n > 1: + bottom *= math.factorial(h.n) - if h.m > 1: - bottom *= math.factorial(h.m) + # to account for the permutations of eT-H internal labels around + external_perms = math.comb(h.n, h.n_lhs) + if external_perms > 1: + adjustment *= external_perms - # to account for the permutations of eT-H internal labels around - external_perms = math.comb(h.m, h.m_lhs) - if external_perms > 1: - adjustment *= external_perms + # like drawing cards from a deck we remove the permutations of the Proj + new_max = h.n - h.n_lhs - # like drawing cards from a deck we remove the permutations of the Proj - new_max = h.m - h.m_lhs + # to account for the permutations of H-Z internal labels around the external labels + internal_perms = math.comb(new_max, h.n_r) + if internal_perms > 1: + adjustment *= internal_perms - # to account for the permutations of H-Z internal labels around the external labels - internal_perms = math.comb(new_max, h.m_r) - if internal_perms > 1: - adjustment *= internal_perms + # to account for the permutations of eT-Z internal labels with themselves + # as we should have accounted for all permutations by + # moving H-Z and external labels prior + count_t = sum(h.n_t) + if count_t > 1: + # account for permutations among the internal labels + adjustment *= math.factorial(count_t) - # to account for the permutations of eT-Z internal labels with themselves - # as we should have accounted for all permutations by - # moving H-Z and external labels prior - count_t = sum(h.m_t) - if count_t > 1: - # account for permutations among the internal labels - adjustment *= math.factorial(count_t) + # --------------------------------------------------------------------------------------------------------- - if h.n > 1: - bottom *= math.factorial(h.n) + if z_right.m > 1: + bottom *= math.factorial(z_right.m) + + # to account for the permutations of external labels with other labels on z + # (we don't account for permuting with themselves as we will symmetrize them later) + external_perms = math.comb(z_right.m, z_right.m_lhs) + if external_perms > 1: + adjustment *= external_perms + + # like drawing cards from a deck we remove the permutations of the Proj + new_max = z_right.m - z_right.m_lhs + + # to account for the permutations of H-Z internal labels with other labels on z + internal_perms = math.comb(new_max, z_right.m_h) + if internal_perms > 1: + adjustment *= internal_perms + + # like drawing cards from a deck we remove the permutations of the H + new_max -= z_right.m_h + + # to account for the permutations of H-Z internal labels with themselves + if z_right.m_h > 1: + adjustment *= math.factorial(z_right.m_h) + + # to account for the permutations of eT-Z internal labels with themselves + # as we should have accounted for all permutations by + # moving H-Z and external labels prior + count_t = sum(z_right.m_t) + if count_t > 1: + # account for permutations among the internal labels + adjustment *= math.factorial(count_t) + + # account for permutations with respect to other labels + # (this is just to prove that we already accounted for these permutations) + number = math.comb(new_max, count_t) + assert number == 1, 'you broke something!!!' + if number > 1: # pragma: no cover + adjustment *= number - # to account for the permutations of eT-H internal labels around - external_perms = math.comb(h.n, h.n_lhs) - if external_perms > 1: - adjustment *= external_perms + if z_right.n > 1: + bottom *= math.factorial(z_right.n) - # like drawing cards from a deck we remove the permutations of the Proj - new_max = h.n - h.n_lhs + # to account for the permutations of external labels + number = math.comb(z_right.n, z_right.n_lhs) + if number > 1: + adjustment *= number - # to account for the permutations of H-Z internal labels around the external labels - internal_perms = math.comb(new_max, h.n_r) - if internal_perms > 1: - adjustment *= internal_perms + # to account for the permutations of internal labels (with h) + if z_right.n_h > 1: + adjustment *= math.factorial(z_right.n_h) - # to account for the permutations of eT-Z internal labels with themselves - # as we should have accounted for all permutations by - # moving H-Z and external labels prior - count_t = sum(h.n_t) - if count_t > 1: - # account for permutations among the internal labels - adjustment *= math.factorial(count_t) + # to account for the permutations of internal labels (with t terms) + count_t = sum(z_right.n_t) + if count_t > 1: + # account for permutations among the internal labels + adjustment *= math.factorial(count_t) - # --------------------------------------------------------------------------------------------------------- + # account for permutations with respect to other labels + number = math.comb(z_right.n, count_t) + adjustment *= number - if z_right.m > 1: - bottom *= math.factorial(z_right.m) + print(f"{adjustment = }") + print(f"{bottom = }") + print(f"{ adjustment / bottom = }") - # to account for the permutations of external labels with other labels on z - # (we don't account for permuting with themselves as we will symmetrize them later) - external_perms = math.comb(z_right.m, z_right.m_lhs) - if external_perms > 1: - adjustment *= external_perms + return adjustment / bottom - # like drawing cards from a deck we remove the permutations of the Proj - new_max = z_right.m - z_right.m_lhs - # to account for the permutations of H-Z internal labels with other labels on z - internal_perms = math.comb(new_max, z_right.m_h) - if internal_perms > 1: - adjustment *= internal_perms +# ----------------------------------------------------------------------------------------------- # +# these handle collating multiple-lines + +def _handle_multiline_same_prefactor( + output_list, prefactor, string_list, lhs_rhs, + nof_tabs=0 +): + """ Specific formatting of multiple terms that share the same prefactor + + When we have multiple einsum terms which share the same prefactor + we collate them in a specific manner like so: + R += prefactor * ( + + + + + ... + + + + ) + + This function simply glues them together in that fashion. + """ - # like drawing cards from a deck we remove the permutations of the H - new_max -= z_right.m_h + tabber = tab*nof_tabs - # to account for the permutations of H-Z internal labels with themselves - if z_right.m_h > 1: - adjustment *= math.factorial(z_right.m_h) + if len(string_list) > 1: - # to account for the permutations of eT-Z internal labels with themselves - # as we should have accounted for all permutations by - # moving H-Z and external labels prior - count_t = sum(z_right.m_t) - if count_t > 1: - # account for permutations among the internal labels - adjustment *= math.factorial(count_t) + # header + if lhs_rhs == 'RHS': + output_list.append(f"{tabber}R += {prefactor}(") + elif lhs_rhs == 'LHS': + output_list.append(f"{tabber}Z += {prefactor}(") - # account for permutations with respect to other labels - # (this is just to prove that we already accounted for these permutations) - number = math.comb(new_max, count_t) - assert number == 1, 'you broke something!!!' - if number > 1: # pragma: no cover - adjustment *= number + # add each line + for string in string_list: + output_list.append(f"{tabber}{tab}{string} +") - if z_right.n > 1: - bottom *= math.factorial(z_right.n) + # remove the last plus symbol + output_list[-1] = output_list[-1][:-2] - # to account for the permutations of external labels - number = math.comb(z_right.n, z_right.n_lhs) - if number > 1: - adjustment *= number + # footer + output_list.append(f"{tabber})") - # to account for the permutations of internal labels (with h) - if z_right.n_h > 1: - adjustment *= math.factorial(z_right.n_h) + else: + # print(f"c {string_list = }") + if lhs_rhs == 'RHS': + output_list.append(f"{tabber}R += {prefactor}{string_list[0]}") + elif lhs_rhs == 'LHS': + output_list.append(f"{tabber}Z += {prefactor}{string_list[0]}") - # to account for the permutations of internal labels (with t terms) - count_t = sum(z_right.n_t) - if count_t > 1: - # account for permutations among the internal labels - adjustment *= math.factorial(count_t) + return output_list + + +def _collect_z_contributions( + h_dict, return_array, lhs_rhs, trunc_obj_name, + suppress_empty_if_checks=True, nof_tabs=0, +): + """ This is a gatekeeper for all einsum equations that are printed + everything gets parsed through this function + every single line that gets printed with `einsum` in it comes from the `return_array` + which this function appends to + """ + + # h^0_0 with zero order Taylor series contributions + for z_order, z_dict in h_dict.items(): + + # exception case for z_order == 0 which has no if statement + tab_adjust = nof_tabs if z_order == 0 else nof_tabs + 1 + + temp_z_list = [] # if not empty + + for prefactor, string_list in z_dict.items(): + if string_list == []: # skip if empty + continue + + _handle_multiline_same_prefactor( + temp_z_list, prefactor, string_list, lhs_rhs, + nof_tabs=tab_adjust + ) + + # processing + if suppress_empty_if_checks and (temp_z_list == []): + continue + + if z_order == 0: + return_array.extend(temp_z_list) + + else: + tabstr = tab * nof_tabs + z_header_if_string = ( + f"{tabstr}if {trunc_obj_name}.z_at_least_{hamiltonian_order_tag[z_order]}:" + ) + + if temp_z_list == []: # pragma: no cover + return_array.append(z_header_if_string) + return_array.append(f"{tabstr}{tab}pass") + else: + return_array.append(z_header_if_string) + return_array.extend(temp_z_list) + + +# ----------------------------------------------------------------------------------------------- # +# big boy function that does most of the work + + +def _write_third_eTz_einsum_python(rank, operators, t_term_list, lhs_rhs, trunc_obj_name='truncation', b_loop_flag=False, suppress_empty_if_checks=True): + """ Still being written + + the flag `suppress_empty_if_checks` is to toggle the "suppression" of code such as + ``` + if truncation.singles: + pass + ``` + which doesn't actually do anything. + """ + + master_omega, H, Z, eT_taylor_expansion = operators + log.info("Starting this function") - # account for permutations with respect to other labels - number = math.comb(z_right.n, count_t) - adjustment *= number + if t_term_list == []: + return ["pass # no valid terms here", ] - print(f"{adjustment = }") - print(f"{bottom = }") - print(f"{ adjustment / bottom = }") + return_list = [] - return adjustment / bottom + # hamiltonian_rank_list is as: + # list + # of dictionaries + # of dictionaries + # of lists + hamiltonian_rank_list = [] + for i in range(H.maximum_rank+1): + hamiltonian_rank_list.append(dict([(i, {}) for i in range(master_omega.maximum_rank+1)])) - # - # - # - # the big loop + # -------------------------------------------------------------- # + # the big loop! + # -------------------------------------------------------------- # for term in t_term_list: omega, t_list, h, z_pair, not_sure_what_this_one_is_for = term @@ -929,7 +1047,7 @@ def compute_prefactor_adjustment(h, z_right): z_operand = f"z_args[({z_right.m}, {z_right.n})]" # the t counts as identity - if t_list == []: + if t_list == []: # pragma: deprecated permutations = None max_t_rank = 0 prefactor = '' @@ -944,7 +1062,7 @@ def compute_prefactor_adjustment(h, z_right): print_indist_perms = False # the easy case where we just print EVERYTHING - if print_indist_perms is True: + if print_indist_perms is True: # pragma: no cover 'we want this functionality for debugging and investigation' # logic about multiple permutations, generate lists of unique t terms permutations, unique_dict = _multiple_perms_logic(term, print_indist_perms) @@ -1002,7 +1120,13 @@ def compute_prefactor_adjustment(h, z_right): # ----------------------------------------------------------------------------------------- # build with permutations - hamiltonian_rank_list[max(h.m, h.n)].setdefault(max_t_rank, {}).setdefault(z_right.rank, {}).setdefault(prefactor, []) + hamiltonian_rank_list[max(h.m, h.n)].setdefault( + max_t_rank, {} + ).setdefault( + z_right.rank, {} + ).setdefault( + prefactor, [] + ) # old_print_wrapper(f"{t_list = }") if lhs_rhs == 'RHS': @@ -1044,7 +1168,7 @@ def compute_prefactor_adjustment(h, z_right): string = ", ".join(combined_electronic_vibrational) # stick the indices into the full einsum function call - if h_operand is None: + if h_operand is None: # pragma: hot_bands_or_thermal string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {z_operand})" else: string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {h_operand}, {z_operand})" @@ -1067,7 +1191,7 @@ def compute_prefactor_adjustment(h, z_right): string = ", ".join(combined_electronic_vibrational) # stick the indices into the full einsum function call - if h_operand is None: + if h_operand is None: # pragma: hot_bands_or_thermal string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {z_operand})" else: string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {h_operand}, {z_operand})" @@ -1161,7 +1285,7 @@ def compute_prefactor_adjustment(h, z_right): string = ", ".join(combined_electronic_vibrational) # stick the indices into the full einsum function call - if h_operand is None: + if h_operand is None: # pragma: hot_bands_or_thermal string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {t_operands}, {z_operand})" else: string = f"np.einsum('{string} -> {e_char}{remaining_indices}', {t_operands}, {h_operand}, {z_operand})" @@ -1173,8 +1297,8 @@ def compute_prefactor_adjustment(h, z_right): # import pdb; pdb.set_trace() - else: - raise Exception('') + else: # pragma: no cover + raise Exception("Should not get here") """ lazy hack because we I don't trust myself to properly modify `latex_eT_zhz.py` at the moment @@ -1324,93 +1448,14 @@ def compact_display_of_hamiltonian_rank_list(hamiltonian_rank_list): # ----------------------------------------------------------------------------------------- - def _handle_multiline_same_prefactor(output_list, prefactor, string_list, lhs_rhs, nof_tabs=0): - """ Specific formatting of multiple terms that share the same prefactor - - When we have multiple einsum terms which share the same prefactor - we collate them in a specific manner like so: - R += prefactor * ( - + - + - ... - + - - ) - - This function simply glues them together in that fashion. - """ - - tabber = tab*nof_tabs - - if len(string_list) > 1: - - # header - if lhs_rhs == 'RHS': - output_list.append(f"{tabber}R += {prefactor}(") - elif lhs_rhs == 'LHS': - output_list.append(f"{tabber}Z += {prefactor}(") - - # add each line - for string in string_list: - output_list.append(f"{tabber}{tab}{string} +") - - # remove the last plus symbol - output_list[-1] = output_list[-1][:-2] - - # footer - output_list.append(f"{tabber})") - - else: - # print(f"c {string_list = }") - if lhs_rhs == 'RHS': - output_list.append(f"{tabber}R += {prefactor}{string_list[0]}") - elif lhs_rhs == 'LHS': - output_list.append(f"{tabber}Z += {prefactor}{string_list[0]}") - - return output_list - h_contribution_list = [] - def collect_z_contributions(h_dict, return_array, nof_tabs=0): - """ This is a gatekeeper for all einsum equations that are printed - everything gets parsed through this function - every single line that gets printed with `einsum` in it comes from the `return_array` - which this function appends to - """ - - # h^0_0 with zero order Taylor series contributions - for z_order, z_dict in h_dict.items(): - if z_dict is {}: continue; # skip if empty - - # exception case for z_order == 0 which has no if statement - tab_adjust = nof_tabs if z_order == 0 else nof_tabs + 1 - - temp_z_list = [] # if not empty - - for prefactor, string_list in z_dict.items(): - if string_list == []: continue; # skip if empty - - _handle_multiline_same_prefactor(temp_z_list, prefactor, string_list, lhs_rhs, nof_tabs=tab_adjust) - - # processing - if temp_z_list == [] and suppress_empty_if_checks: - continue - - if z_order == 0: - return_array.extend(temp_z_list) - - else: - tabstr = tab*nof_tabs - z_header_if_string = f"{tabstr}if {trunc_obj_name}.z_at_least_{hamiltonian_order_tag[z_order]}:" - - if temp_z_list == []: - return_array.append(z_header_if_string) - return_array.append(f"{tabstr}{tab}pass") - else: - return_array.append(z_header_if_string) - return_array.extend(temp_z_list) - - collect_z_contributions(hamiltonian_rank_list[0][0], h_contribution_list, nof_tabs=0) + _collect_z_contributions( + hamiltonian_rank_list[0][0], h_contribution_list, + lhs_rhs, trunc_obj_name, + suppress_empty_if_checks=suppress_empty_if_checks, + nof_tabs=0, + ) # loop over first order (and higher) Taylor series contributions for j in range(1, master_omega.maximum_rank+1): @@ -1419,7 +1464,12 @@ def collect_z_contributions(h_dict, return_array, nof_tabs=0): temp_list = [] # if not empty # h^0_0 with first order (and higher) Taylor series contributions - collect_z_contributions(hamiltonian_rank_list[0][j], temp_list, nof_tabs=1) + _collect_z_contributions( + hamiltonian_rank_list[0][j], temp_list, + lhs_rhs, trunc_obj_name, + suppress_empty_if_checks=suppress_empty_if_checks, + nof_tabs=1, + ) # processing if temp_list == [] and suppress_empty_if_checks: @@ -1439,7 +1489,12 @@ def collect_z_contributions(h_dict, return_array, nof_tabs=0): temp_list = [] # if not empty # h^i_j with zero order Taylor series contributions - collect_z_contributions(hamiltonian_rank_list[i][0], temp_list, nof_tabs=1) + _collect_z_contributions( + hamiltonian_rank_list[i][0], temp_list, + lhs_rhs, trunc_obj_name, + suppress_empty_if_checks=suppress_empty_if_checks, + nof_tabs=1, + ) # for prefactor in hamiltonian_rank_list[i][0].keys(): # if hamiltonian_rank_list[i][0][prefactor] is {}: continue; # skip if empty @@ -1462,7 +1517,12 @@ def collect_z_contributions(h_dict, return_array, nof_tabs=0): temp_list = [] # if not empty # h^i_j with first order (and higher) Taylor series contributions - collect_z_contributions(hamiltonian_rank_list[i][j], temp_list, nof_tabs=2) + _collect_z_contributions( + hamiltonian_rank_list[i][j], temp_list, + lhs_rhs, trunc_obj_name, + suppress_empty_if_checks=suppress_empty_if_checks, + nof_tabs=2, + ) # processing if temp_list == [] and suppress_empty_if_checks: @@ -1541,7 +1601,7 @@ def remove_all_excited_state_t_terms(eT_taylor_expansion): # if this element is not a list if not isinstance(e1, list): # and the element has annihilation operators - if e1.m > 0: + if e1.m > 0: # pragma: hot_bands_or_thermal # record this index as one that we have to remove i_list.append(i) @@ -1553,7 +1613,7 @@ def remove_all_excited_state_t_terms(eT_taylor_expansion): # if this element is not a list if not isinstance(e2, list): # and the element has annihilation operators - if e2.m > 0: + if e2.m > 0: # pragma: hot_bands_or_thermal # record this index as one that we have to remove j_list.append(1) continue @@ -1662,7 +1722,7 @@ def _generate_eT_zhz_einsums(Proj, operators, lhs_rhs, only_ground_state=False, # generate all valid combinations _filter_out_valid_eTz_terms(Proj, eT_series_term, H, None, Z, valid_term_list, 'RHS') - if False: # debug + if False: old_print_wrapper('\n\n\n') # save in a human readable format to a file @@ -1728,7 +1788,7 @@ def _construct_eT_zhz_compute_function(Proj, operators, lhs_rhs, only_ground_sta ground_state_only_einsums = _generate_eT_zhz_einsums(Proj, operators, lhs_rhs, only_ground_state=True, opt_einsum=opt_einsum) # generate ground + excited state einsums - if not only_ground_state: + if not only_ground_state: # pragma: hot_bands_or_thermal ground_and_excited_state_einsums = _generate_eT_zhz_einsums(Proj, operators, lhs_rhs, only_ground_state=False, opt_einsum=opt_einsum) else: ground_and_excited_state_einsums = [("raise Exception('Hot Band amplitudes not implemented!')", ), ]*2 diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..762be68 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,239 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..75e5bc2 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,255 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..9b3c4b6 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,259 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..9b3c4b6 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,259 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..419f15f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,269 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..3ca08b6 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,281 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..6bfacbf --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,285 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..6309485 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,271 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..e1c605d --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,291 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..ae25fd8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,303 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..6309485 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,271 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..a2cdec6 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,293 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..f44c21a --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(1)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,313 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..762be68 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,239 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..9ca5aed --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,364 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..8d21d3f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..7d9d7c5 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,384 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..7fd9283 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,378 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..78422f8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,412 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..4dc046f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,424 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..3e061b8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,422 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..cdad2f7 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,446 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..34a118d --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,424 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..afe3a83 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(2)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,456 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..762be68 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,239 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..9ca5aed --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,364 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..a1498fa --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,491 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..225ab22 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,507 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..7fd9283 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,378 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..df3bce3 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,523 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..e433442 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,553 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..c3bdd49 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,533 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..1b9116d --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,575 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..58f0a5b --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,535 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..a5d9b38 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(3)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,585 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..762be68 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,239 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..9ca5aed --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,364 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..a1498fa --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,491 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..8368b62 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,620 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..7fd9283 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,378 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..df3bce3 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,523 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..3fc2469 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,666 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..c3bdd49 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,533 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..86a43a2 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,688 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..7fc9897 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,243 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..5dc8ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,380 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..58f0a5b --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,535 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..0993bac --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(1)_P(4)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,698 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..f70b9bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,261 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..3b3f126 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,293 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..8f5a9f4 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,311 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..19f2616 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,315 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..45e46a8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,279 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..5620b0a --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,325 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..9869767 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,355 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..629dac2 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,367 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..4451a73 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,341 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..1cdb404 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,389 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..e00443d --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,417 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..82383d4 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,345 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..413453a --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,401 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..04f4b07 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(1)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,447 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..f70b9bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,261 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..6559027 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,424 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..26491bb --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,460 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..73bc6b6 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,472 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..45e46a8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,279 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..f70ac1e --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,468 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..3ab03cc --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,524 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..b624cba --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,556 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..50f34df --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,484 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..6e0b82c --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,566 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..f4225b1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,618 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..0e18461 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,488 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..53ecfae --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,578 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..64f2f95 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(2)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,656 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..f70b9bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,261 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..6559027 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,424 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..0adc5bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,599 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..3d52a35 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,629 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..45e46a8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,279 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..f70ac1e --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,468 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..7066566 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,671 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..1cec794 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,729 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..50f34df --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,484 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..898d68e --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,713 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..5d6a1c7 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,803 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..0e18461 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,488 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..e71eaec --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,725 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..b570ad1 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(3)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,841 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(1).py new file mode 100644 index 0000000..f70b9bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(1).py @@ -0,0 +1,261 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(2).py new file mode 100644 index 0000000..6559027 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(2).py @@ -0,0 +1,424 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(3).py new file mode 100644 index 0000000..0adc5bd --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(3).py @@ -0,0 +1,599 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(4).py new file mode 100644 index 0000000..820e5f5 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(1)_Z(4).py @@ -0,0 +1,766 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(1).py new file mode 100644 index 0000000..45e46a8 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(1).py @@ -0,0 +1,279 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(2).py new file mode 100644 index 0000000..f70ac1e --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(2).py @@ -0,0 +1,468 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(3).py new file mode 100644 index 0000000..7066566 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(3).py @@ -0,0 +1,671 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(4).py new file mode 100644 index 0000000..0030f32 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(2)_Z(4).py @@ -0,0 +1,874 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(2).py new file mode 100644 index 0000000..50f34df --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(2).py @@ -0,0 +1,484 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(3).py new file mode 100644 index 0000000..898d68e --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(3).py @@ -0,0 +1,713 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(4).py new file mode 100644 index 0000000..bda4330 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(3)_Z(4).py @@ -0,0 +1,948 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(1).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(1).py new file mode 100644 index 0000000..440190f --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(1).py @@ -0,0 +1,283 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(2).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(2).py new file mode 100644 index 0000000..0e18461 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(2).py @@ -0,0 +1,488 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(3).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(3).py new file mode 100644 index 0000000..e71eaec --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(3).py @@ -0,0 +1,725 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(4).py b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(4).py new file mode 100644 index 0000000..10f88b0 --- /dev/null +++ b/tests/deep/files/test_code_eT_zhz/eT_zhz_eqs_RHS_H(2)_P(4)_T(1)_exp(4)_Z(4).py @@ -0,0 +1,986 @@ +# system imports +from math import factorial + +# third party imports +import numpy as np +import opt_einsum as oe + +# local imports +from .symmetrize import symmetrize_tensor +from ..log_conf import log + +# ------------------------------------------------------------------------------------------------------------- # +# --------------------------------------------- DEFAULT FUNCTIONS --------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args): + """ Calculate the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # add the terms + add_m0_n0_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n0_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n1_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # add the terms + add_m0_n1_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n1_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n2_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # add the terms + add_m0_n2_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n2_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n3_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # add the terms + add_m0_n3_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n3_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + + +def compute_m0_n4_amplitude(A, N, ansatz, truncation, t_args, h_args, z_args): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # add the terms + add_m0_n4_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + add_m0_n4_eT_HZ_terms(R, ansatz, truncation, t_args, h_args, z_args) + return R + +# ------------------------------------------------------------------------------------------------------------- # +# -------------------------------------------- OPTIMIZED FUNCTIONS -------------------------------------------- # +# ------------------------------------------------------------------------------------------------------------- # + +# --------------------------------------------- INDIVIDUAL TERMS --------------------------------------------- # + + +# -------------- operator(name='', rank=0, m=0, n=0) TERMS -------------- # +def add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('aci, ci -> a', h_args[(0, 1)], z_args[(1, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acij, cij -> a', h_args[(0, 2)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='', rank=0, m=0, n=0) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, ac, ci -> a', t_args[(0, 1)], h_args[(0, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('i, j, ac, cij -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, j, k, l, ac, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + R += np.einsum('i, aci, c -> a', t_args[(0, 1)], h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acij, cj -> a', t_args[(0, 1)], h_args[(1, 1)], z_args[(1, 0)]) + + np.einsum('i, j, acj, ci -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acj, cij -> a', t_args[(0, 1)], h_args[(0, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acjk, cik -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, k, ack, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ackl, cijl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, l, acl, cijk -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * ( + np.einsum('i, j, k, acl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, aclm, cijkm -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += (1 / 2) * np.einsum('i, j, acij, c -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('i, j, k, acjk, ci -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cij -> a', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acjk, cijk -> a', t_args[(0, 1)], h_args[(0, 2)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ackl, cijkl -> a', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 1 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='b', rank=1, m=0, n=1) TERMS -------------- # +def add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + R += np.einsum('acz, c -> az', h_args[(1, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('aciz, ci -> az', h_args[(1, 1)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aci, ciz -> az', h_args[(0, 1)], z_args[(2, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('acij, cijz -> az', h_args[(0, 2)], z_args[(3, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='b', rank=1, m=0, n=1) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, ac, ciz -> az', t_args[(0, 1)], h_args[(0, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, j, ac, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, j, k, ac, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += ( + np.einsum('i, acz, ci -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + + np.einsum('i, aci, cz -> az', t_args[(0, 1)], h_args[(1, 0)], z_args[(1, 0)]) + ) + if truncation.z_at_least_quadratic: + R += ( + np.einsum('i, acij, cjz -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, acjz, cij -> az', t_args[(0, 1)], h_args[(1, 1)], z_args[(2, 0)]) + + np.einsum('i, j, acj, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + ) + R += (1 / 2) * np.einsum('i, j, acz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += ( + np.einsum('i, acj, cijz -> az', t_args[(0, 1)], h_args[(0, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acjk, cikz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + ) + R += (1 / 2) * ( + np.einsum('i, j, ackz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, k, ack, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + R += (1 / 6) * np.einsum('i, j, k, acz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, j, ack, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, ackl, cijlz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 24) * np.einsum('i, j, k, l, acz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, j, k, aclz, cijkl -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, k, l, acl, cijkz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + R += np.einsum('i, aciz, c -> az', t_args[(0, 1)], h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_linear: + R += np.einsum('i, j, acjz, ci -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, j, acij, cz -> az', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, j, k, acjk, ciz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, k, ackz, cij -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, j, k, l, ackl, cijz -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijk -> az', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjk, cijkz -> az', t_args[(0, 1)], h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 2 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bb', rank=2, m=0, n=2) TERMS -------------- # +def add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_linear: + R += np.einsum('acz, cy -> azy', h_args[(1, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('aciz, ciy -> azy', h_args[(1, 1)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aci, cizy -> azy', h_args[(0, 1)], z_args[(3, 0)]) + + if truncation.h_at_least_quadratic: + R += (1 / 2) * np.einsum('aczy, c -> azy', h_args[(2, 0)], z_args[(0, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('acij, cijzy -> azy', h_args[(0, 2)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bb', rank=2, m=0, n=2) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, ac, cizy -> azy', t_args[(0, 1)], h_args[(0, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 4) * np.einsum('i, j, ac, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += np.einsum('i, acz, ciy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + R += (1 / 2) * np.einsum('i, aci, czy -> azy', t_args[(0, 1)], h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += np.einsum('i, acjz, cijy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + R += (1 / 2) * ( + np.einsum('i, acij, cjzy -> azy', t_args[(0, 1)], h_args[(1, 1)], z_args[(3, 0)]) + + np.einsum('i, j, acj, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + + np.einsum('i, j, acz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + ) + if truncation.z_at_least_quartic: + R += (1 / 2) * ( + np.einsum('i, acj, cijzy -> azy', t_args[(0, 1)], h_args[(0, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acjk, cikzy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, ackz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ack, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, acz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_linear: + R += np.einsum('i, aciz, cy -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + R += (1 / 2) * np.einsum('i, aczy, ci -> azy', t_args[(0, 1)], h_args[(2, 0)], z_args[(1, 0)]) + if truncation.z_at_least_quadratic: + R += np.einsum('i, j, acjz, ciy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + R += (1 / 4) * ( + np.einsum('i, j, aczy, cij -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, j, acij, czy -> azy', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, k, aczy, cijk -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, k, ackz, cijy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, k, acjk, cizy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, k, l, aczy, cijkl -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, k, l, aclz, cijky -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, k, l, ackl, cijzy -> azy', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 3 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbb', rank=3, m=0, n=3) TERMS -------------- # +def add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_quadratic: + R += (1 / 2) * np.einsum('acz, cyx -> azyx', h_args[(1, 0)], z_args[(2, 0)]) + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('aciz, ciyx -> azyx', h_args[(1, 1)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aci, cizyx -> azyx', h_args[(0, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_linear: + R += (1 / 2) * np.einsum('aczy, cx -> azyx', h_args[(2, 0)], z_args[(1, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbb', rank=3, m=0, n=3) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('i, ac, cizyx -> azyx', t_args[(0, 1)], h_args[(0, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 2) * np.einsum('i, acz, ciyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aci, czyx -> azyx', t_args[(0, 1)], h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 2) * np.einsum('i, acjz, cijyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + R += (1 / 4) * np.einsum('i, j, acz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * ( + np.einsum('i, acij, cjzyx -> azyx', t_args[(0, 1)], h_args[(1, 1)], z_args[(4, 0)]) + + np.einsum('i, j, acj, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + ) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_quadratic: + R += (1 / 2) * ( + np.einsum('i, aczy, cix -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + + np.einsum('i, aciz, cyx -> azyx', t_args[(0, 1)], h_args[(2, 0)], z_args[(2, 0)]) + ) + if truncation.z_at_least_cubic: + R += (1 / 12) * np.einsum('i, j, acij, czyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 2) * np.einsum('i, j, acjz, ciyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 4) * np.einsum('i, j, aczy, cijx -> azyx', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 12) * ( + np.einsum('i, j, k, acjk, cizyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + + np.einsum('i, j, k, aczy, cijkx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + ) + R += (1 / 4) * np.einsum('i, j, k, ackz, cijyx -> azyx', t_args[(0, 1)], t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + +# --------------------------------------------------------------------------- # +# ---------------------------- RANK 4 FUNCTIONS ---------------------------- # +# --------------------------------------------------------------------------- # + + +# -------------- operator(name='bbbb', rank=4, m=0, n=4) TERMS -------------- # +def add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) HZ terms. + These terms have no vibrational contribution from the e^T operator. + This reduces the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.z_at_least_cubic: + R += (1 / 6) * np.einsum('acz, cyxw -> azyxw', h_args[(1, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 6) * np.einsum('aciz, ciyxw -> azyxw', h_args[(1, 1)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.z_at_least_quadratic: + R += (1 / 4) * np.einsum('aczy, cxw -> azyxw', h_args[(2, 0)], z_args[(2, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +def add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, opt_einsum): + """ Optimized calculation of the operator(name='bbbb', rank=4, m=0, n=4) eT_HZ terms. + These terms include the vibrational contributions from the e^T operator. + This increases the number of possible non-zero permutations of creation/annihilation operators. + """ + + if ansatz.ground_state: + if truncation.h_at_least_linear: + if truncation.t_singles: + if truncation.z_at_least_quartic: + R += (1 / 24) * np.einsum('i, aci, czyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, acz, ciyxw -> azyxw', t_args[(0, 1)], h_args[(1, 0)], z_args[(4, 0)]) + + if truncation.h_at_least_quadratic: + if truncation.t_singles: + if truncation.z_at_least_cubic: + R += (1 / 4) * np.einsum('i, aczy, cixw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + R += (1 / 6) * np.einsum('i, aciz, cyxw -> azyxw', t_args[(0, 1)], h_args[(2, 0)], z_args[(3, 0)]) + if truncation.z_at_least_quartic: + R += (1 / 48) * np.einsum('i, j, acij, czyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 6) * np.einsum('i, j, acjz, ciyxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + R += (1 / 8) * np.einsum('i, j, aczy, cijxw -> azyxw', t_args[(0, 1)], t_args[(0, 1)], h_args[(2, 0)], z_args[(4, 0)]) + else: + raise Exception('Hot Band amplitudes not implemented!') + + return + + +# --------------------------------------------- RESIDUAL FUNCTIONS --------------------------------------------- # +def compute_m0_n0_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='', rank=0, m=0, n=0) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n0_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n0_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n1_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='b', rank=1, m=0, n=1) amplitude.""" + truncation.confirm_at_least_singles() + + # the residual tensor + R = np.zeros(shape=(A, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n1_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n1_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n2_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bb', rank=2, m=0, n=2) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + + # the residual tensor + R = np.zeros(shape=(A, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n2_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n2_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n3_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbb', rank=3, m=0, n=3) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n3_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n3_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +def compute_m0_n4_amplitude_optimized(A, N, ansatz, truncation, t_args, h_args, z_args, opt_paths): + """Compute the operator(name='bbbb', rank=4, m=0, n=4) amplitude.""" + truncation.confirm_at_least_singles() + truncation.confirm_at_least_doubles() + truncation.confirm_at_least_triples() + truncation.confirm_at_least_quadruples() + + # the residual tensor + R = np.zeros(shape=(A, N, N, N, N), dtype=complex) + + # unpack the optimized paths + optimized_HZ_paths, optimized_eT_HZ_paths = opt_paths + + # add the terms + add_m0_n4_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_HZ_paths) + add_m0_n4_eT_HZ_terms_optimized(R, ansatz, truncation, t_args, h_args, z_args, optimized_eT_HZ_paths) + return R + + +# --------------------------------------------- OPTIMIZED PATHS FUNCTION --------------------------------------------- # \ No newline at end of file diff --git a/tests/deep/files/test_latex_eT_zhz/latex_Test_run_main_et_zhz_LHS.tex b/tests/deep/files/test_latex_eT_zhz/latex_Test_run_main_et_zhz_LHS.tex new file mode 100644 index 0000000..b4c226c --- /dev/null +++ b/tests/deep/files/test_latex_eT_zhz/latex_Test_run_main_et_zhz_LHS.tex @@ -0,0 +1,201 @@ + +\documentclass{article} + +\usepackage[T1]{fontenc} +\usepackage{geometry} +\usepackage{natbib} +\usepackage{graphicx} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{bm} +\usepackage{physics} +\usepackage{simplewick} +\usepackage{dsfont} + +\usepackage{color} +\NewDocumentCommand{\disconnected}{G{}}{\colorbox{yellow}{$#1$}} +\NewDocumentCommand{\red}{G{}}{{\color{red}#1}} +\NewDocumentCommand{\blue}{G{}}{{\color{blue}#1}} +\NewDocumentCommand{\magenta}{G{}}{{\color{magenta}#1}} + +%\geometry{portrait, left=0.4in, right=0.4in, top=0.25in, bottom=0.5in} +\geometry{a4paper, left=0.4in, right=0.4in, top=0.25in, bottom=0.5in} +%\geometry{legalpaper, landscape, left=0.4in, right=0.4in, top=0.25in, bottom=0.5in} + +\newcommand{\bh}{\textbf{h}} +\newcommand{\bt}{\textbf{t}} +\newcommand{\bw}{\textbf{w}} +\newcommand{\bc}{\textbf{c}} +\newcommand{\bd}{\textbf{d}} + +\newcommand{\bs}{\textbf{s}} +\newcommand{\bz}{\textbf{z}} +\newcommand{\bS}{\hat{\textbf{S}}_{\gamma}} +\newcommand{\bZ}{\hat{\textbf{Z}}_{\gamma}} +\newcommand{\ebS}{e^{\bS}} +\newcommand{\ebZ}{e^{\bZ}} +\newcommand{\g}{\hat{g}_{\gamma}} +\newcommand{\bg}{\hat{\textbf{g}}_{\gamma}} +\newcommand{\bG}{\textbf{G}} + +\newcommand{\up}[1]{\hat{#1}^{\dagger}} +\newcommand{\down}[1]{\hat{#1}} + +\begin{document} + + +% +% +% +% +\section{Automated equations} +All equations are derived assuming a Hamiltonian, $\hat{S}$ and $\hat{Z}$ of the form: +\begin{equation} + \hat{H} = \sum_{a,b} \ket{a}\bra{b}h^{a}_{b}(q) +\qquad\qquad + \hat{S} = \sum_{c,d} \ket{c}\bra{d}s^{c}_{d}(q) +\qquad\qquad + \hat{Z} = \sum_{e>f} \ket{e}\bra{f}z^{e}_{f}(q) +\qquad\qquad + \hat{\Omega} = \down{i} + \up{i} + \down{i}\down{j} + \down{i}\up{j} + \up{i}\up{j} + \cdots +\end{equation} +when we limit ourselves to at most 2nd order terms (creation operator: $\down{b}$, annihilation operator: $\up{b}$) +\begin{equation} + \bh(q) = \bh + \bh_{i}\down{i} + \bh^{i}\up{i} + \bh^{i}_{j}\up{i}\down{j} + \frac{1}{2}\bh_{ij}\down{i}\down{j} + \frac{1}{2}\bh^{ij}\up{i}\up{j} +\end{equation} +\begin{equation} + \bs(q) = \bs_{0} + \bs^{i}\up{i} + \frac{1}{2}\bs^{ij}\up{i}\up{j} +\end{equation} +\begin{equation} + \bz(q) = \bz_{0} + \bz^{i}\up{i} + \frac{1}{2}\bz^{ij}\up{i}\up{j} +\end{equation} + +Define the following: (not correct but mechanically useful) +\begin{equation} + f = \contraction[1ex]{}{\up{b}}{}{\down{b}}\up{b}\down{b} +\qquad + \bar{f} = \contraction[1ex]{}{\down{b}}{}{\up{b}}\down{b}\up{b} +\qquad + ( + \contraction[1ex]{}{\down{b}}{}{\up{b}}\down{b}\up{b} + - + \contraction[1ex]{}{\up{b}}{}{\down{b}}\up{b}\down{b} + ) + = (\bar{f} - f) = 1 +\qquad + \bar{f} = 1, f = 0 +\end{equation} +and +\begin{equation} + \bt_{i} \equiv f\bs_{i} +\qquad + \bt^{i} \equiv \bar{f}\bs^{i} +\qquad + \bt^{i}_{j} \equiv \bar{f}f\bs^{i}_{j} +\qquad + \bt^{ij} \equiv \bar{f}^2\bs^{ij} +\qquad + \bt_{ij} \equiv f^2\bs_{ij} +\qquad + \text{and so forth ....} +\end{equation} + + +The ansatz equation +\begin{equation} + \ket{\psi_{\gamma}(\tau)} + = e^{i\hat{H}\tau}\ket{\gamma,0} +% + \approx e^{\hat{S}_{\gamma}}e^{\hat{Z}_{\gamma}}\ket{\gamma,0} +% + = e^{\hat{S}_{\gamma}}(\hat{1}+\hat{Z})\ket{\gamma,0} +\end{equation} +\begin{equation} + \ket{\Psi(\tau)} = \sum_{\gamma}\bm{\chi}_\gamma\ket{\psi_{\gamma}(\tau)} + % \quad (\bm{\chi} \text{ is a vector which is A dimensionality}) +\end{equation} + +The new amplitude equation is +\begin{align} + LHS &= RHS +\\ + (\hat{1} - \hat{Z}_{\gamma})\left(i\dv{\hat{S}_{\gamma}}{\tau}\right)(\hat{1} + \hat{Z}_{\gamma}) + &= (\hat{1} - \hat{Z}_{\gamma})e^{-\hat{S}_{\gamma}}\hat{H}e^{\hat{S}_{\gamma}}(\hat{1} + \hat{Z}_{\gamma}) +% +\\ &= (\hat{1} - \hat{Z}_{\gamma})\bar{H}_{\gamma}(\hat{1} + \hat{Z}_{\gamma}) +\\ &= \hat{G} +\end{align} + +where +\begin{align} + i\dv{\hat{S}_{\gamma}}{\tau} = \left(\bar{H} + \bar{H}\hat{Z}\right)_{\gamma\gamma} = \hat{G}_{\gamma\gamma} +\end{align} + +and + +\begin{align} + i\dv{\hat{Z}_{x\gamma}}{\tau} = \left(\bar{H} + \bar{H}\hat{Z}\right)_{x\gamma} - i\dv{\hat{S}_{\gamma}}{\tau}\hat{Z}_{x\gamma} +\end{align} + +\clearpage +% +% +% +% +% +% + + +\vspace{2cm}% +% +% +% +% + +\begin{equation} + \hat{\Omega} = 1 +\qquad\qquad + i\dv{\hat{\bt}^{}_{\gamma}}{\tau} = \hat{G}^{}_{\gamma\gamma} +\end{equation} + +% +% +% +% +% + +\begin{align}\begin{split} +LHS &= +% +% +\\&+\sum\Big((\mathds{1}\mathds1\left(i\dv{\bz_0}{\tau}\right) + \bar{f}\bs_{\magenta{}\blue{}\magenta{k}\red{}}\mathds1\left(i\dv{\bz^{\magenta{k}\red{}}}{\tau}\right) + \bar{f}\bs_{\magenta{}\blue{k}\magenta{}\red{}}\left(i\dv{\bt^{\blue{k}\blue{}\red{}}}{\tau}\right)\bz_0)\Big) +\end{split}\end{align} + +\paragraph{Linear Equations} + +% +% +% +% +% + +\begin{equation} + \hat{\Omega} = \down{i} +\qquad\qquad + i\dv{\hat{\bt}^{i}_{\gamma}}{\tau} = \hat{G}^{i}_{\gamma\gamma} +\end{equation} + +% +% +% +% +% + +\begin{align}\begin{split} +LHS &= +% +% +\\&+\sum\Big((\mathds{1}\mathds1\left(i\dv{\bz^{\red{y}}}{\tau}\right) + \mathds{1}\left(i\dv{\bt^{\blue{}\red{y}}}{\tau}\right)\bz_0 + \bar{f}\bs_{\magenta{}\blue{}\magenta{k}\red{}}\left(i\dv{\bt^{\blue{}\blue{}\red{y}}}{\tau}\right)\bz^{\magenta{k}\red{}} + \bar{f}\bs_{\magenta{}\blue{k}\magenta{}\red{}}\left(i\dv{\bt^{\blue{k}\blue{}\red{}}}{\tau}\right)\bz^{\magenta{}\red{y}})\Big) +\end{split}\end{align} + +\end{document} \ No newline at end of file diff --git a/tests/deep/test_code_eT_zhz.py b/tests/deep/test_code_eT_zhz.py index bd0d0b7..3ba7b81 100644 --- a/tests/deep/test_code_eT_zhz.py +++ b/tests/deep/test_code_eT_zhz.py @@ -3,12 +3,22 @@ # system imports # from logging import exception -from os.path import abspath, dirname, join +from os.path import abspath, dirname, join, basename import pytest # local imports from truncation_keys import TruncationsKeys as tkeys -from code_eT_zhz import generate_eT_zhz_python +from latex_eT_zhz import _filter_out_valid_eTz_terms +from code_eT_zhz import ( + generate_eT_zhz_python, + _simplify_eT_zhz_python_prefactor, + _write_third_eTz_einsum_python, + # + generate_eT_taylor_expansion, + generate_pruned_H_operator, + generate_omega_operator, + generate_z_operator, +) # set the path (`root_dir`) to the files we need to compare against deep_dir = dirname(abspath(__file__)) @@ -16,30 +26,59 @@ classtest = 'test_code_eT_zhz' -def _gen_wrapper_eT_zhz_python(truncations, tmpdir, **kwargs): - # the 's_taylor_max_order' isn't releveant for this execution pathway +class Test_simplify_eT_zhz_python_prefactor(): - # f_term_string = "_no_f_terms" if kwargs['remove_f_terms'] else '' - # gs_string = "ground_state_" if kwargs['only_ground_state'] else '' - # path = f"./{gs_string}eT_zhz_equations{f_term_string}.py" + def test_disjoint(self): + """basic test""" - # temporary naming scheme until a better one can be designed - # also hot band equation generation has not been implemented anyways + # input data + numerator_list = ['1', '2', '3'] + denominator_list = ['4', '5', '6'] - path = ( - "eT_zhz_eqs" - f"_{kwargs['lhs_rhs']}" - f"_H({truncations[tkeys.H]})" - f"_P({truncations[tkeys.P]})" - f"_T({truncations[tkeys.T]})" - f"_exp({truncations[tkeys.eT]})" - f"_Z({truncations[tkeys.CC]})" - ".py" - ) - output_path = join(tmpdir, path) - kwargs['path'] = output_path + # run function + function_output = _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list) + expected_result = (['1', '2', '3'], ['4', '5', '6']) - generate_eT_zhz_python(truncations, **kwargs) + assert function_output == expected_result + + def test_duplicate_prefactors(self): + """basic test""" + + # a > b + + # input data + numerator_list = ['1', '2', '2'] + denominator_list = ['2'] + + # run function + function_output = _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list) + expected_result = (['1', '2'], []) + + assert function_output == expected_result + + # a < b + + # input data + numerator_list = ['1', '2'] + denominator_list = ['2', '2', '2'] + + # run function + function_output = _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list) + expected_result = (['1'], ['2', '2']) + + assert function_output == expected_result + + # a == b + + # input data + numerator_list = ['1'] + denominator_list = ['1', '2'] + + # run function + function_output = _simplify_eT_zhz_python_prefactor(numerator_list, denominator_list) + expected_result = ([], ['2']) + + assert function_output == expected_result class Test_lhs_gen(): @@ -64,8 +103,12 @@ def D(self, request): def E(self, request): return request.param + @pytest.fixture(scope="class", params=['LHS', 'RHS']) + def left_right_switch(self, request): + return request.param + @pytest.fixture(scope="class") - def truncations(self, A, B, C, D, E): + def trunc(self, A, B, C, D, E): eT_trunc = { tkeys.H: A, tkeys.CC: B, @@ -75,18 +118,17 @@ def truncations(self, A, B, C, D, E): } return eT_trunc - def test_mass_gen(self, tmpdir, truncations): + def gen_path(self, truncations, tmpdir, kwargs): + """ defines the path to the file with the python equations""" + + # f_term_string = "_no_f_terms" if kwargs['remove_f_terms'] else '' + # gs_string = "ground_state_" if kwargs['only_ground_state'] else '' + # path = f"./{gs_string}eT_zhz_equations{f_term_string}.py" + # temporary naming scheme until a better one can be designed - _gen_wrapper_eT_zhz_python( - truncations, - tmpdir, - only_ground_state=True, - remove_f_terms=False, - lhs_rhs='LHS' - ) path = ( "eT_zhz_eqs" - f"_LHS" + f"_{kwargs['lhs_rhs']}" f"_H({truncations[tkeys.H]})" f"_P({truncations[tkeys.P]})" f"_T({truncations[tkeys.T]})" @@ -94,14 +136,211 @@ def test_mass_gen(self, tmpdir, truncations): f"_Z({truncations[tkeys.CC]})" ".py" ) - output_path = join(tmpdir, path) + + return join(tmpdir, path) + + def test_mass_gen(self, tmpdir, trunc, left_right_switch): + """ Test hthe f """ + + kwargs = { + 'only_ground_state': True, + 'remove_f_terms': False, + 'lhs_rhs': left_right_switch, + } + + output_path = self.gen_path(trunc, tmpdir, kwargs) + + # add to the kwargs + kwargs['path'] = output_path + + # do the hard work of generating all the code + generate_eT_zhz_python(trunc, **kwargs) with open(output_path, 'r') as fp: file_data = fp.read() - file_name = join(root_dir, classtest, path) - print(file_name) + file_name = join(root_dir, classtest, basename(output_path)) + with open(file_name, 'r') as fp: reference_file_data = fp.read() assert file_data == reference_file_data, 'Fail' + + +class Test__write_third_eTz_einsum_python(): + """ The primary purpose here is to run the function + `_write_third_eTz_einsum_python` with the flag + `suppress_empty_if_checks` set to `False. + """ + + @pytest.fixture(scope="class", params=['LHS', 'RHS']) + def lhs_rhs(self, request): + return request.param + + @pytest.fixture(scope="class", params=[1]) + def max_h_rank(self, request): + return request.param + + @pytest.fixture(scope="class", params=[1]) + def max_cc_rank(self, request): + return request.param + + @pytest.fixture(scope="class", params=[1]) + def max_proj_rank(self, request): + return request.param + + @pytest.fixture(scope="class", params=[1]) + def max_T_rank(self, request): + return request.param + + @pytest.fixture(scope="class") + def max_exp_taylor_rank(self): + return 1 + + @pytest.fixture(scope="class", params=[True, False]) + def Pop(self, request, max_cc_rank, max_proj_rank): + return generate_omega_operator(max_cc_rank, max_proj_rank) + + @pytest.fixture(scope="class", params=[True, False]) + def Hop(self, request, max_h_rank): + return generate_pruned_H_operator(max_h_rank) + + @pytest.fixture(scope="class", params=[True, False]) + def Zop(self, request, max_cc_rank): + return generate_z_operator(max_cc_rank, only_ground_state=request.param) + + @pytest.fixture(scope="class", params=[True, False]) + def eTop(self, request, max_T_rank, max_exp_taylor_rank): + return generate_eT_taylor_expansion(max_T_rank, max_exp_taylor_rank) + + @pytest.fixture(scope="class", params=[1, 2]) + def operators(self, Pop, Hop, Zop, eTop): + return (Pop, Hop, Zop, eTop) + + def test_no_suppression(self, operators, lhs_rhs): + """ Simple test to get full coverage, need to redesign later """ + + # for i, Proj in enumerate(operators[0].operator_list): + + t_term_list = [] + + # just pick the highest rank projector + Proj = operators[0].operator_list[-1] + + master_omega, H, Z, eT_taylor_expansion = operators + + # use the simple eT = 1 truncation and only consider HZ but not eTHZ terms + zero_eT_term = operators[-1][0] # only select the first term from eTop + _filter_out_valid_eTz_terms(Proj, zero_eT_term, H, None, Z, t_term_list, lhs_rhs) + + string = _write_third_eTz_einsum_python( + Proj.rank, operators, t_term_list, lhs_rhs, + trunc_obj_name='truncation', b_loop_flag=True, suppress_empty_if_checks=False + ) + + return + + # should be expanded in the future + # def notdone_test_collect_z_contributions(self): + # """ After `collect_z_contributions` is factored out + # this should test the function, specifically the + + # if temp_z_list == []: + # return_array.append(z_header_if_string) + # return_array.append(f"{tabstr}{tab}pass") + + # branch + + # """ + + # @pytest.fixture(scope="function") + # def z_pair(): + # """ x """ + + # def create_hamiltonian_rank_list(Zop, H, master_omega, t_term_list): + # """ + + # The full `hamiltonian_rank_list` is a four-deep nested dict. + # Each element is accessed like so + # hamiltonian_rank_list[max(h.m, h.n)][max_t_rank][z_right.rank][prefactor] + + # For testing purposes we only need the last two layers + # hamiltonian_rank_list[0][0][z_right.rank][prefactor] + + # """ + + # z_rank_list = [] + + # # fill with empty dictionaries + # for i in range(Zop.maximum_rank+1): + + # z_right_kwargs = { + # 'rank': right_z.rank, + # 'm': right_z.m, + # # 'm_lhs': 0, + # # 'm_t': [0, ], + # # 'm_h': 0, + # # 'm_l': 0, + # 'n': right_z.n, + # # 'n_lhs': 0, + # # 'n_t': [0, ], + # # 'n_h': 0, + # # 'n_l': 0, + # } + + # z_right = disconnected_eT_z_right_operator_namedtuple(**z_right_kwargs) + + # z_pair = (None, z_right) + + + # z_rank_list[z] + # z_rank_list.append( + # dict([(i, {}) for i in range(master_omega.maximum_rank+1)]) + # ) + + # for term in t_term_list: + # # unpack + # omega, t_list, h, z_pair, _ = term + + # max_t_rank = max(t.rank for t in t_list) + + # z_left, z_right = z_pair + + # prefactor = '1' + + # # build with permutations + # hamiltonian_rank_list[max(h.m, h.n)].setdefault( + # max_t_rank, {}).setdefault( + # z_right.rank, {}).setdefault( + # prefactor, [] + # ) + + # string = f"np.einsum('acj, cj -> ac', h[(0,1)], z[(1,0)])" + + # # append that string to the current list + # hamiltonian_rank_list[max(h.m, h.n)][max_t_rank][z_right.rank][prefactor].append( + # string + # ) + + + # return hamiltonian_rank_list + + # def test_suppression(self, H, master_omega): + # """ x """ + + # return_array = [] + + # hamiltonian_rank_list = create_hamiltonian_rank_list(H, master_omega) + + # global suppress_empty_if_checks + # suppress_empty_if_checks = False + + # collect_z_contributions(hamiltonian_rank_list, return_array, nof_tabs=0) + + # del suppress_empty_if_checks + + # print(return_array) + + # def test_no_suppression(): + # """ x """ + # pass diff --git a/tests/deep/test_latex_eT_zhz.py b/tests/deep/test_latex_eT_zhz.py index e84f00c..653fa08 100644 --- a/tests/deep/test_latex_eT_zhz.py +++ b/tests/deep/test_latex_eT_zhz.py @@ -2270,3 +2270,40 @@ def test_run_main(self, tmpdir): reference_file_data = fp.read() assert file_data == reference_file_data, 'Fail' + + def test_run_main_LHS(self, tmpdir): + """runs main function and compares it to a reference file""" + + output_path = join(tmpdir, "latex_Test_run_main_et_zhz_LHS.tex") + + eT_trunc = { + tkeys.H: 1, + tkeys.CC: 1, + tkeys.T: 1, + tkeys.eT: 1, + tkeys.P: 1 + } + default_kwargs = { + 'only_ground_state': True, + 'remove_f_terms': False, + 'path': output_path, + 'lhs_rhs': 'LHS', + } + + et.generate_eT_z_t_symmetric_latex( + eT_trunc, + only_ground_state=True, + remove_f_terms=False, + path=output_path, + lhs_rhs='LHS' + ) + + with open(output_path, 'r') as fp: + file_data = fp.read() + + func_name = "latex_Test_run_main_et_zhz_LHS.tex" + file_name = join(root_dir, classtest, func_name) + with open(file_name, 'r') as fp: + reference_file_data = fp.read() + + assert file_data == reference_file_data, 'Fail'