From f80291d4dd1d1063428ed8be9901ee20d842e973 Mon Sep 17 00:00:00 2001 From: Hao Zhang Date: Fri, 17 Nov 2023 16:48:37 +0800 Subject: [PATCH] port tetragono to support tat v0.4 --- tetragono/tetragono/abstract_state.py | 29 +++++++++---------- tetragono/tetragono/common_tensor/No.py | 20 ++++++++----- .../tetragono/sampling_lattice/lattice.py | 5 +++- .../tetragono/sampling_lattice/observer.py | 9 ++++-- .../tetragono/sampling_lattice/sampling.py | 7 +---- tetragono/tetragono/simple_update_lattice.py | 8 ++--- 6 files changed, 41 insertions(+), 37 deletions(-) diff --git a/tetragono/tetragono/abstract_state.py b/tetragono/tetragono/abstract_state.py index d6badfc0d..c0dc06e65 100644 --- a/tetragono/tetragono/abstract_state.py +++ b/tetragono/tetragono/abstract_state.py @@ -217,7 +217,8 @@ def Edge(self): type The edge type of this abstract state. """ - return self.Tensor.model.Edge + # Get the compat edge constructor. + return self.Tensor.__self__.symmetry.Edge @property def Symmetry(self): @@ -229,7 +230,8 @@ def Symmetry(self): type The symmetry type of this abstract state. """ - return self.Tensor.model.Symmetry + # Group all input into a tuple + return staticmethod(lambda *args: args[0] if args and isinstance(args[0], tuple) else args) def _v2_to_v3_rename(self, state): """ @@ -328,10 +330,8 @@ def _construct_symmetry(self, value): Symmetry The result symmetry object. """ - if isinstance(value, self.Symmetry): - return value - else: - return self.Symmetry(value) + # Symmetry is nothing but a tuple wrapper + return self.Symmetry(value) @property def total_symmetry(self): @@ -367,7 +367,7 @@ def _total_symmetry_edge(self): Edge The result virtual edge. """ - return self.Edge([(-self._total_symmetry, 1)], False) + return self.Edge([(self._total_symmetry, 1)], False).conjugate() def _construct_edge(self, value): """ @@ -383,10 +383,8 @@ def _construct_edge(self, value): Edge The result edge object. """ - if isinstance(value, self.Edge): - return value - else: - return self.Edge(value) + # Edge accept argument with type Edge. So previous condition is not needed. + return self.Edge(value) def _construct_physics_edge(self, edge): """ @@ -444,13 +442,14 @@ def _set_hamiltonian(self, points, tensor): The hamiltonian tensor. """ body = len(points) - if not isinstance(tensor, self.Tensor): - raise TypeError("Wrong hamiltonian type") + # Do not check hamiltonian type temporarily + #if not isinstance(tensor, self.Tensor): + # raise TypeError("Wrong hamiltonian type") if {f"{i}" for i in tensor.names} != {f"{i}{j}" for i in ["I", "O"] for j in range(body)}: raise ValueError("Wrong hamiltonian name") for i in range(body): - edge_out = tensor.edges(f"O{i}") - edge_in = tensor.edges(f"I{i}") + edge_out = tensor.edge_by_name(f"O{i}") + edge_in = tensor.edge_by_name(f"I{i}") if edge_out != self.physics_edges[points[i]]: raise ValueError("Wrong hamiltonian edge") if edge_out.conjugated() != edge_in: diff --git a/tetragono/tetragono/common_tensor/No.py b/tetragono/tetragono/common_tensor/No.py index 9145cfa22..e86417e3c 100644 --- a/tetragono/tetragono/common_tensor/No.py +++ b/tetragono/tetragono/common_tensor/No.py @@ -21,19 +21,23 @@ Tensor = TAT.No.Z.Tensor -identity = Tensor(["I0", "O0"], [2, 2]) -identity.blocks[identity.names] = [[1, 0], [0, 1]] +identity = Tensor(["I0", "O0"], [2, 2]).zero() +identity[{"I0": 0, "O0": 0}] = 1 +identity[{"I0": 1, "O0": 1}] = 1 -pauli_x = Tensor(["I0", "O0"], [2, 2]) -pauli_x.blocks[pauli_x.names] = [[0, 1], [1, 0]] +pauli_x = Tensor(["I0", "O0"], [2, 2]).zero() +pauli_x[{"I0": 0, "O0": 1}] = 1 +pauli_x[{"I0": 1, "O0": 0}] = 1 Sx = pauli_x / 2 -pauli_y = Tensor(["I0", "O0"], [2, 2]) -pauli_y.blocks[pauli_y.names] = [[0, -1j], [1j, 0]] +pauli_y = Tensor(["I0", "O0"], [2, 2]).zero() +pauli_y[{"I0": 0, "O0": 1}] = -1j +pauli_y[{"I0": 1, "O0": 0}] = +1j Sy = pauli_y / 2 -pauli_z = Tensor(["I0", "O0"], [2, 2]) -pauli_z.blocks[pauli_z.names] = [[1, 0], [0, -1]] +pauli_z = Tensor(["I0", "O0"], [2, 2]).zero() +pauli_z[{"I0": 0, "O0": 0}] = +1 +pauli_z[{"I0": 1, "O0": 1}] = -1 Sz = pauli_z / 2 pauli_x_pauli_x = kronecker_product( diff --git a/tetragono/tetragono/sampling_lattice/lattice.py b/tetragono/tetragono/sampling_lattice/lattice.py index 8f1d3b8e4..285ff19ce 100644 --- a/tetragono/tetragono/sampling_lattice/lattice.py +++ b/tetragono/tetragono/sampling_lattice/lattice.py @@ -313,7 +313,10 @@ def _get_shrinker(self, l1l2, configuration): # P side is dimension one edge # Q side is connected to lattice shrinker = self.Tensor(["P", "Q"], [[(symmetry, 1)], edge.conjugated()]).zero() - shrinker[{"Q": (-symmetry, index), "P": (symmetry, 0)}] = 1 + shrinker[{ + "Q": (tuple(sym if isinstace(sym, bool) else -sym for sym in symmetry), index), + "P": (symmetry, 0) + }] = 1 yield orbit, shrinker def _shrink_configuration(self, l1l2, configuration): diff --git a/tetragono/tetragono/sampling_lattice/observer.py b/tetragono/tetragono/sampling_lattice/observer.py index 535357aa5..a472ff196 100644 --- a/tetragono/tetragono/sampling_lattice/observer.py +++ b/tetragono/tetragono/sampling_lattice/observer.py @@ -18,7 +18,8 @@ import os import numpy as np -import PyScalapack +# PyScalapack support should be dropped, I think... +#import PyScalapack from ..utility import (show, showln, allreduce_lattice_buffer, allreduce_buffer, allreduce_number, bcast_buffer, lattice_update, lattice_prod_sum, lattice_conjugate, mpi_rank, mpi_size, mpi_comm, pickle) from ..tensor_element import tensor_element @@ -274,8 +275,10 @@ def add_observer(self, name, observers): if self._start: raise RuntimeError("Cannot enable hole after sampling start") for positions, observer in observers.items(): - if not isinstance(observer, self.owner.Tensor): - raise TypeError("Wrong observer type") + pass + # Do not check the type of observer temporarily + #if not isinstance(observer, self.owner.Tensor): + # raise TypeError("Wrong observer type") self._observer[name] = observers def add_energy(self): diff --git a/tetragono/tetragono/sampling_lattice/sampling.py b/tetragono/tetragono/sampling_lattice/sampling.py index 593261d8d..5a5b86dfe 100644 --- a/tetragono/tetragono/sampling_lattice/sampling.py +++ b/tetragono/tetragono/sampling_lattice/sampling.py @@ -320,12 +320,7 @@ def __call__(self): .transpose(["I", "O"])) hole_edge = hole.edge_by_name("O") # Calculate rho for all the segments of the physics edge of this orbit - rho = [] - for seg in hole_edge.segments: - symmetry, _ = seg - block_rho = hole.blocks[[("I", -symmetry), ("O", symmetry)]] - diag_rho = np.diagonal(block_rho) - rho = [*rho, *diag_rho] + rho = hole.data.diagonal() rho = np.array(rho).real rho = np.maximum(rho, 0) # Sometimes there is some negative value because of numeric error. if np.sum(rho) == 0: diff --git a/tetragono/tetragono/simple_update_lattice.py b/tetragono/tetragono/simple_update_lattice.py index 395085125..43f66986d 100644 --- a/tetragono/tetragono/simple_update_lattice.py +++ b/tetragono/tetragono/simple_update_lattice.py @@ -535,9 +535,9 @@ def _update_virtual_bond(self): for l1, l2 in self.sites(): # Update half of virtual bond, another part will be updated automatically. if l1 != self.L1 - 1: - self.virtual_bond[l1, l2, "D"] = self[l1, l2].edges("D") + self.virtual_bond[l1, l2, "D"] = self[l1, l2].edge_by_name("D") if l2 != self.L2 - 1: - self.virtual_bond[l1, l2, "R"] = self[l1, l2].edges("R") + self.virtual_bond[l1, l2, "R"] = self[l1, l2].edge_by_name("R") def _single_term_simple_update(self, coordinates, index_and_orbit, evolution_operator, new_dimension): """ @@ -629,7 +629,7 @@ def _single_term_simple_update_double_site_nearest_horizontal(self, coordinates, left = self[i, j] right = self[i, j + 1] right = self._try_multiple(right, i, j + 1, "L", division=True) - original_dimension = left.edges("R").dimension + original_dimension = left.edge_by_name("R").dimension left_q, left_r = left.qr("r", {*(f"P{orbit}" for body_index, orbit in left_index_and_orbit), "R"}, "R", "L") right_q, right_r = right.qr("r", {*(f"P{orbit}" for body_index, orbit in right_index_and_orbit), "L"}, "L", "R") u, s, v = ( @@ -697,7 +697,7 @@ def _single_term_simple_update_double_site_nearest_vertical(self, coordinates, i up = self[i, j] down = self[i + 1, j] down = self._try_multiple(down, i + 1, j, "U", division=True) - original_dimension = up.edges("D").dimension + original_dimension = up.edge_by_name("D").dimension up_q, up_r = up.qr("r", {*(f"P{orbit}" for body_index, orbit in up_index_and_orbit), "D"}, "D", "U") down_q, down_r = down.qr("r", {*(f"P{orbit}" for body_index, orbit in down_index_and_orbit), "U"}, "U", "D") u, s, v = (