def unmerge(self, cutoff=1e-10): """ Separate the cores in our MergedInput and return an InputRegion The length of the resultant InputRegion will be identical to our original MergedInput (same number of inputs), but its core_len will be doubled (twice as many individual cores) """ bond_str = 'slrij' tensor = self.tensor svd_string = 'lrij->lui,urj' max_D = tensor.size(1) # Split every one of the cores into two and add them both to core_list core_list, bond_list, sv_list = [], [-1], [-1] for merged_core in tensor: sv_vec = torch.empty(max_D) left_core, right_core, bond_dim = svd_flex(merged_core, svd_string, max_D, cutoff, sv_vec=sv_vec) core_list += [left_core, right_core] bond_list += [bond_dim, -1] sv_list += [sv_vec, -1] # Collate the split cores into one tensor and return as an InputRegion tensor = torch.stack(core_list) return [InputRegion(tensor)], bond_list, sv_list
def unmerge(self, cutoff=1e-10): """ Split our MergedOutput into an OutputSite and an InputSite The non-zero entries of our tensors are dynamically sized according to the SVD cutoff, but will generally be padded with zeros to give the new index a regular size. """ bond_str = 'olri' tensor = self.tensor left_output = self.left_output if left_output: svd_string = 'olri->olu,uri' max_D = tensor.size(2) sv_vec = torch.empty(max_D) output_core, input_core, bond_dim = svd_flex(tensor, svd_string, max_D, cutoff, sv_vec=sv_vec) return ([OutputSite(output_core), InputSite(input_core)], [-1, bond_dim, -1], [-1, sv_vec, -1]) else: svd_string = 'olri->our,lui' max_D = tensor.size(1) sv_vec = torch.empty(max_D) output_core, input_core, bond_dim = svd_flex(tensor, svd_string, max_D, cutoff, sv_vec=sv_vec) return ([InputSite(input_core), OutputSite(output_core)], [-1, bond_dim, -1], [-1, sv_vec, -1])