def matrix_element(self, bra, ket): """Calculates a matrix element. Gives matrix for the Qobj sandwiched between a `bra` and `ket` vector. Parameters ----------- bra : qobj Quantum object of type 'bra'. ket : qobj Quantum object of type 'ket'. Returns ------- elem : complex Complex valued matrix element. Raises ------ TypeError Can only calculate matrix elements between a bra and ket quantum object. """ if isoper(self): if isbra(bra) and isket(ket): return (bra.data * self.data * ket.data)[0,0] if isket(bra) and isket(ket): return (bra.data.T * self.data * ket.data)[0,0] raise TypeError("Can only calculate matrix elements for operators and between ket and bra Qobj")
def matrix_element(self, bra, ket): """Calculates a matrix element. Gives matrix for the Qobj sandwiched between a `bra` and `ket` vector. Parameters ----------- bra : qobj Quantum object of type 'bra'. ket : qobj Quantum object of type 'ket'. Returns ------- elem : complex Complex valued matrix element. Raises ------ TypeError Can only calculate matrix elements between a bra and ket quantum object. """ if isoper(self): if isbra(bra) and isket(ket): return (bra.data * self.data * ket.data)[0, 0] if isket(bra) and isket(ket): return (bra.data.T * self.data * ket.data)[0, 0] raise TypeError( "Can only calculate matrix elements for operators and between ket and bra Qobj" )
def transform(self, inpt, inverse=False): """Performs a basis transformation defined by an input array. Input array can be a ``matrix`` defining the transformation, or a ``list`` of kets that defines the new basis. Parameters ---------- inpt : array_like A ``matrix`` or ``list`` of kets defining the transformation. inverse : bool Whether to return inverse transformation. Returns ------- oper : qobj Operator in new basis. Notes ----- This function is still in development. """ if isinstance(inpt, list) or isinstance(inpt, np.ndarray): if len(inpt) != self.shape[0] or len(inpt) != self.shape[1]: raise TypeError('Invalid size of ket list for basis transformation') S = np.matrix([inpt[n].full()[:,0] for n in range(len(inpt))]).H elif isinstance(inpt,np.ndarray): S = np.matrix(inpt) else: raise TypeError('Invalid operand for basis transformation') # normalize S just in case the supplied basis states aren't normalized #S = S/la.norm(S) out=Qobj(type=self.type) out.dims=[self.dims[1],self.dims[0]] out.shape=[self.shape[1],self.shape[0]] out.isherm=self.isherm out.type=self.type # transform data if inverse: if isket(self): out.data = S.H * self.data elif isbra(self): out.data = self.data * S else: out.data = S * self.data * S.H else: if isket(self): out.data = S * self.data elif isbra(self): out.data = self.data * S.H else: out.data = S.H * self.data * S # force sparse out.data = sp.csr_matrix(out.data,dtype=complex) return out
def floquet_markov_mesolve(R, ekets, rho0, tlist, e_ops, options=None): """ Solve the dynamics for the system using the Floquet-Markov master equation. """ if options == None: opt = Odeoptions() else: opt=options if opt.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = ket2dm(rho0) # # prepare output array # n_tsteps = len(tlist) dt = tlist[1]-tlist[0] output = Odedata() output.times = tlist if isinstance(e_ops, FunctionType): n_expt_op = 0 expt_callback = True elif isinstance(e_ops, list): n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: output.states = [] else: output.expect = [] output.num_expect = n_expt_op for op in e_ops: if op.isherm: output.expect.append(np.zeros(n_tsteps)) else: output.expect.append(np.zeros(n_tsteps,dtype=complex)) else: raise TypeError("Expectation parameter must be a list or a function") # # transform the initial density matrix and the e_ops opterators to the # eigenbasis: from computational basis to the floquet basis # if ekets != None: rho0 = rho0.transform(ekets, True) if isinstance(e_ops, list): for n in np.arange(len(e_ops)): # not working e_ops[n] = e_ops[n].transform(ekets) # # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_ode_rhs) r.set_f_params(R.data.data, R.data.indices, R.data.indptr) r.set_integrator('zvode', method=opt.method, order=opt.order, atol=opt.atol, rtol=opt.rtol, max_step=opt.max_step) r.set_initial_value(initial_vector, tlist[0]) # # start evolution # rho = Qobj(rho0) t_idx = 0 for t in tlist: if not r.successful(): break; rho.data = vec2mat(r.y) if expt_callback: # use callback method e_ops(t, Qobj(rho)) else: # calculate all the expectation values, or output rho if no operators if n_expt_op == 0: output.states.append(Qobj(rho)) # copy psi/rho else: for m in range(0, n_expt_op): output.expect[m][t_idx] = expect(e_ops[m], rho) # basis OK? r.integrate(r.t + dt) t_idx += 1 return output
def transform(self, inpt, inverse=False): """Performs a basis transformation defined by an input array. Input array can be a ``matrix`` defining the transformation, or a ``list`` of kets that defines the new basis. Parameters ---------- inpt : array_like A ``matrix`` or ``list`` of kets defining the transformation. inverse : bool Whether to return inverse transformation. Returns ------- oper : qobj Operator in new basis. Notes ----- This function is still in development. """ if isinstance(inpt, list) or isinstance(inpt, np.ndarray): if len(inpt) != self.shape[0] or len(inpt) != self.shape[1]: raise TypeError( 'Invalid size of ket list for basis transformation') S = np.matrix([inpt[n].full()[:, 0] for n in range(len(inpt))]).H elif isinstance(inpt, np.ndarray): S = np.matrix(inpt) else: raise TypeError('Invalid operand for basis transformation') # normalize S just in case the supplied basis states aren't normalized #S = S/la.norm(S) out = Qobj(type=self.type) out.dims = [self.dims[1], self.dims[0]] out.shape = [self.shape[1], self.shape[0]] out.isherm = self.isherm out.type = self.type # transform data if inverse: if isket(self): out.data = S.H * self.data elif isbra(self): out.data = self.data * S else: out.data = S * self.data * S.H else: if isket(self): out.data = S * self.data elif isbra(self): out.data = self.data * S.H else: out.data = S.H * self.data * S # force sparse out.data = sp.csr_matrix(out.data, dtype=complex) return out
def floquet_markov_mesolve(R, ekets, rho0, tlist, e_ops, options=None): """ Solve the dynamics for the system using the Floquet-Markov master equation. """ if options == None: opt = Odeoptions() else: opt = options if opt.tidy: R.tidyup() # # check initial state # if isket(rho0): # Got a wave function as initial state: convert to density matrix. rho0 = ket2dm(rho0) # # prepare output array # n_tsteps = len(tlist) dt = tlist[1] - tlist[0] output = Odedata() output.times = tlist if isinstance(e_ops, FunctionType): n_expt_op = 0 expt_callback = True elif isinstance(e_ops, list): n_expt_op = len(e_ops) expt_callback = False if n_expt_op == 0: output.states = [] else: output.expect = [] output.num_expect = n_expt_op for op in e_ops: if op.isherm: output.expect.append(np.zeros(n_tsteps)) else: output.expect.append(np.zeros(n_tsteps, dtype=complex)) else: raise TypeError("Expectation parameter must be a list or a function") # # transform the initial density matrix and the e_ops opterators to the # eigenbasis: from computational basis to the floquet basis # if ekets != None: rho0 = rho0.transform(ekets, True) if isinstance(e_ops, list): for n in np.arange(len(e_ops)): # not working e_ops[n] = e_ops[n].transform(ekets) # # # setup integrator # initial_vector = mat2vec(rho0.full()) r = scipy.integrate.ode(cyq_ode_rhs) r.set_f_params(R.data.data, R.data.indices, R.data.indptr) r.set_integrator('zvode', method=opt.method, order=opt.order, atol=opt.atol, rtol=opt.rtol, max_step=opt.max_step) r.set_initial_value(initial_vector, tlist[0]) # # start evolution # rho = Qobj(rho0) t_idx = 0 for t in tlist: if not r.successful(): break rho.data = vec2mat(r.y) if expt_callback: # use callback method e_ops(t, Qobj(rho)) else: # calculate all the expectation values, or output rho if no operators if n_expt_op == 0: output.states.append(Qobj(rho)) # copy psi/rho else: for m in range(0, n_expt_op): output.expect[m][t_idx] = expect(e_ops[m], rho) # basis OK? r.integrate(r.t + dt) t_idx += 1 return output