import numpy as np
from colder.core.physics import hamiltonian, hamiltonian_collection
import colder.core.quantum.numpy as cqs
from typing import Tuple, List, Union
[docs]
class interface:
__operator_associations : dict = { 'X' : cqs.operators.X, 'Y' : cqs.operators.Y, 'Z' : cqs.operators.Z }
def __init__(self, nqubits : int, hh : Union[hamiltonian, hamiltonian_collection]):
# store internally the target hamiltonian objects
self.hobjs : list = []
self.nqubits : int = nqubits
self.__core = cqs.quantum_sparse(size = nqubits, local_dim=2)
if isinstance(hh, hamiltonian_collection):
# hamiltonian collections are unwrapped
self.hobjs += hh.terms
elif isinstance(hh, hamiltonian):
# hamiltonian terms are just appended
self.hobjs.append(hh)
else:
raise Exception('unknown input type')
def __compute_hamiltonian(self, hh : hamiltonian) -> np.ndarray:
"""
Compute single hamiltonian term.
Args:
hh (hamiltonian): hamiltonian object
Returns:
np.ndarray: _description_
"""
op_string : str = hh.operator
op_matrices : list = [ self.__operator_associations[ii] for ii in op_string ]
target_coeffs = hh.target_coeffs
if target_coeffs is None: target_coeffs = np.ones(hh.n_terms)
result = 0
for coeff, targ in zip(target_coeffs, hh.targets):
combs : list = [ x for x in zip(op_matrices, targ) ]
sorted_combs = sorted(combs, key = lambda x: x[1])
result += coeff*self.__core.kron_list( [ el[0] for el in sorted_combs ], sites = [ el[1] for el in sorted_combs ] )
return result
[docs]
def compute_timeindependent_hamiltonians(self) -> List[np.ndarray]:
return [ self.__compute_hamiltonian(hh) for hh in self.hobjs ]
[docs]
def compute_timeindependent_hamiltonians_with_coeff(self) -> List[ Tuple[str,np.ndarray] ]:
return [ (hh.coeff, self.__compute_hamiltonian(hh)) for hh in self.hobjs ]
[docs]
def finalize(self, matrix : np.ndarray) -> np.ndarray:
return matrix
[docs]
def COLD_make_hamiltonian(self):
return self.compute_timeindependent_hamiltonians_with_coeff()
[docs]
def COLD_get_finalize_method(self):
finalize = lambda m : m
return finalize