|
| 1 | +# [Two-time Correlation Functions](@id doc:Two-time-Correlation-Functions) |
| 2 | + |
| 3 | +## Introduction |
| 4 | + |
| 5 | +With the `QuantumToolbox.jl` time-evolution function [`mesolve`](@ref), a state vector ([`Ket`](@ref)) or density matrix ([`Operator`](@ref)) can be evolved from an initial state at ``t_0`` to an arbitrary time ``t``, namely |
| 6 | + |
| 7 | +```math |
| 8 | +\hat{\rho}(t) = \mathcal{G}(t, t_0)\{\hat{\rho}(t_0)\}, |
| 9 | +``` |
| 10 | +where ``\mathcal{G}(t, t_0)\{\cdot\}`` is the propagator defined by the equation of motion. The resulting density matrix can then be used to evaluate the expectation values of arbitrary combinations of same-time operators. |
| 11 | + |
| 12 | +To calculate two-time correlation functions on the form ``\left\langle \hat{A}(t+\tau) \hat{B}(t) \right\rangle``, we can use the quantum regression theorem [see, e.g., [Gardiner-Zoller2004](@cite)] to write |
| 13 | + |
| 14 | +```math |
| 15 | +\left\langle \hat{A}(t+\tau) \hat{B}(t) \right\rangle = \textrm{Tr} \left[\hat{A} \mathcal{G}(t+\tau, t)\{\hat{B}\hat{\rho}(t)\} \right] = \textrm{Tr} \left[\hat{A} \mathcal{G}(t+\tau, t)\{\hat{B} \mathcal{G}(t, 0)\{\hat{\rho}(0)\}\} \right], |
| 16 | +``` |
| 17 | + |
| 18 | +We therefore first calculate ``\hat{\rho}(t) = \mathcal{G}(t, 0)\{\hat{\rho}(0)\}`` using [`mesolve`](@ref) with ``\hat{\rho}(0)`` as initial state, and then again use [`mesolve`](@ref) to calculate ``\mathcal{G}(t+\tau, t)\{\hat{B}\hat{\rho}(t)\}`` using ``\hat{B}\hat{\rho}(t)`` as initial state. |
| 19 | + |
| 20 | +Note that if the initial state is the steady state, then ``\hat{\rho}(t) = \mathcal{G}(t, 0)\{\hat{\rho}_{\textrm{ss}}\} = \hat{\rho}_{\textrm{ss}}`` and |
| 21 | + |
| 22 | +```math |
| 23 | +\left\langle \hat{A}(t+\tau) \hat{B}(t) \right\rangle = \textrm{Tr} \left[\hat{A} \mathcal{G}(t+\tau, t)\{\hat{B}\hat{\rho}_{\textrm{ss}}\} \right] = \textrm{Tr} \left[\hat{A} \mathcal{G}(\tau, 0)\{\hat{B} \hat{\rho}_{\textrm{ss}}\} \right] = \left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle, |
| 24 | +``` |
| 25 | +which is independent of ``t``, so that we only have one time coordinate ``\tau``. |
| 26 | + |
| 27 | +`QuantumToolbox.jl` provides a family of functions that assists in the process of calculating two-time correlation functions. The available functions and their usage is shown in the table below. |
| 28 | + |
| 29 | +| **Function call** | **Correlation function** | |
| 30 | +|:------------------|:-------------------------| |
| 31 | +| [`correlation_2op_2t`](@ref) | ``\left\langle \hat{A}(t + \tau) \hat{B}(t) \right\rangle`` or ``\left\langle \hat{A}(t) \hat{B}(t + \tau) \right\rangle`` | |
| 32 | +| [`correlation_2op_1t`](@ref) | ``\left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle`` or ``\left\langle \hat{A}(0) \hat{B}(\tau) \right\rangle`` | |
| 33 | +| [`correlation_3op_1t`](@ref) | ``\left\langle \hat{A}(0) \hat{B}(\tau) \hat{C}(0) \right\rangle`` | |
| 34 | +| [`correlation_3op_2t`](@ref) | ``\left\langle \hat{A}(t) \hat{B}(t + \tau) \hat{C}(t) \right\rangle`` | |
| 35 | + |
| 36 | +The most common used case is to calculate the two time correlation function ``\left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle``, which can be done by [`correlation_2op_1t`](@ref). |
| 37 | + |
| 38 | +```@setup correlation_and_spectrum |
| 39 | +using QuantumToolbox |
| 40 | +
|
| 41 | +using CairoMakie |
| 42 | +CairoMakie.enable_only_mime!(MIME"image/svg+xml"()) |
| 43 | +``` |
| 44 | + |
| 45 | +## Steadystate correlation function |
| 46 | + |
| 47 | +The following code demonstrates how to calculate the ``\langle \hat{x}(t) \hat{x}(0)\rangle`` correlation for a leaky cavity with three different relaxation rates ``\gamma``. |
| 48 | + |
| 49 | +```@example correlation_and_spectrum |
| 50 | +tlist = LinRange(0, 10, 200) |
| 51 | +a = destroy(10) |
| 52 | +x = a' + a |
| 53 | +H = a' * a |
| 54 | +
|
| 55 | +# if the initial state is specified as `nothing`, the steady state will be calculated and used as the initial state. |
| 56 | +corr1 = correlation_2op_1t(H, nothing, tlist, [sqrt(0.5) * a], x, x) |
| 57 | +corr2 = correlation_2op_1t(H, nothing, tlist, [sqrt(1.0) * a], x, x) |
| 58 | +corr3 = correlation_2op_1t(H, nothing, tlist, [sqrt(2.0) * a], x, x) |
| 59 | +
|
| 60 | +# plot by CairoMakie.jl |
| 61 | +fig = Figure(size = (500, 350)) |
| 62 | +ax = Axis(fig[1, 1], xlabel = L"Time $t$", ylabel = L"\langle \hat{x}(t) \hat{x}(0) \rangle") |
| 63 | +lines!(ax, tlist, real(corr1), label = L"\gamma = 0.5", linestyle = :solid) |
| 64 | +lines!(ax, tlist, real(corr2), label = L"\gamma = 1.0", linestyle = :dash) |
| 65 | +lines!(ax, tlist, real(corr3), label = L"\gamma = 2.0", linestyle = :dashdot) |
| 66 | +
|
| 67 | +axislegend(ax, position = :rt) |
| 68 | +
|
| 69 | +fig |
| 70 | +``` |
| 71 | + |
| 72 | +## Emission spectrum |
| 73 | + |
| 74 | +Given a correlation function ``\left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle``, we can define the corresponding power spectrum as |
| 75 | + |
| 76 | +```math |
| 77 | +S(\omega) = \int_{-\infty}^\infty \left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle e^{-i \omega \tau} d \tau |
| 78 | +``` |
| 79 | + |
| 80 | +In `QuantumToolbox.jl`, we can calculate ``S(\omega)`` using either [`spectrum`](@ref), which provides several solvers to perform the Fourier transform semi-analytically, or we can use the function [`spectrum_correlation_fft`](@ref) to numerically calculate the fast Fourier transform (FFT) of a given correlation data. |
| 81 | + |
| 82 | +The following example demonstrates how these methods can be used to obtain the emission (``\hat{A} = \hat{a}^\dagger`` and ``\hat{B} = \hat{a}``) power spectrum. |
| 83 | + |
| 84 | +```@example correlation_and_spectrum |
| 85 | +N = 4 # number of cavity fock states |
| 86 | +ωc = 1.0 * 2 * π # cavity frequency |
| 87 | +ωa = 1.0 * 2 * π # atom frequency |
| 88 | +g = 0.1 * 2 * π # coupling strength |
| 89 | +κ = 0.75 # cavity dissipation rate |
| 90 | +γ = 0.25 # atom dissipation rate |
| 91 | +
|
| 92 | +# Jaynes-Cummings Hamiltonian |
| 93 | +a = tensor(destroy(N), qeye(2)) |
| 94 | +sm = tensor(qeye(N), destroy(2)) |
| 95 | +H = ωc * a' * a + ωa * sm' * sm + g * (a' * sm + a * sm') |
| 96 | +
|
| 97 | +# collapse operators |
| 98 | +n_th = 0.25 |
| 99 | +c_ops = [ |
| 100 | + sqrt(κ * (1 + n_th)) * a, |
| 101 | + sqrt(κ * n_th) * a', |
| 102 | + sqrt(γ) * sm, |
| 103 | +]; |
| 104 | +
|
| 105 | +# calculate the correlation function using mesolve, and then FFT to obtain the spectrum. |
| 106 | +# Here we need to make sure to evaluate the correlation function for a sufficient long time and |
| 107 | +# sufficiently high sampling rate so that FFT captures all the features in the resulting spectrum. |
| 108 | +tlist = LinRange(0, 100, 5000) |
| 109 | +corr = correlation_2op_1t(H, nothing, tlist, c_ops, a', a; progress_bar = Val(false)) |
| 110 | +ωlist1, spec1 = spectrum_correlation_fft(tlist, corr) |
| 111 | +
|
| 112 | +# calculate the power spectrum using spectrum |
| 113 | +# using Exponential Series (default) method |
| 114 | +ωlist2 = LinRange(0.25, 1.75, 200) * 2 * π |
| 115 | +spec2 = spectrum(H, ωlist2, c_ops, a', a; solver = ExponentialSeries()) |
| 116 | +
|
| 117 | +# calculate the power spectrum using spectrum |
| 118 | +# using Pseudo-Inverse method |
| 119 | +spec3 = spectrum(H, ωlist2, c_ops, a', a; solver = PseudoInverse()) |
| 120 | +
|
| 121 | +# plot by CairoMakie.jl |
| 122 | +fig = Figure(size = (500, 350)) |
| 123 | +ax = Axis(fig[1, 1], title = "Vacuum Rabi splitting", xlabel = "Frequency", ylabel = "Emission power spectrum") |
| 124 | +lines!(ax, ωlist1 / (2 * π), spec1, label = "mesolve + FFT", linestyle = :solid) |
| 125 | +lines!(ax, ωlist2 / (2 * π), spec2, label = "Exponential Series", linestyle = :dash) |
| 126 | +lines!(ax, ωlist2 / (2 * π), spec3, label = "Pseudo-Inverse", linestyle = :dashdot) |
| 127 | +
|
| 128 | +xlims!(ax, ωlist2[1] / (2 * π), ωlist2[end] / (2 * π)) |
| 129 | +axislegend(ax, position = :rt) |
| 130 | +
|
| 131 | +fig |
| 132 | +``` |
| 133 | + |
| 134 | +## Non-steadystate correlation function |
| 135 | + |
| 136 | +More generally, we can also calculate correlation functions of the kind ``\left\langle \hat{A}(t_1 + t_2) \hat{B}(t_1) \right\rangle``, i.e., the correlation function of a system that is not in its steady state. In `QuantumToolbox.jl`, we can evaluate such correlation functions using the function [`correlation_2op_2t`](@ref). The default behavior of this function is to return a matrix with the correlations as a function of the two time coordinates (``t_1`` and ``t_2``). |
| 137 | + |
| 138 | +```@example correlation_and_spectrum |
| 139 | +t1_list = LinRange(0, 10.0, 200) |
| 140 | +t2_list = LinRange(0, 10.0, 200) |
| 141 | +
|
| 142 | +N = 10 |
| 143 | +a = destroy(N) |
| 144 | +x = a' + a |
| 145 | +H = a' * a |
| 146 | +
|
| 147 | +c_ops = [sqrt(0.25) * a] |
| 148 | +
|
| 149 | +α = 2.5 |
| 150 | +ρ0 = coherent_dm(N, α) |
| 151 | +
|
| 152 | +corr = correlation_2op_2t(H, ρ0, t1_list, t2_list, c_ops, x, x; progress_bar = Val(false)) |
| 153 | +
|
| 154 | +# plot by CairoMakie.jl |
| 155 | +fig = Figure(size = (500, 400)) |
| 156 | +
|
| 157 | +ax = Axis(fig[1, 1], title = L"\langle \hat{x}(t_1 + t_2) \hat{x}(t_1) \rangle", xlabel = L"Time $t_1$", ylabel = L"Time $t_2$") |
| 158 | +
|
| 159 | +heatmap!(ax, t1_list, t2_list, real(corr)) |
| 160 | +
|
| 161 | +fig |
| 162 | +``` |
| 163 | + |
| 164 | +### Example: first-order optical coherence function |
| 165 | + |
| 166 | +This example demonstrates how to calculate a correlation function on the form ``\left\langle \hat{A}(\tau) \hat{B}(0) \right\rangle`` for a non-steady initial state. Consider an oscillator that is interacting with a thermal environment. If the oscillator initially is in a coherent state, it will gradually decay to a thermal (incoherent) state. The amount of coherence can be quantified using the first-order optical coherence function |
| 167 | + |
| 168 | +```math |
| 169 | +g^{(1)}(\tau) = \frac{\left\langle \hat{a}^\dagger(\tau) \hat{a}(0) \right\rangle}{\sqrt{\left\langle \hat{a}^\dagger(\tau) \hat{a}(\tau) \right\rangle \left\langle \hat{a}^\dagger(0) \hat{a}(0)\right\rangle}}. |
| 170 | +``` |
| 171 | +For a coherent state ``\vert g^{(1)}(\tau) \vert = 1``, and for a completely incoherent (thermal) state ``g^{(1)}(\tau) = 0``. The following code calculates and plots ``g^{(1)}(\tau)`` as a function of ``\tau``: |
| 172 | + |
| 173 | +```@example correlation_and_spectrum |
| 174 | +τlist = LinRange(0, 10, 200) |
| 175 | +
|
| 176 | +# Hamiltonian |
| 177 | +N = 15 |
| 178 | +a = destroy(N) |
| 179 | +H = 2 * π * a' * a |
| 180 | +
|
| 181 | +# collapse operator |
| 182 | +G1 = 0.75 |
| 183 | +n_th = 2.00 # bath temperature in terms of excitation number |
| 184 | +c_ops = [ |
| 185 | + sqrt(G1 * (1 + n_th)) * a, |
| 186 | + sqrt(G1 * n_th) * a' |
| 187 | +] |
| 188 | +
|
| 189 | +# start with a coherent state of α = 2.0 |
| 190 | +ρ0 = coherent_dm(N, 2.0) |
| 191 | +
|
| 192 | +# first calculate the occupation number as a function of time |
| 193 | +n = mesolve(H, ρ0, τlist, c_ops, e_ops = [a' * a], progress_bar = Val(false)).expect[1,:] |
| 194 | +n0 = n[1] # occupation number at τ = 0 |
| 195 | +
|
| 196 | +# calculate the correlation function G1 and normalize with n to obtain g1 |
| 197 | +g1 = correlation_2op_1t(H, ρ0, τlist, c_ops, a', a, progress_bar = Val(false)) |
| 198 | +g1 = g1 ./ sqrt.(n .* n0) |
| 199 | +
|
| 200 | +# plot by CairoMakie.jl |
| 201 | +fig = Figure(size = (500, 350)) |
| 202 | +ax = Axis(fig[1, 1], title = "Decay of a coherent state to an incoherent (thermal) state", xlabel = L"Time $\tau$") |
| 203 | +lines!(ax, τlist, real(g1), label = L"g^{(1)}(\tau)", linestyle = :solid) |
| 204 | +lines!(ax, τlist, real(n), label = L"n(\tau)", linestyle = :dash) |
| 205 | +
|
| 206 | +axislegend(ax, position = :rt) |
| 207 | +
|
| 208 | +fig |
| 209 | +``` |
| 210 | + |
| 211 | +### Example: second-order optical coherence function |
| 212 | + |
| 213 | +The second-order optical coherence function, with time-delay ``\tau``, is defined as |
| 214 | + |
| 215 | +```math |
| 216 | +g^{(2)}(\tau) = \frac{\left\langle \hat{a}^\dagger(0) \hat{a}^\dagger(\tau) \hat{a}(\tau) \hat{a}(0) \right\rangle}{\left\langle \hat{a}^\dagger(0) \hat{a}(0) \right\rangle^2}. |
| 217 | +``` |
| 218 | + |
| 219 | +For a coherent state ``g^{(2)}(\tau) = 1``, for a thermal state ``g^{(2)}(\tau = 0) = 2`` and it decreases as a function of time (bunched photons, they tend to appear together), and for a Fock state with ``n``-photons ``g^{(2)}(\tau = 0) = n(n-1)/n^2 < 1`` and it increases with time (anti-bunched photons, more likely to arrive separated in time). |
| 220 | + |
| 221 | +To calculate this type of correlation function with `QuantumToolbox.jl`, we can use [`correlation_3op_1t`](@ref), which computes a correlation function on the form ``\left\langle \hat{A}(0) \hat{B}(\tau) \hat{C}(0) \right\rangle`` (three operators and one delay-time vector). We first have to combine the central two operators into one single one as they are evaluated at the same time, e.g. here we do ``\hat{B}(\tau) = \hat{a}^\dagger(\tau) \hat{a}(\tau) = (\hat{a}^\dagger\hat{a})(\tau)``. |
| 222 | + |
| 223 | +The following code calculates and plots ``g^{(2)}(\tau)`` as a function of ``\tau`` for a coherent, thermal and Fock state: |
| 224 | + |
| 225 | +```@example correlation_and_spectrum |
| 226 | +τlist = LinRange(0, 25, 200) |
| 227 | +
|
| 228 | +# Hamiltonian |
| 229 | +N = 25 |
| 230 | +a = destroy(N) |
| 231 | +H = 2 * π * a' * a |
| 232 | +
|
| 233 | +κ = 0.25 |
| 234 | +n_th = 2.0 # bath temperature in terms of excitation number |
| 235 | +c_ops = [ |
| 236 | + sqrt(κ * (1 + n_th)) * a, |
| 237 | + sqrt(κ * n_th) * a' |
| 238 | +] |
| 239 | +
|
| 240 | +cases = [ |
| 241 | + Dict("state" => coherent_dm(N, sqrt(2)), "label" => "coherent state", "lstyle" => :solid), |
| 242 | + Dict("state" => thermal_dm(N, 2), "label" => "thermal state", "lstyle" => :dash), |
| 243 | + Dict("state" => fock_dm(N, 2), "label" => "Fock state", "lstyle" => :dashdot), |
| 244 | +] |
| 245 | +
|
| 246 | +# plot by CairoMakie.jl |
| 247 | +fig = Figure(size = (500, 350)) |
| 248 | +ax = Axis(fig[1, 1], xlabel = L"Time $\tau$", ylabel = L"g^{(2)}(\tau)") |
| 249 | +
|
| 250 | +for case in cases |
| 251 | + ρ0 = case["state"] |
| 252 | +
|
| 253 | + # calculate the occupation number at τ = 0 |
| 254 | + n0 = expect(a' * a, ρ0) |
| 255 | +
|
| 256 | + # calculate the correlation function g2 |
| 257 | + g2 = correlation_3op_1t(H, ρ0, τlist, c_ops, a', a' * a, a, progress_bar = Val(false)) |
| 258 | + g2 = g2 ./ n0^2 |
| 259 | +
|
| 260 | + lines!(ax, τlist, real(g2), label = case["label"], linestyle = case["lstyle"]) |
| 261 | +end |
| 262 | +
|
| 263 | +axislegend(ax, position = :rt) |
| 264 | +
|
| 265 | +fig |
| 266 | +``` |
0 commit comments