def test_charge(): "Charge operator" N = 5 M = -np.random.randint(N) ch = charge(N, M) ch_matrix = np.diag(np.arange(M, N + 1)) assert_equal(np.allclose(ch.full(), ch_matrix), True)
def test_charge(): "Charge operator" N = 5 M = - np.random.randint(N) ch = charge(N,M) ch_matrix = np.diag(np.arange(M,N+1)) assert_equal(np.allclose(ch.full(), ch_matrix), True)
def calc_Hc_cb(self): """ Calculate Hc in charge bassis. Returns ------- qp.Qobj """ Hc = self.Ec * qp.charge(self.Nc)**2 return Hc
def test_charge_type(): "Operator CSR Type: charge" op = charge(5) assert_equal(isspmatrix_csr(op.data), True)
#%% N = 10 E_c = 4 * const.e**2 / (abs(complex(Csh.evalf(subs=C_subs))) / 1e15) / const.h / 1e9 Ic_dens = 2e-6 # A / 1 um2, critical current density S = 0.2*0.1 # um2, area of Josephson junction overlapping Ic = Ic_dens * S Fi0 = const.physical_constants['mag. flux quantum'][0] E_j = Fi0 * Ic / (2.0 * const.pi * const.h * 1e9) # GHz E_j = 17 ng = 0.1 print(E_c, E_j) #%% ch_op = qp.charge(N) #ch_vec = qp.Qobj(ch_op.diag()) #%% def H_C(E_c,n_g,N): return E_c*(ch_op - n_g)**2 / 2 #%% def H_J(E_j,N): return -E_j/2*qp.tunneling(2*N+1,1) #%% [markdown] # ## Charge dispersion
def build_momentum_charge(dim, power): op = charge((dim - 1) / 2)**power return op
import auscc as au import qutip as qt import numpy as np import matplotlib.pyplot as plt import sympy as sp from matplotlib import cm N = 128 x = np.linspace(-np.pi, np.pi, N) dx = np.diff(x)[0] Uc = 1 - np.cos(x) Uq, Nq = au.quantize_potential_dft(Uc) Q = qt.charge(Nq[0]) C = 5 H = Q**2 / (2 * C) + Uq E, psi = H.eigenstates() p0 = abs(au.eval_wavefunction(psi[0], x))**2 p1 = abs(au.eval_wavefunction(psi[1], x))**2 p2 = abs(au.eval_wavefunction(psi[2], x))**2 plt.figure() plt.plot(x, Uc, color='k', linestyle='-') plt.plot(x, E[0] * np.ones_like(x), color='k', linestyle='--') plt.plot(x, (E[1] - E[0]) * p0 / (2 * np.max(p0)) + E[0], color='b') plt.plot(x, E[1] * np.ones_like(x), color='k', linestyle='--') plt.plot(x, (E[2] - E[1]) * p1 / (2 * np.max(p1)) + E[1], color='r') plt.plot(x, E[2] * np.ones_like(x), color='k', linestyle='--') plt.plot(x, (E[3] - E[2]) * p2 / (2 * np.max(p2)) + E[2], color='g') plt.plot(x, (2 * E[1] - E[0]) * np.ones_like(x), color='k', linestyle='--', alpha=0.5)
class Transmon: def __init__(self, Ec=0.6, Ej=28, alpha=0.2, d=None, phi=None, gamma_rel=0.0, gamma_phi=0.0, Nc=2, eigspace_N=2, index=0, nonlinear_osc=False): """ Class represents single Tmon. It can calculate its spectrum in charge basis and represent charge operators in its spectral basis. In order to fasten calculations that often require sweep over flux variable, eigenproblem solution is can be obtained on an arbitrary mesh before the extensive calcs take place. These solutions then can be used to sample from (or interpolate from) to get eigenproblem solution faster. Parameters ---------- Ec: float Charge energy of a qubit [GHz] Explicit formula (SI): e^2/(2*C*h)*1e-9, C - capacitance, h - plank constant Ej: float energy of the largest JJ in transmon [GHz] .math I_k \Pni_0 / (2 * pi * h), I_k - junction critical current in SI, \Phi_0 - flux quantum. alpha : float asymmetry parameter. I_k1/I_k2 < 1, ration of lower critical current to the larger one. d: float asymmetry parameter, alternative to `alpha`. `d = (1 - alpha)/(1 + alpha)`. Used in Koch. phi: float flux phase of the transmon in radians (from `0` to `2 pi`). gamma_rel : float longitudal relaxation frequency. For Lindblad operator expressed as `sqrt(gamma_rel/2) \sigma_m`. And lindblad entry is defiened as `2 L p L^+ - {L^+ L,p}`. gamma_phi : float phase relaxation frequency. For lindblad operator expressed as `sqrt(gamma_phi) \sigma_m`. And lindblad entry is defiened as `2 L p L^+ - {L^+ L,p}`. Nc : int Maximum cooper pair number in charge basis (>=0). Charge basis size is `2*Nc + 1`. eigspace_N : int number of eigensystem components with lowest energy that all operators should be restricted onto. index : int index of a transmon. For navigation in a Tmons structures that utilizes `Transmon(...)` instances. nonlinear_osc : bool Not Implemented TODO: ask Gleb, assumed fastened analytical solution for eigensystem, I presume. """ self.Ec = Ec self.Ej = Ej if (d is None) and (alpha is not None): self.d = (1 - alpha) / (alpha + 1) self.alpha = alpha elif (alpha is None) and (d is not None): self.d = d self.alpha = (1 - d) / (1 + d) self.phi = phi self.Nc = Nc self.eigspace_N = eigspace_N # index used if transmons is build into connected strucre self.index = index # dimension of a charge basis self.space_dim = Nc * 2 + 1 self._gamma_rel = gamma_rel self._gamma_phi = gamma_phi self._nonlinear_osc = False if self._nonlinear_osc is True: raise NotImplementedError("`nonlinear_osc=True` not " "implemented yet") self._eigsys_sol_cache: dict[SolKey, TmonEigensystem] = {} def clear_caches(self): self._eigsys_sol_cache = {} ''' GETTERS SECTION START ''' def get_Ns(self): return self.eigspace_N def get_index(self): return self.index ''' GETTERS SECTION END ''' ''' HELP FUNCTIONS SECTION START ''' def _phi_coeff(self, phi): return np.sign(np.cos(phi)) * np.sqrt(1 + self.alpha**2 + 2 * self.alpha * np.cos(phi)) ''' HELP FUNCTIONS SECTION END ''' def calc_Hc_cb(self): """ Calculate Hc in charge bassis. Returns ------- qp.Qobj """ Hc = self.Ec * qp.charge(self.Nc)**2 return Hc def calc_Hj_cb2(self, phi): """ Calculate Josephson energy in charge bassis. phi = pi Flux/Flux_quantum Returns ------- qp.Qobj """ import scipy.stats scipy.stats.norm() scalar = - self.Ej * self._phi_coeff(phi)\ / 2 phi0 = np.arctan(self.d * np.tan(phi)) op = np.exp(-1j * phi0) * raising_op( self.space_dim) + \ np.exp(1j * phi0) * lowering_op(self.space_dim) return scalar * qp.Qobj(op) def calc_Hj_cb(self, phi): """ Calculate Josephson energy in charge bassis. phi = pi Flux/Flux_quantum Returns ------- qp.Qobj """ scalar = - np.sign(np.cos(phi))*self.Ej * \ self._phi_coeff(phi) / 2 op = qp.tunneling(self.space_dim, 1) return scalar * op def calc_Hfull_cb2(self, phi): """ Calculate total Hamiltonian from class parameters Returns ------- qp.Qobj """ return self.calc_Hc_cb() + self.calc_Hj_cb2(phi) def calc_Hfull_cb(self, phi): return self.calc_Hc_cb() + self.calc_Hj_cb(phi) def solve(self, case=1): """ Solve eigensystem problem and return operators in Returns ------- list[TmonEigensystem] Eigensystem solution as a class. `TmonEigensystem` consists of all relevant operators and parameters describing numerical problem in eigenbasis. """ result = [] ctr = False if isinstance(self.phi, np.ndarray): if isinstance(self.phi, list): self.phi = np.array(self.phi, dtype=float) sol_keys = (SolKey(self.Ec, self.Ej, self.alpha, phi, self.Nc) for phi in self.phi) else: sol_keys = (SolKey(self.Ec, self.Ej, self.alpha, self.phi, self.Nc), ) # 1 entry tuple for sol_key in sol_keys: try: solution = self._eigsys_sol_cache[sol_key] result.append(solution) except KeyError: if case == 1: if not ctr: print("case 1") ctr = True H_full = self.calc_Hfull_cb(sol_key.phi) else: if not ctr: print("case 2") ctr = True H_full = self.calc_Hfull_cb2(sol_key.phi) n_full = qp.charge(self.Nc) evals, evecs = H_full.eigenstates(sort="low") # TODO: parallelize H_op = my_transform(H_full, evecs) n_op = my_transform(n_full, evecs) H_op = H_op - H_op[0, 0] * qp.identity(self.space_dim) solution = TmonEigensystem(self.Ec, self.Ej, self.alpha, phi=sol_key.phi, evecs=evecs, H_op=H_op.tidyup(), n_op=n_op.tidyup(), Nc=self.Nc) self._eigsys_sol_cache[sol_key] = solution result.append(solution) if isinstance(self.phi, np.ndarray) and len(self.phi) == 1: return solution else: return result