Source code for qDNA.model.tb_basis

from itertools import product
from ast import literal_eval

import numpy as np

# ----------------------------------------------------------------------


[docs] def get_tb_basis(tb_dims): """Generates a symbolic string representation of the indices '(i, j)' where i indicates the strand number and j the site number inside the strand. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. Returns ------- list List of string representations of site indices. Examples -------- >>> get_tb_basis((2, 2)) ['(0, 0)', '(0, 1)', '(1, 0)', '(1, 1)'] """ num_sites = tb_dims[0] * tb_dims[1] tb_basis = [int_to_str(tb_dims, site_num) for site_num in range(num_sites)] return tb_basis
def str_to_int(tb_dims, tb_basis_str): """Converts a string representation of a site index to an integer representation. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. tb_basis_str: str String representation of the site index. Returns ------- int Integer representation of the site index. Example ------- >>> str_to_int((1,3), '(0, 2)') 2 """ return tuple_to_int(tb_dims, str_to_tuple(tb_basis_str)) def int_to_str(tb_dims, tb_basis_int): """Converts the integer representation of a basis state to the string representation. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. tb_basis_int: int Integer representation of the basis state. Returns ------- str String representation of the basis state. """ return tuple_to_str(int_to_tuple(tb_dims, tb_basis_int)) def str_to_tuple(tb_basis_str): """Converts the string representation of a basis state to the tuple representation. Parameters ---------- tb_basis_str: str String representation of the basis state. Returns ------- tuple Tuple representation of the basis state. """ return literal_eval(tb_basis_str) def tuple_to_str(tb_basis_tuple): """Converts the tuple representation of a basis state to the string representation. Parameters ---------- tb_basis_tuple: tuple Tuple representation of the basis state. Returns ------- str String representation of the basis state. """ return str(tb_basis_tuple) def int_to_tuple(tb_dims, tb_basis_int): """Converts the integer representation of a basis state to the tuple representation. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. tb_basis_int: int Integer representation of the basis state. Returns ------- tuple Tuple representation of the basis state. """ _, num_sites_per_strand = tb_dims return (tb_basis_int // num_sites_per_strand, tb_basis_int % num_sites_per_strand) def tuple_to_int(tb_dims, tb_basis_tuple): """Converts the tuple representation of a basis state to the integer representation. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. tb_basis_tuple: tuple Tuple representation of the basis state. Returns ------- int Integer representation of the basis state. """ _, num_sites_per_strand = tb_dims strand_num, site_in_strand_num = tb_basis_tuple return strand_num * num_sites_per_strand + site_in_strand_num # ----------------------------------------------------------------------
[docs] def get_eh_basis(tb_dims): """Generates a symbolic string representation of electron-hole basis indices. Parameters ---------- tb_dims: tuple A tuple (num_strands, num_sites_per_strand) representing the tight-binding dimensions. Returns ------- list List of tuples representing electron-hole basis indices. Examples -------- >>> get_eh_basis((2, 2)) [('(0, 0)', '(0, 0)'), ('(0, 0)', '(0, 1)'), ('(0, 0)', '(1, 0)'), ('(0, 0)', '(1, 1)'), ('(0, 1)', '(0, 0)'), ('(0, 1)', '(0, 1)'), ('(0, 1)', '(1, 0)'), ('(0, 1)', '(1, 1)'), ('(1, 0)', '(0, 0)'), ('(1, 0)', '(0, 1)'), ('(1, 0)', '(1, 0)'), ('(1, 0)', '(1, 1)'), ('(1, 1)', '(0, 0)'), ('(1, 1)', '(0, 1)'), ('(1, 1)', '(1, 0)'), ('(1, 1)', '(1, 1)')] """ tb_basis = get_tb_basis(tb_dims) eh_basis = list(product(tb_basis, tb_basis)) return eh_basis
[docs] def get_eh_distance(eh_basis): """Calculates the distance between electron and hole for each state in the basis (in multiples of the lattice spacing). Parameters ---------- eh_basis: list List of electron and hole positions as tuples of strings. Returns ------- ndarray Array of distances between electron and hole for each state. Examples -------- >>> get_eh_distance([('(0, 0)', '(1, 1)'), ('(1, 0)', '(0, 0)')]) array([1.41421356, 1. ]) """ distance_list = [] for position_electron, position_hole in eh_basis: position_electron = literal_eval(position_electron) position_hole = literal_eval(position_hole) distance = np.sqrt( sum( (idx_electron - idx_hole) ** 2 for idx_electron, idx_hole in zip(position_electron, position_hole) ) ) distance_list.append(distance) return np.array(distance_list)
[docs] def get_particle_eh_states(particle, tb_basis_element, tb_basis): """Generates a list of electron-hole states for a given particle and site basis element. Parameters ---------- particle: str The type of particle ('electron', 'hole', or 'exciton'). tb_basis_element: str The site basis element for which to generate the states. tb_basis: list The list of all site basis elements. Returns ------- list List of tuples representing the electron-hole states. Examples -------- >>> get_particle_eh_states('electron', '(0, 2)', get_tb_basis((1,3))) [('(0, 2)', '(0, 0)'), ('(0, 2)', '(0, 1)'), ('(0, 2)', '(0, 2)')] """ if tb_basis_element not in tb_basis: raise ValueError( f"Given basis element {tb_basis_element} not in tight-binding basis {tb_basis}" ) if particle == "electron": return list(product([tb_basis_element], tb_basis)) if particle == "hole": return list(product(tb_basis, [tb_basis_element])) if particle == "exciton": return list(product([tb_basis_element], [tb_basis_element])) raise ValueError(f"Invalid particle type: {particle}")
# ----------------------------------------------------------------------
[docs] def basis_change(matrix, states, liouville=False): """Performs a basis change of the given matrix. Parameters ---------- matrix: ndarray The matrix to change basis. states: ndarray The old basis expressed as a vector in the new basis. liouville: bool Set to True for an open quantum system. The matrix must have dimension :math:`N^2` instead of :math:`N`. Returns ------- ndarray Matrix in the new basis. """ if liouville: states = np.kron(states, np.conj(states)) return np.matmul(states, np.matmul(matrix, np.conj(states).T))
[docs] def global_to_local(matrix, eigs, liouville=False): """Performs a basis change from the eigenbasis to the site basis. Parameters ---------- matrix: ndarray The matrix to change basis. eigs: ndarray The eigenbasis (old) expressed in the site basis (new). liouville: bool Set to True for an open quantum system. The matrix must have dimension :math:`N^2` instead of :math:`N`. Returns ------- ndarray Matrix in the site basis. """ return basis_change(matrix, eigs, liouville=liouville)
[docs] def local_to_global(matrix, eigs, liouville=False): """Performs a basis change from the site basis to the eigenbasis. Parameters ---------- matrix: ndarray The matrix to change basis. eigs: ndarray The site basis (old) expressed in the eigenbasis (new). liouville: bool Set to True for an open quantum system. The matrix must have dimension :math:`N^2` instead of :math:`N`. Returns ------- ndarray Matrix in the eigenbasis. """ return basis_change(matrix, np.conj(eigs).T, liouville=liouville)
# ----------------------------------------------------------------------