def create_sz_sz_operator(self, site1: int, site2: int) -> OperatorSpecification: if site1 == site2: return OperatorSpecification( [self.grid] * self.parameters.L, {f"sz_sz_coeff_{site1}_{site2}": 1.0}, {f"sz_sz_term_{site1}_{site2}": self.grid.get().get_sigma_0()}, f"sz_sz_coeff_{site1}_{site2} | {site1 + 1} sz_sz_term_{site1}_{site2}", ) return OperatorSpecification( [self.grid] * self.parameters.L, {f"sz_sz_coeff_{site1}_{site2}": 1.0}, {f"sz_sz_term_{site1}_{site2}": self.grid.get().get_sigma_z()}, f"sz_sz_coeff_{site1}_{site2} | {site1 + 1} sz_sz_term_{site1}_{site2}| {site2 + 1} sz_sz_term_{site1}_{site2}", )
def create_sx_sx_operator(self, site1: int, site2: int) -> OperatorSpecification: if site1 == site2: return OperatorSpecification( [self.grid] * self.parameters.L, {f"sx_sx_coeff_{site1}_{site2}": 1.0}, {f"sx_sx_term_{site1}_{site2}": self.grid.get().get_sigma_0()}, f"sx_sx_coeff_{site1}_{site2} | {self.dof_map[site1] + 1} sx_sx_term_{site1}_{site2}", ) return OperatorSpecification( [self.grid] * self.parameters.L, {f"sx_sx_coeff_{site1}_{site2}": 1.0}, {f"sx_sx_term_{site1}_{site2}": self.grid.get().get_sigma_x()}, f"sx_sx_coeff_{site1}_{site2} | {self.dof_map[site1] + 1} sx_sx_term_{site1}_{site2}| {self.dof_map[site2] + 1} sx_sx_term_{site1}_{site2}", )
def create_hamiltonian(self) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} L = self.parameters["L"] J0 = self.parameters["J0"] funcname = self.parameters["function"] terms["sx"] = self.grid.get().get_sigma_x() terms["sy"] = self.grid.get().get_sigma_y() if funcname == "uniform": function = lambda n: 1.0 elif funcname == "exponential": function = lambda n: numpy.exp(-n) elif funcname == "gaussian": function = lambda n: numpy.exp(-2 * n * n) else: raise ValueError("Invalid function name") for i in range(L - 1): dof_1 = self.dof_map[i] dof_2 = self.dof_map[i + 1] n = abs(L // 2 - 1 - i) coeffs[f"J_{i}"] = 0.5 * J0 * function(n) table.append(f"J_{i} | {dof_1+1} sx | {dof_2+1} sx") table.append(f"J_{i} | {dof_1+1} sy | {dof_2+1} sy") return OperatorSpecification( [self.grid] * self.parameters.L, coeffs, terms, table, )
def create_sx_operator(self, site: int) -> OperatorSpecification: return OperatorSpecification( [self.grid] * self.parameters.L, {f"sx_coeff_{site}": 1.0}, {f"sx_term_{site}": self.grid.get().get_sigma_x()}, f"sx_coeff_{site} | {site + 1} sx_term_{site}", )
def create_sz_operator(self, site: int) -> OperatorSpecification: return OperatorSpecification( [self.grid] * self.parameters.L, {f"sz_coeff_{site}": 1.0}, {f"sz_term_{site}": self.grid.get().get_sigma_z()}, f"sz_coeff_{site} | {self.dof_map[site] + 1} sz_term_{site}", )
def get_kinetic_operator_1b_B(self) -> OperatorSpecification: return OperatorSpecification( (self.grid_1b,), {"kinetic_coeff_B": -0.5 * self.parameters.mass_B}, {"kinetic_B": self.grid_1b.get_d2()}, "kinetic_coeff_B | 1 kinetic_B", )
def get_kinetic_operator_1b(self) -> OperatorSpecification: return OperatorSpecification( (self.grid_1b, ), {"kinetic_coeff": -0.5}, {"kinetic": self.grid_1b.get_d2()}, "kinetic_coeff | 1 kinetic", )
def create_Sz_operator(self) -> OperatorSpecification: return OperatorSpecification( [self.grid] * self.parameters.L, {f"Sz_coeff": 1.0}, {f"Sz_term": self.grid.get().get_sigma_z()}, [f"Sz_coeff | {site + 1} Sz_term" for site in range(self.parameters["L"])], )
def get_penalty_term(self, penalty: float) -> OperatorSpecification: table: List[str] = ["penalty_coeff_lambda_N^2 | 1 penalty_unity"] for i in range(self.parameters.sites): table.append(f"penalty_coeff_lambda | {i + 1} penalty_n_squared") table.append(f"penalty_coeff_m2_lambda_N | {i + 1} penalty_n") for j in range(i): table.append( "penalty_coeff_2_lambda | {} penalty_n | {} penalty_n". format( i + 1, j + 1, ), ) return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), { "penalty_coeff_2_lambda": 2 * penalty, "penalty_coeff_lambda": penalty, "penalty_coeff_lambda_N^2": penalty * (self.parameters.N**2), "penalty_coeff_m2_lambda_N": -2 * penalty * self.parameters.N, }, { "penalty_n": self.grid.get_x(), "penalty_n_squared": self.grid.get_x()**2, "penalty_unity": self.grid.get().get_unit_operator(), }, table, )
def create_hopping_term(self) -> OperatorSpecification: table: List[str] = [] for i in range(self.parameters.sites - 1): table += [ f"hopping_coeff | {i + 1} modified_creator | {i + 2} annihilator", f"hopping_coeff | {i + 2} creator | {i + 1} modified_annihilator", ] if self.parameters.pbc: table += [ "hopping_coeff | {} modified_creator | {} annihilator".format( self.parameters.sites, 1, ), "hopping_coeff | {} creator | {} modified_annihilator".format( 1, self.parameters.sites, ), ] return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), { "hopping_coeff": -self.parameters.J, }, { "creator": self.grid.get().get_creation_operator(), "annihilator": self.grid.get().get_annihilation_operator(), "modified_creator": self.get_modified_creation_operator(), "modified_annihilator": self.get_modified_annihilation_operator(), }, table, )
def get_position_operator_1b(self) -> OperatorSpecification: return OperatorSpecification( (self.grid_1b, ), {"position_coeff": 1.0}, {"position": self.grid_1b.get_x()}, "position_coeff | 1 position", )
def get_site_occupation_operator(self, site_index: int) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), {"site_occupation_coeff": 1.0}, {"site_occupation": self.grid.get_x()}, f"site_occupation_coeff | {site_index + 1} site_occupation", )
def create_all_down_projector(self) -> OperatorSpecification: return OperatorSpecification( [self.grid] * self.parameters.L, {f"all_down_coeff": 1.0}, {f"all_down_term": self.grid.get().get_projector_down()}, "all_down_coeff " + " ".join(f"| {site+1} all_down_term" for site in range(self.parameters.L)), )
def create_hamiltonian( self, dof_map: dict[tuple[int, int], int], ) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} Lx: int = self.parameters["Lx"] Ly: int = self.parameters["Ly"] rc: float = self.parameters["cutoff_radius"] J: float = self.parameters["J"] alpha: float = self.parameters["alpha"] N = Lx * Ly if self.parameters["J"] != 0.0: terms.update({"sz": self.grid.get().get_sigma_z()}) for (x1, y1) in itertools.product(range(Lx), range(Ly)): i = dof_map[(x1, y1)] for (x2, y2) in itertools.product(range(Lx), range(Ly)): j = dof_map[(x2, y2)] if i <= j: continue dx = x1 - x2 dy = y1 - y2 dist = numpy.sqrt((dx**2) + (dy**2)) if (rc > 0.0) and (dist > rc): continue coupling = -J / (dist**alpha) coeffs.update({f"-J_{i}_{j}": coupling}) table.append(f"-J_{i}_{j} | {i+1} sz | {j+1} sz") if self.parameters["hx"] != 0.0: coeffs.update({"-hx": -self.parameters["hx"]}) terms.update({"sx": self.grid.get().get_sigma_x()}) for i in range(N): table.append(f"-hx | {i+1} sx") if self.parameters["hy"] != 0.0: coeffs.update({"-hy": -self.parameters["hy"]}) terms.update({"sy": self.grid.get().get_sigma_y()}) for i in range(N): table.append(f"-hy | {i+1} sy") if self.parameters["hz"] != 0.0: coeffs.update({"-hz": -self.parameters["hz"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range(N): table.append(f"-hz | {i+1} sz") return OperatorSpecification( [self.grid] * N, coeffs, terms, table, )
def create_Sx_operator(self) -> OperatorSpecification: return OperatorSpecification( [self.grid] * (self.parameters.L**2), {f"Sx_coeff": 1.0}, {f"Sx_term": self.grid.get().get_sigma_x()}, [ f"Sx_coeff | {site + 1} Sx_term" for site in range(self.parameters["L"]**2) ], )
def get_particle_number_operator(self) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), {"particle_number_coeff": 1.0}, {"particle_number": self.grid.get_x()}, [ f"particle_number_coeff | {i + 1} particle_number" for i in range(self.parameters.sites) ], )
def get_site_occupation_operator_squared( self, site_index: int, ) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), {"site_occupation_squared_coeff": 1.0}, {"site_occupation_squared": self.grid.get_x()**2}, "site_occupation_squared_coeff | {} site_occupation_squared". format(site_index + 1, ), )
def create_hamiltonian( self, dof_map: dict[tuple[int, int], int], ) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} L = self.parameters["L"] if self.parameters["Jx"] != 0.0: coeffs.update({"-Jx": -self.parameters["Jx"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for y in range(L): for x in range(L if self.parameters["pbc"] else L - 1): index1 = dof_map[(x, y)] index2 = dof_map[((x + 1) % L, y)] table.append(f"-Jx | {index1 + 1} sz | {index2 + 1} sz") if self.parameters["Jy"] != 0.0: coeffs.update({"-Jy": -self.parameters["Jy"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for y in range(L if self.parameters["pbc"] else L - 1): for x in range(L): index1 = dof_map[(x, y)] index2 = dof_map[(x, (y + 1) % L)] table.append(f"-Jy | {index1 + 1} sz | {index2 + 1} sz") if self.parameters["hx"] != 0.0: coeffs.update({"-hx": -self.parameters["hx"]}) terms.update({"sx": self.grid.get().get_sigma_x()}) for i in range(L**2): table.append(f"-hx | {i+1} sx") if self.parameters["hy"] != 0.0: coeffs.update({"-hy": -self.parameters["hy"]}) terms.update({"sy": self.grid.get().get_sigma_y()}) for i in range(L**2): table.append(f"-hy | {i+1} sy") if self.parameters["hz"] != 0.0: coeffs.update({"-hz": -self.parameters["hz"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range(L**2): table.append(f"-hz | {i+1} sz") return OperatorSpecification( [self.grid] * (self.parameters.L**2), coeffs, terms, table, )
def get_potential_operator_right_1b_B(self) -> OperatorSpecification: return OperatorSpecification( (self.grid_1b, ), {"potential_right_coeff_B": -self.parameters.V0R}, { "potential_right_B": gaussian( self.grid.get_x(), self.parameters.x0R, self.parameters.alpha, ), }, "potential_right_coeff_B | 1 potential_right_B", )
def create_interaction_term(self) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), { "interaction_coeff": self.parameters.U / 2.0, }, { "interaction": self.grid.get_x() * (self.grid.get_x() - 1.0), }, [ f"interaction_coeff | {i + 1} interaction" for i in range(self.parameters.sites) ], )
def get_potential_operator_left_1b_B(self) -> OperatorSpecification: return OperatorSpecification( (self.grid_1b, ), {"potential_left_coeff_A": -self.parameters.V0L}, { "potential_left_A": gaussian( self.grid.get_x(), self.parameters.x0L, 1.0, ), }, "potential_left_coeff_A | 1 potential_left_A", )
def create_hamiltonian( self, dof_map: dict[tuple[int, int], int], ): table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} Lx = self.parameters["Lx"] Ly = self.parameters["Ly"] Rb = self.parameters["Rb"] Rc = self.parameters["Rc"] delta = self.parameters["delta"] if Rb != 0.0: terms.update({"pup": self.grid.get().get_projector_up()}) for y1 in range(Ly): for x1 in range(Lx): i1 = dof_map[(x1, y1)] for y2 in range(Ly): for x2 in range(Lx): i2 = dof_map[(x2, y2)] if i2 >= i1: continue dx = x2 - x1 dy = y2 - y1 r = numpy.sqrt((dx**2) + (dy**2)) if (Rc > 0.0) and (r >= Rc): continue prefactor = 0.5 * ((Rb / r) ** 6) coeffs[f"prefactor_{i1}_{i2}"] = prefactor table.append( f"prefactor_{i1}_{i2} | {i1+1} pup | {i2+1} pup", ) coeffs.update({"0.5": 0.5}) terms.update({"sx": self.grid.get().get_sigma_x()}) for i in range(Lx * Ly): table.append(f"0.5 | {i+1} sx") if delta != 0.0: coeffs.update({"-delta": -delta}) terms.update({"pup": self.grid.get().get_projector_up()}) for i in range(Lx * Ly): table.append(f"-delta | {i+1} pup") return OperatorSpecification([self.grid] * (Lx * Ly), coeffs, terms, table)
def get_site_occupation_pair_operator( self, site_a: int, site_b: int, ) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), {"occupation_pair_coeff": 1.0}, {"site_occupation": self.grid.get_x()}, "occupation_pair_coeff | {} site_occupation | {} site_occupation". format( site_a, site_b, ), )
def get_fake_initial_state_hamiltonian(self) -> OperatorSpecification: n = self.grid.get().npoints mat = numpy.zeros((n, n), dtype=numpy.float64) for i in range(n): mat[i, i] = i return OperatorSpecification( (self.grid, ), { "coeff": 1, }, { "matrix": mat, }, "coeff | 1 matrix", )
def create_hamiltonian(self) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} if self.parameters["J"] != 0.0: terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range( self.parameters.L, ): for j in range(i): if (self.parameters["cutoff_radius"] > 0.0) and ( numpy.abs(i - j) > self.parameters["cutoff_radius"] ): continue coupling = -self.parameters["J"] / ( numpy.abs(i - j) ** self.parameters["alpha"] ) coeffs.update({f"-J_{i}_{j}": coupling}) table.append(f"-J_{i}_{j} | {i+1} sz | {j+1} sz") if self.parameters["hx"] != 0.0: coeffs.update({"-hx": -self.parameters["hx"]}) terms.update({"sx": self.grid.get().get_sigma_x()}) for i in range(self.parameters.L): table.append(f"-hx | {i+1} sx") if self.parameters["hy"] != 0.0: coeffs.update({"-hy": -self.parameters["hy"]}) terms.update({"sy": self.grid.get().get_sigma_y()}) for i in range(self.parameters.L): table.append(f"-hy | {i+1} sy") if self.parameters["hz"] != 0.0: coeffs.update({"-hz": -self.parameters["hz"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range(self.parameters.L): table.append(f"-hz | {i+1} sz") return OperatorSpecification( [self.grid] * self.parameters.L, coeffs, terms, table, )
def create_correlator(self, site_a: int, site_b: int) -> OperatorSpecification: return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), {"correlator_coeff": 1.0}, { "correlator_creator": self.grid.get().get_creation_operator(), "correlator_annihilator": self.grid.get().get_annihilation_operator(), }, "correlator_coeff | {} correlator_creator | {} correlator_annihilator" .format( site_a, site_b, ), )
def create_hamiltonian(self) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} if self.parameters["J"] != 0.0: coeffs.update({"-J": -self.parameters["J"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range( self.parameters.L if self.parameters["pbc"] else self.parameters.L - 1, ): j = (i + 1) % self.parameters.L table.append(f"-J | {i+1} sz | {j+1} sz") if self.parameters["hx"] != 0.0: coeffs.update({"-hx": -self.parameters["hx"]}) terms.update({"sx": self.grid.get().get_sigma_x()}) for i in range(self.parameters.L): table.append(f"-hx | {i+1} sx") if self.parameters["hy"] != 0.0: coeffs.update({"-hy": -self.parameters["hy"]}) terms.update({"sy": self.grid.get().get_sigma_y()}) for i in range(self.parameters.L): table.append(f"-hy | {i+1} sy") if self.parameters["hz"] != 0.0: coeffs.update({"-hz": -self.parameters["hz"]}) terms.update({"sz": self.grid.get().get_sigma_z()}) for i in range(self.parameters.L): table.append(f"-hz | {i+1} sz") return OperatorSpecification( [self.grid] * self.parameters.L, coeffs, terms, table, )
def create_hamiltonian(self) -> OperatorSpecification: table: list[str] = [] coeffs: dict[str, complex] = {} terms: dict[str, ArrayLike] = {} dvr: SpinHalfDvr = self.grid.get() L = self.parameters["L"] prng = numpy.random.Generator( numpy.random.PCG64(self.parameters["seed"])) Jmatrix = numpy.zeros((L, L), dtype=numpy.float64) dist_matrix = numpy.ones((L, L), dtype=numpy.float64) for i in range(L): for j in range(i): Jmatrix[i, j] = prng.uniform( self.parameters["Jmin"], self.parameters["Jmax"], ) Jmatrix[j, i] = Jmatrix[i, j] dist_matrix[i, j] = numpy.abs(i - j) coupling_matrix = Jmatrix / (dist_matrix**self.parameters["alpha"]) terms.update({"s+": dvr.get_sigma_plus(), "s-": dvr.get_sigma_minus()}) for i in range(L): for j in range(i): coeffs.update({f"J_{i}_{j}": coupling_matrix[i, j]}) table.append(f"J_{i}_{j} | {i+1} s+ | {j+1} s-") table.append(f"J_{i}_{j} | {i+1} s- | {j+1} s+") return OperatorSpecification( [self.grid] * self.parameters.L, coeffs, terms, table, )
def get_efficient_penalty_term( self, gamma: float = 10.0, zeta: float = 0.0625, ) -> OperatorSpecification: N = self.parameters.N prefactor_1 = gamma / (zeta**2) * numpy.exp(-zeta * N) prefactor_2 = gamma / (zeta**2) * numpy.exp(zeta * N) constant = -2 * gamma / (zeta**2) term_1 = numpy.exp(zeta * self.grid.get_x()) term_2 = numpy.exp(-zeta * self.grid.get_x()) term_unit = self.grid.get().get_unit_operator() return OperatorSpecification( tuple(self.grid for i in range(self.parameters.sites)), { "penalty_coeff_1": prefactor_1, "penalty_coeff_2": prefactor_2, "penalty_coeff_3": constant, }, { "penalty_1": term_1, "penalty_2": term_2, "penalty_3": term_unit }, [ "penalty_coeff_1 | " + " | ".join(f"{i + 1} penalty_1" for i in range(self.parameters.sites)), "penalty_coeff_2 | " + " | ".join(f"{i + 1} penalty_2" for i in range(self.parameters.sites)), "penalty_coeff_3 | 1 penalty_3", ], )