Beispiel #1
0
def _mesolve_QobjEvo(H, c_ops, tlist, args, opt):
    """
    Prepare the system for the solver, H can be an QobjEvo.
    """
    H_td = QobjEvo(H, args, tlist=tlist)
    if not issuper(H_td.cte):
        L_td = liouvillian(H_td)
    else:
        L_td = H_td
    for op in c_ops:
        op_td = QobjEvo(op, args, tlist=tlist)
        if not issuper(op_td.cte):
            op_td = lindblad_dissipator(op_td)
        L_td += op_td

    if opt.rhs_with_state:
        L_td._check_old_with_state()

    nthread = opt.openmp_threads if opt.use_openmp else 0
    L_td.compile(omp=nthread)

    ss = SolverSystem()
    ss.H = L_td
    ss.makefunc = _qobjevo_set
    solver_safe["mesolve"] = ss
    return ss
Beispiel #2
0
def _generate_A_ops_Euler(sc, L, dt):
	"""
	combine precomputed operators in one long operator for the Euler method
	"""
	A_len = len(sc)
	out = []
	out += [spre(c).data + spost(c.dag()).data for c in sc]
	out += [(L + np.sum([lindblad_dissipator(c, data_only=True) for c in sc], axis=0))*dt]
	out1 = [[sp.vstack(out).tocsr(), sc[0].shape[0]]]
	#the following hack is required for compatibility with old A_ops
	out1 += [[] for n in xrange(A_len-1)]
	return out1
Beispiel #3
0
 def test_lindblad_dissipator_td(self):
     "Superoperator: lindblad_dissipator, time-dependent"
     assert_(lindblad_dissipator(self.t2)(.5) ==
             lindblad_dissipator(self.t2(.5)))
     assert_(lindblad_dissipator(self.t2, self.q1)(.5) ==
             lindblad_dissipator(self.t2(.5), self.q1))
     assert_(lindblad_dissipator(self.q1, self.t2)(.5) ==
             lindblad_dissipator(self.q1, self.t2(.5)))
Beispiel #4
0
 def test_lindblad_dissipator_td(self):
     "Superoperator: lindblad_dissipator, time-dependent"
     assert_(lindblad_dissipator(self.t2)(.5) ==
             lindblad_dissipator(self.t2(.5)))
     assert_(lindblad_dissipator(self.t2, self.q1)(.5) ==
             lindblad_dissipator(self.t2(.5), self.q1))
     assert_(lindblad_dissipator(self.q1, self.t2)(.5) ==
             lindblad_dissipator(self.q1, self.t2(.5)))
Beispiel #5
0
def _generate_rho_A_ops(sc, L, dt):
    """
    pre-compute superoperator operator combinations that are commonly needed
    when evaluating the RHS of stochastic master equations
    """
    out = []
    for c_idx, c in enumerate(sc):
        n = c.dag() * c
        out.append([spre(c).data, spost(c).data,
                    spre(c.dag()).data, spost(c.dag()).data,
                    spre(n).data, spost(n).data, (spre(c) * spost(c.dag())).data,
                    lindblad_dissipator(c, data_only=True)])

    return out
Beispiel #6
0
def _generate_A_ops_Milstein(sc, L, dt):
	"""
	combine precomputed operators in one long operator for the Milstein method
	with commuting stochastic jump operators.
	"""
	A_len = len(sc)
	temp = [spre(c).data + spost(c.dag()).data for c in sc]
	out = []
	out += temp
	out += [temp[n]*temp[n] for n in xrange(A_len)]
	out += [temp[n]*temp[m] for (n,m) in np.ndindex(A_len,A_len) if n > m]
	out += [(L + np.sum([lindblad_dissipator(c, data_only=True) for c in sc], axis=0))*dt]
	out1 = [[sp.vstack(out).tocsr(), sc[0].shape[0]]]
	#the following hack is required for compatibility with old A_ops
	out1 += [[] for n in xrange(A_len-1)]
	return out1
Beispiel #7
0
def _mesolve_func_td(L_func, c_op_list, rho0, tlist, args, opt):
    """
    Evolve the density matrix using an ODE solver with time dependent
    Hamiltonian.
    """
    if type(c_op_list) is list:
        c_ops = []
        for op in c_op_list:
            op_td = QobjEvo(op, args, tlist=tlist, copy=False)
            if not issuper(op_td.cte):
                c_ops += [lindblad_dissipator(op_td)]
            else:
                c_ops += [op_td]
        if c_op_list:
            c_ops_ = [sum(c_ops)]
        else:
            c_ops_ = []
    elif callable(c_op_list):
        c_ops_ = c_op_list

    if opt.rhs_with_state:
        state0 = rho0.full().ravel("F")
        obj = L_func(0., state0, args)
        if not issuper(obj):
            L_func = _LiouvillianFromFunc(L_func, c_ops_).H2L_with_state
        else:
            L_func = _LiouvillianFromFunc(L_func, c_ops_).L_with_state
    else:
        obj = L_func(0., args)
        if callable(c_ops_):
            if not issuper(obj):
                L_func = _LiouvillianFromFunc(L_func, c_ops_).H2L_c
            else:
                L_func = _LiouvillianFromFunc(L_func, c_ops_).L_c
        else:
            if not issuper(obj):
                L_func = _LiouvillianFromFunc(L_func, c_ops_).H2L
            else:
                L_func = _LiouvillianFromFunc(L_func, c_ops_).L

    ss = SolverSystem()
    ss.L = L_func
    ss.makefunc = _Lfunc_set
    solver_safe["mesolve"] = ss
    return ss
Beispiel #8
0
def _mesolve_func_td(L_func, c_op_list, rho0, tlist, args, opt):
    """
    Evolve the density matrix using an ODE solver with time dependent
    Hamiltonian.
    """
    c_ops = []
    for op in c_op_list:
        td = QobjEvo(op, args, tlist=tlist, copy=False)
        c_ops.append(td if td.cte.issuper else lindblad_dissipator(td))
    c_ops_ = [sum(c_ops)] if c_op_list else []
    L_api = _LiouvillianFromFunc(L_func, c_ops_, rho0.dims)
    if opt.rhs_with_state:
        obj = L_func(0., rho0.full().ravel("F"), args)
        L_func = L_api.L_with_state if issuper(obj) else L_api.H2L_with_state
    else:
        obj = L_func(0., args)
        L_func = L_api.L if issuper(obj) else L_api.H2L
    ss = SolverSystem()
    ss.L = L_func
    ss.makefunc = _Lfunc_set
    solver_safe["mesolve"] = ss
    return ss
Beispiel #9
0
def _mesolve_QobjEvo(H, c_ops, tlist, args, opt):
    """
    Prepare the system for the solver, H can be an QobjEvo.
    """
    H_td = QobjEvo(H, args, tlist=tlist)
    if not issuper(H_td.cte):
        L_td = liouvillian(H_td)
    else:
        L_td = H_td
    for op in c_ops:
        # We want to avoid passing tlist where it isn't necessary, to allow a
        # Hamiltonian/Liouvillian which already _has_ time-dependence not equal
        # to the mesolve evaluation times to be used in conjunction with
        # time-independent c_ops.  If we _always_ pass it, it may appear to
        # QobjEvo that there is a tlist mismatch, even though it is not used.
        if isinstance(op, Qobj):
            op_td = QobjEvo(op)
        elif isinstance(op, QobjEvo):
            op_td = QobjEvo(op, args)
        else:
            op_td = QobjEvo(op, args, tlist=tlist)
        if not issuper(op_td.cte):
            op_td = lindblad_dissipator(op_td)
        L_td += op_td

    if opt.rhs_with_state:
        L_td._check_old_with_state()

    nthread = opt.openmp_threads if opt.use_openmp else 0
    L_td.compile(omp=nthread)

    ss = SolverSystem()
    ss.H = L_td
    ss.makefunc = _qobjevo_set
    solver_safe["mesolve"] = ss
    return ss
Beispiel #10
0
def smesolve_generic(ssdata, options, progress_bar):
    """
    internal

    .. note::

        Experimental.

    """
    if debug:
        print(inspect.stack()[0][3])

    N_store = len(ssdata.tlist)
    N_substeps = ssdata.nsubsteps
    N = N_store * N_substeps
    dt = (ssdata.tlist[1] - ssdata.tlist[0]) / N_substeps
    NT = ssdata.ntraj

    data = Odedata()
    data.solver = "smesolve"
    data.times = ssdata.tlist
    data.expect = np.zeros((len(ssdata.e_ops), N_store), dtype=complex)
    data.ss = np.zeros((len(ssdata.e_ops), N_store), dtype=complex)
    data.noise = []
    data.measurement = []

    # pre-compute suporoperator operator combinations that are commonly needed
    # when evaluating the RHS of stochastic master equations
    A_ops = []
    for c_idx, c in enumerate(ssdata.sc_ops):

        n = c.dag() * c
        A_ops.append([spre(c).data, spost(c).data,
                      spre(c.dag()).data, spost(c.dag()).data,
                      spre(n).data, spost(n).data,
                      (spre(c) * spost(c.dag())).data,
                      lindblad_dissipator(c, data_only=True)])

    s_e_ops = [spre(e) for e in ssdata.e_ops]

    # Liouvillian for the deterministic part.
    # needs to be modified for TD systems
    L = liouvillian_fast(ssdata.H, ssdata.c_ops)

    progress_bar.start(ssdata.ntraj)

    for n in range(ssdata.ntraj):
        progress_bar.update(n)

        rho_t = mat2vec(ssdata.state0.full()).ravel()

        noise = ssdata.noise[n] if ssdata.noise else None

        states_list, dW, m = _smesolve_single_trajectory(
            L, dt, ssdata.tlist, N_store, N_substeps,
            rho_t, A_ops, s_e_ops, data, ssdata.rhs,
            ssdata.d1, ssdata.d2, ssdata.d2_len, ssdata.homogeneous,
            ssdata.distribution, ssdata.args,
            store_measurement=ssdata.store_measurement,
            store_states=ssdata.store_states, noise=noise)

        data.states.append(states_list)
        data.noise.append(dW)
        data.measurement.append(m)

    progress_bar.finished()

    # average density matrices
    if options.average_states and np.any(data.states):
        data.states = [sum(state_list).unit() for state_list in data.states]

    # average
    data.expect = data.expect / NT

    # standard error
    if NT > 1:
        data.se = (data.ss - NT * (data.expect ** 2)) / (NT * (NT - 1))
    else:
        data.se = None

    # convert complex data to real if hermitian
    data.expect = [np.real(data.expect[n,:]) if e.isherm else data.expect[n,:]
                   for n, e in enumerate(ssdata.e_ops)]

    return data
Beispiel #11
0
def smesolve_generic(ssdata, options, progress_bar):
    """
    internal

    .. note::

        Experimental.

    """
    if debug:
        print(inspect.stack()[0][3])

    N_store = len(ssdata.tlist)
    N_substeps = ssdata.nsubsteps
    N = N_store * N_substeps
    dt = (ssdata.tlist[1] - ssdata.tlist[0]) / N_substeps
    NT = ssdata.ntraj

    data = Odedata()
    data.solver = "smesolve"
    data.times = ssdata.tlist
    data.expect = np.zeros((len(ssdata.e_ops), N_store), dtype=complex)
    data.ss = np.zeros((len(ssdata.e_ops), N_store), dtype=complex)
    data.noise = []
    data.measurement = []

    # pre-compute suporoperator operator combinations that are commonly needed
    # when evaluating the RHS of stochastic master equations
    A_ops = []
    for c_idx, c in enumerate(ssdata.sc_ops):

        n = c.dag() * c
        A_ops.append([spre(c).data, spost(c).data,
                      spre(c.dag()).data, spost(c.dag()).data,
                      spre(n).data, spost(n).data,
                      (spre(c) * spost(c.dag())).data,
                      lindblad_dissipator(c, data_only=True)])

    s_e_ops = [spre(e) for e in ssdata.e_ops]

    # Liouvillian for the deterministic part.
    # needs to be modified for TD systems
    L = liouvillian_fast(ssdata.H, ssdata.c_ops)

    progress_bar.start(ssdata.ntraj)

    for n in range(ssdata.ntraj):
        progress_bar.update(n)

        rho_t = mat2vec(ssdata.state0.full()).ravel()

        noise = ssdata.noise[n] if ssdata.noise else None

        states_list, dW, m = _smesolve_single_trajectory(
            L, dt, ssdata.tlist, N_store, N_substeps,
            rho_t, A_ops, s_e_ops, data, ssdata.rhs,
            ssdata.d1, ssdata.d2, ssdata.d2_len, ssdata.homogeneous,
            ssdata.distribution, ssdata.args,
            store_measurement=ssdata.store_measurement,
            store_states=ssdata.store_states, noise=noise)

        data.states.append(states_list)
        data.noise.append(dW)
        data.measurement.append(m)

    progress_bar.finished()

    # average density matrices
    if options.average_states and np.any(data.states):
        data.states = [sum(state_list).unit() for state_list in data.states]

    # average
    data.expect = data.expect / NT

    # standard error
    if NT > 1:
        data.se = (data.ss - NT * (data.expect ** 2)) / (NT * (NT - 1))
    else:
        data.se = None

    # convert complex data to real if hermitian
    data.expect = [np.real(data.expect[n,:]) if e.isherm else data.expect[n,:]
                   for n, e in enumerate(ssdata.e_ops)]

    return data