mirror of
https://github.com/vale981/master-thesis
synced 2025-03-10 05:06:38 -04:00
95 lines
2.4 KiB
Python
95 lines
2.4 KiB
Python
"""A pedadogical exercise implementation of HOPS."""
|
||
import numpy as np
|
||
import numpy.typing as npt
|
||
import typing as t
|
||
import pdb
|
||
import scipy
|
||
|
||
|
||
def make_hops_step(
|
||
η, H_s: np.ndarray, L: np.ndarray, W: complex, k_max: int
|
||
) -> t.Callable[float, np.ndarray]:
|
||
"""Creates the step function for the integration of hops with
|
||
exactly one exponential term.
|
||
|
||
:param η: random process from `stocproc`
|
||
:param H_s: the system hamiltonian
|
||
:param L: the interaction operator
|
||
:param W: the exponent of the BCF
|
||
:param k_max: the depth of the hirarchy
|
||
:returns: the step function for the integration of hops
|
||
"""
|
||
dim = H_s.shape[0]
|
||
|
||
H_si = -1j * H_s
|
||
B = -np.conj(L).T
|
||
K = np.diag(np.arange(0, k_max + 1))
|
||
|
||
def step(t, ψ):
|
||
ψ = ψ.reshape((dim, k_max + 1), order="F")
|
||
|
||
# 1. Apply system H and tho constant contributions
|
||
ψ_1 = H_si @ ψ + W * (ψ @ K) + L @ (ψ * η(t))
|
||
|
||
# 2. Now the shifted orders, we set the truncator to zero
|
||
zeros = np.zeros((1, dim)).T
|
||
ψ_ext = np.hstack((zeros, ψ, zeros))
|
||
|
||
ψ_2 = B @ ψ_ext[:, 0:-2]
|
||
ψ_3 = L @ (ψ_ext[:, 2:] @ K)
|
||
|
||
res = np.array((ψ_1 + ψ_2 + ψ_3)).reshape(((k_max + 1) * dim,), order="F")
|
||
# print(res)
|
||
# __import__("pdb").set_trace()
|
||
return res
|
||
|
||
return step
|
||
|
||
|
||
def integrate_hops_trajectory(
|
||
η,
|
||
H_s: np.ndarray,
|
||
L: np.ndarray,
|
||
W: complex,
|
||
k_max: int,
|
||
ψ_0: np.ndarray,
|
||
τ_max: float,
|
||
seed: t.Optional[int] = None,
|
||
**kwargs
|
||
):
|
||
dim = H_s.shape[0]
|
||
ψ_0_ext = np.concatenate((ψ_0, np.zeros(k_max * dim))) + 0j
|
||
η.new_process(seed=seed)
|
||
step = make_hops_step(η, H_s, L, W, k_max)
|
||
return scipy.integrate.solve_ivp(
|
||
step, (0, τ_max), ψ_0_ext, vectorized=False, dense_output=True, **kwargs
|
||
)
|
||
|
||
|
||
def integrate_hops_ensemble(
|
||
η,
|
||
H_s: np.ndarray,
|
||
L: np.ndarray,
|
||
W: complex,
|
||
k_max: int,
|
||
ψ_0: np.ndarray,
|
||
τ_max: float,
|
||
N: int,
|
||
**kwargs
|
||
):
|
||
dim = H_s.shape[0]
|
||
τ = np.linspace(0, τ_max, 100)
|
||
ρ = np.zeros((100, dim, dim), dtype="complex128")
|
||
|
||
for _ in range(0, N):
|
||
ψ = (
|
||
integrate_hops_trajectory(
|
||
η, H_s, L, W, k_max, ψ_0, τ_max, seed=None, **kwargs
|
||
)
|
||
.sol(τ)[0:2, :]
|
||
.T
|
||
)
|
||
|
||
ρ += ψ[:, :, np.newaxis] * ψ.conj()[:, np.newaxis, :]
|
||
|
||
return τ, ρ / N
|