def make_integrator(self, c_op, E, g, H): total_SLH = series_SLH({'S': np.eye(c_op.shape[0], dtype=c_op.dtype), 'L': c_op, 'H': H}, sqz_trunc_osc_src_SLH(self.n_max, E, g)) c_total = total_SLH['L'] H_total = total_SLH['H'] common_dict = self.basis_common_dict.copy() common_dict['C_vector'] = sb.vectorize(c_total, common_dict['basis']) common_dict['H_vector'] = sb.vectorize(H_total, common_dict['basis']) D_c = sb.diffusion_op(**common_dict) F = sb.hamiltonian_op(**common_dict) drift_rep = D_c + F return integ.UncondGaussIntegrator(c_total, 0, 0, H_total, basis=common_dict['basis'], drift_rep=drift_rep)
def integrate_non_herm(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions that may be non hermitian (useful for applications involving the quantum regression theorem). :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(rho, t)) return Solution(ivp_soln.y.T, self.basis)
def integrate(self, rho_0, times, solve_ivp_kwargs=None): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ default_solve_ivp_kwargs = { 'method': 'BDF', 't_eval': times, 'jac': self.jac } process_default_kwargs(solve_ivp_kwargs, default_solve_ivp_kwargs) rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real ivp_soln = solve_ivp(self.a_fn, (times[0], times[-1]), rho_0_vec, **default_solve_ivp_kwargs) return HierarchySolution(ivp_soln.y.T, self.basis, self.d_sys)
def integrate(self, rho_0, times, U1s=None, U2s=None): r"""Integrate the initial value problem. Integrate for a sequence of times with a given initial condition (and optionally specified white noise). Parameters ---------- rho_0: numpy.array The initial state of the system times: numpy.array A sequence of time points for which to solve for rho U1s: numpy.array(len(times) - 1) Samples from a standard-normal distribution used to construct Wiener increments :math:`\Delta W` for each time interval. Multiple rows may be included for independent trajectories. U2s: numpy.array(len(times) - 1) Unused, included to make the argument list uniform with higher-order integrators. Returns ------- Solution The state of :math:`\rho` for all specified times """ rho_0_vec = sb.vectorize(rho_0, self.basis).real if U1s is None: U1s = np.random.randn(len(times) -1) vec_soln = sde.milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, rho_0_vec, times, U1s) return Solution(vec_soln, self.basis)
def integrate_hier_init_cond(self, rho_0_hier, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions, expressed as a full hierarchy density matrix rather than only a system density matrix. Handles non-hermitian initial conditions to facilitate applications involving the quantum regression theorem (this means the vectorized solutions will be complex in general). :param rho_0_hier: The initial state of the system as a matrix :type rho_0_hier: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0_hier, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def integrate_hier_init_cond(self, rho_0_hier, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions, expressed as a full hierarchy density matrix rather than only a system density matrix. Handles non-hermitian initial conditions to facilitate applications involving the quantum regression theorem (this means the vectorized solutions will be complex in general). :param rho_0_hier: The initial state of the system as a matrix :type rho_0_hier: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0_hier, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def integrate(self, rho_0, times, U1s=None, U2s=None): r"""Integrate the initial value problem. Integrate for a sequence of times with a given initial condition (and optionally specified white noise). Parameters ---------- rho_0: numpy.array The initial state of the system times: numpy.array A sequence of time points for which to solve for rho U1s: numpy.array(len(times) - 1) Samples from a standard-normal distribution used to construct Wiener increments :math:`\Delta W` for each time interval. Multiple rows may be included for independent trajectories. U2s: numpy.array(len(times) - 1) Unused, included to make the argument list uniform with higher-order integrators. Returns ------- Solution The state of :math:`\rho` for all specified times """ rho_0_vec = sb.vectorize(rho_0, self.basis).real if U1s is None: U1s = np.random.randn(len(times) - 1) vec_soln = sde.milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, rho_0_vec, times, U1s) return Solution(vec_soln, self.basis)
def check_vectorize(operators, basis): vectorizations = [sb.vectorize(operator, basis) for operator in operators] reconstructions = [sum([coeff*basis_el for coeff, basis_el in zip(vectorization, basis)]) for vectorization in vectorizations] for operator, reconstruction in zip(operators, reconstructions): diff = reconstruction - operator assert_almost_equal(np.trace(np.dot(diff.conj().T, diff)), 0, 7)
def integrate(self, rho_0, times, U1s=None): rho_0_vec = sb.vectorize(np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real if U1s is None: U1s = np.random.randn(len(times) - 1) vec_soln = sde.euler(self.a_fn, self.b_fn, rho_0_vec, times, U1s) return integ.Solution(vec_soln, self.basis)
def integrate(self, rho_0, times, U1s=None): rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real if U1s is None: U1s = np.random.randn(len(times) - 1) vec_soln = sde.euler(self.a_fn, self.b_fn, rho_0_vec, times, U1s) return integ.Solution(vec_soln, self.basis)
def integrate(self, rho_0, times, U1s=None, U2s=None): rho_0_vec = sb.vectorize(rho_0, self.basis).real if U1s is None: U1s = np.random.randn(len(times) -1) vec_soln = sde.faulty_milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, rho_0_vec, times, U1s) return Solution(vec_soln, self.basis)
def check_vectorize(operators, basis): vectorizations = [sb.vectorize(operator, basis) for operator in operators] reconstructions = [sum([coeff*basis_el for coeff, basis_el in zip(vectorization, basis)]) for vectorization in vectorizations] for operator, reconstruction in zip(operators, reconstructions): diff = reconstruction - operator assert_almost_equal(np.trace(np.dot(diff.conj().T, diff)), 0, 7)
def integrate(self, rho_0, times, U1s=None, U2s=None): rho_0_vec = sb.vectorize(rho_0, self.basis).real if U1s is None: U1s = np.random.randn(len(times) - 1) vec_soln = sde.faulty_milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, rho_0_vec, times, U1s) return Solution(vec_soln, self.basis)
def integrate(self, rho_0, times, U1s=None): rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real if U1s is None: U1s = np.random.randn(len(times) - 1) vec_soln = sde.milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, rho_0_vec, times, U1s) return HierarchySolution(vec_soln, self.basis, self.d_sys)
def make_integrator(self, c_op, E, g, H): total_SLH = series_SLH( { 'S': np.eye(c_op.shape[0], dtype=c_op.dtype), 'L': c_op, 'H': H }, sqz_trunc_osc_src_SLH(self.n_max, E, g)) c_total = total_SLH['L'] H_total = total_SLH['H'] common_dict = self.basis_common_dict.copy() common_dict['C_vector'] = sb.vectorize(c_total, common_dict['basis']) common_dict['H_vector'] = sb.vectorize(H_total, common_dict['basis']) D_c = sb.diffusion_op(**common_dict) F = sb.hamiltonian_op(**common_dict) drift_rep = D_c + F return integ.UncondGaussIntegrator(c_total, 0, 0, H_total, basis=common_dict['basis'], drift_rep=drift_rep)
def integrate_tr_dec_no_jump(self, rho_0, times, solve_ivp_kwargs=None): default_solve_ivp_kwargs = { 'method': 'BDF', 't_eval': times, 'jac': self.no_jump_tr_dec_D_fn } process_default_kwargs(solve_ivp_kwargs, default_solve_ivp_kwargs) rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real ivp_soln = solve_ivp(self.no_jump_fn_tr_dec, (times[0], times[-1]), rho_0_vec, **default_solve_ivp_kwargs) return HierarchySolution(ivp_soln.y.T, self.basis, self.d_sys)
def integrate(self, rho_0, times, Us=None, return_meas_rec=False): rho_0_vec = sb.vectorize(np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real if Us is None: Us = np.random.uniform(size=len(times) - 1) vec_soln = sde.jump_euler(self.no_jump_fn, self.Dfun, self.jump_fn, self.jump_rate_fn, rho_0_vec, times, Us, return_dNs=return_meas_rec) if return_meas_rec: vec_soln, dNs = vec_soln return integ.Solution(vec_soln, self.basis), dNs return integ.Solution(vec_soln, self.basis)
def integrate(self, rho_0, times): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0, self.basis).real vec_soln = odeint(self.a_fn, rho_0_vec, times, Dfun=self.Dfun) return Solution(vec_soln, self.basis)
def integrate(self, rho_0, times): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0, self.basis).real vec_soln = odeint(self.a_fn, rho_0_vec, times, Dfun=self.Dfun) return Solution(vec_soln, self.basis)
def integrate(self, rho_0, times, Us=None, return_meas_rec=False): rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real if Us is None: Us = np.random.uniform(size=len(times) - 1) vec_soln = sde.jump_euler(self.no_jump_fn, self.Dfun, self.jump_fn, self.jump_rate_fn, rho_0_vec, times, Us, return_dNs=return_meas_rec) if return_meas_rec: vec_soln, dNs = vec_soln return integ.Solution(vec_soln, self.basis), dNs return integ.Solution(vec_soln, self.basis)
def integrate(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def check_system_builder_double_comm_op(): sx = np.array([[0, 1], [1, 0]], dtype=np.complex) sm = np.array([[0, 0], [1, 0]], dtype=np.complex) Id = np.eye(2, dtype=np.complex) zero = np.zeros((2, 2), dtype=np.complex) r = np.log(2) N = np.sinh(r)**2 M = -np.sinh(r) * np.cosh(r) H = zero c_op = sm c_op_dag = c_op.conjugate().T rho0 = (Id + sx) / 2 integrator = integrate.UncondGaussIntegrator(c_op, M, N, H) rho0_vec = sb.vectorize(rho0, integrator.basis) partial_basis = integrator.basis[:-1] common_dict = sb.op_calc_setup(c_op, M, N, H, partial_basis) E = sb.double_comm_op(**common_dict) vec_double_comm = E @ rho0_vec matrix_double_comm = ((M / 2) * mf.comm(c_op_dag, mf.comm(c_op_dag, rho0)) + (M.conjugate() / 2) * mf.comm(c_op, mf.comm(c_op, rho0))) check_mat_eq(np.einsum('k,kmn->mn', vec_double_comm, integrator.basis), matrix_double_comm)
def integrate(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions. :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize( np.kron(rho_0, np.eye(self.n_max + 1, dtype=np.complex)), self.basis).real ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(t)) return integ.Solution(ivp_soln.y.T, self.basis)
def integrate_non_herm(self, rho_0, times, method='BDF'): r"""Integrate the equation for a list of times with given initial conditions that may be non hermitian (useful for applications involving the quantum regression theorem). :param rho_0: The initial state of the system :type rho_0: `numpy.array` :param times: A sequence of time points for which to solve for rho :type times: `list(real)` :param method: The integration method for `scipy.integrate.solve_ivp` to use. :type method: String :returns: The components of the vecorized :math:`\rho` for all specified times :rtype: `Solution` """ rho_0_vec = sb.vectorize(rho_0, self.basis) ivp_soln = solve_ivp(lambda t, rho: self.a_fn(rho, t), (times[0], times[-1]), rho_0_vec, method=method, t_eval=times, jac=lambda t, rho: self.Dfun(rho, t)) return Solution(ivp_soln.y.T, self.basis)
def integrate_measurements(self, rho_0, times, dMs): r"""Integrate system evolution conditioned on a measurement record. Parameters ---------- rho_0: numpy.array The initial state of the system times: numpy.array A sequence of time points for which to solve for rho dMs: numpy.array(len(times) - 1) Incremental measurement outcomes used to drive the SDE. Returns ------- Solution The components of the vecorized :math:`\rho` for all specified times """ rho_0_vec = sb.vectorize(rho_0, self.basis).real vec_soln = sde.meas_milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, self.dW_fn, rho_0_vec, times, dMs) return Solution(vec_soln, self.basis)
def integrate_measurements(self, rho_0, times, dMs): r"""Integrate system evolution conditioned on a measurement record. Parameters ---------- rho_0: numpy.array The initial state of the system times: numpy.array A sequence of time points for which to solve for rho dMs: numpy.array(len(times) - 1) Incremental measurement outcomes used to drive the SDE. Returns ------- Solution The components of the vecorized :math:`\rho` for all specified times """ rho_0_vec = sb.vectorize(rho_0, self.basis).real vec_soln = sde.meas_milstein(self.a_fn, self.b_fn, self.b_dx_b_fn, self.dW_fn, rho_0_vec, times, dMs) return Solution(vec_soln, self.basis)