Bi-Directional Waveguide via Feedback Reduction
This example reconstructs the N=2 bidirectional-waveguide model using the SLH feedback reduction rule. The resulting Hamiltonian and Lindblad operators are then used to simulate the transmitted and reflected intensities for a coherent input pulse.
using QuantumInputOutputusing SecondQuantizedAlgebrausing Symbolics: Symbolicsusing QuantumOpticsusing QuantumOpticsBase: daggerusing Plotsusing LinearAlgebraN = 2# symbolic Hilbert spaceha(i) = NLevelSpace(Symbol("a$(i)"), 2)h = tensor([ha(i) for i = 1:N]...)# symbolic operatorsσ(α, i, j) = Transition(h, Symbol("σ_$(α)"), i, j, α)# symbolic parametersγR(i) = Symbolics.variable(Symbol("γ^{($(i))}_R"); T = Real)γL(i) = Symbolics.variable(Symbol("γ^{($(i))}_L"); T = Real)Δ(i) = Symbolics.variable(Symbol("Δ_{$(i)}"); T = Real)ϕ(i, j) = Symbolics.variable(Symbol("ϕ_{$(i)$(j)}"); T = Real)Ein = Symbolics.variable(Symbol("E_{in}"); T = Real)Each quantum dot is treated as a two-port component: port 1 couples to the right-moving field and port 2 couples to the left-moving field. We concatenate the source, the two dots, and the phase shifter, and then eliminate the internal waveguide links with six feedback reductions.
I2 = Matrix{Int}(I, 2, 2)G_in = SLH(I2, [Ein, 0], 0)G_qd(i) = SLH(I2, [√(γR(i)) * σ(i, 1, 2), √(γL(i)) * σ(i, 1, 2)], -Δ(i) * σ(i, 2, 2))G_phase(i, j) = SLH([exp(1im * ϕ(i, j)) 0; 0 exp(1im * ϕ(i, j))], [0, 0], 0)G_unc = G_in ⊞ G_qd(1) ⊞ G_phase(1, 2) ⊞ G_qd(2)G_t = feedback(G_unc, 1 => 3, 3 => 5, 5 => 7, 8 => 6, 6 => 4, 4 => 2)The reduced model has two external ports. In the remaining port order, the first Lindblad operator corresponds to the reflected left-moving output and the second one to the transmitted right-moving output.
H = hamiltonian(G_t)L = jump_operator(G_t)L_L = L[1]L_R = L[2]γ_ = 1.0β = 0.9γRn = fill(γ_ * β / 2, N)γLn = fill(γ_ * β / 2, N)γ_add = fill(γ_ * (1 - β), N)Δn = fill(0.0, N)ϕn = fill(π / 10, max(N - 1, 0))σt = 0.8α0 = √(0.1)t0 = 4σtTend = 3t0u1(t) = 1 / (sqrt(σt) * π^(1 / 4)) * exp(-(t - t0)^2 / (2 * σt^2))Ein_t(t) = α0 * u1(t)p_sym = [ [γR(i) for i = 1:N]; [γL(i) for i = 1:N]; [Δ(i) for i = 1:N]; [ϕ(i, i + 1) for i = 1:(N-1)]]p_num = [γRn; γLn; Δn; ϕn]dict_p = Dict(p_sym .=> p_num)dict_p_t = Dict(Ein => Ein_t)ba = NLevelBasis(2)b = tensor([ba for _ = 1:N]...)H_QO = to_numeric(H, b; parameter = dict_p, time_parameter = dict_p_t)L_R_QO = to_numeric(L_R, b; parameter = dict_p, time_parameter = dict_p_t)L_L_QO = to_numeric(L_L, b; parameter = dict_p, time_parameter = dict_p_t)σ_qo(α, i, j) = to_numeric(σ(α, i, j), b)J_add = [√(γ_add[i]) * σ_qo(i, 1, 2) for i = 1:N]function input_output(t, ρ) Ht = H_QO(t) J = [L_R_QO(t), L_L_QO(t), J_add...] return Ht, J, dagger.(J)endT = collect(0.0:0.005:1.0) .* Tendψ0 = tensor([nlevelstate(ba, 1) for _ = 1:N]...)t, ρt = timeevolution.master_dynamic(T, ψ0, input_output)I_R = zeros(length(t))I_L = zeros(length(t))for (i, ti) in enumerate(t) LR = L_R_QO(ti) LL = L_L_QO(ti) I_R[i] = real(expect(LR' * LR, ρt[i])) I_L[i] = real(expect(LL' * LL, ρt[i]))endp = plot(t, I_R; label = "Transmission")plot!(p, t, I_L; label = "Reflection")plot!(p, t, abs2.(Ein_t.(t)); color = :grey, ls = :dash, label = "Input")plot!( p; xlabel = "time", ylabel = "intensity", legend = :best, grid = true, size = (500, 320),)pPackage versions
These results were obtained using the following versions:
using InteractiveUtilsversioninfo()using PkgPkg.status( ["QuantumInputOutput", "SecondQuantizedAlgebra", "QuantumOptics", "Plots"], mode = PKGMODE_MANIFEST,)Julia Version 1.13.0
Commit d1c37793dd2 (2026-09-09 19:00 UTC)
Build Info:
Official https://julialang.org release
Platform Info:
OS: Linux (x86_64-linux-gnu)
CPU: 4 × AMD EPYC 7763 64-Core Processor
WORD_SIZE: 64
LLVM: libLLVM-20.1.8 (ORCJIT, znver3)
GC: Built with stock GC
Threads: 1 default, 0 interactive, 1 GC (on 4 virtual cores)
Environment:
JULIA_PKG_SERVER_REGISTRY_PREFERENCE = eager
JULIA_DEBUG = Documenter,Literate
JULIA_NUM_THREADS = 1
Status `~/work/QuantumInputOutput.jl/QuantumInputOutput.jl/docs/Manifest.toml`
⌅ [7d9fca2a] Arpack v0.5.3
⌅ [861a8166] Combinatorics v1.0.2
[d38c429a] Contour v0.6.3
⌅ [82cc6244] DataInterpolations v9.5.0
[459566f4] DiffEqCallbacks v4.19.4
[77a26b50] DiffEqNoiseProcess v5.36.4
[c87230d0] FFMPEG v0.4.5
[7a1cc6ca] FFTW v1.10.0
⌅ [53c48c17] FixedPointNumbers v0.8.6
[069b7b12] FunctionWrappers v1.1.3
[28b8d3ca] GR v0.73.27
[42fd0dbc] IterativeSolvers v0.9.4
[1019f520] JLFzf v0.1.11
[682c06a0] JSON v1.9.0
[0b1a1467] KrylovKit v0.10.4
[b964fa9f] LaTeXStrings v1.4.1
[23fbe1c1] Latexify v0.16.12
[7a12625a] LinearMaps v3.11.4
[442fdcdd] Measures v0.3.3
[d8a4904e] MutableArithmetics v1.8.1
[77ba4419] NaNMath v1.1.4
[e7bfaba1] NumericalIntegration v0.3.4
[1dea7af3] OrdinaryDiffEq v7.8.1
[1344f307] OrdinaryDiffEqLowOrderRK v2.2.5
[ccf2f8ad] PlotThemes v3.3.0
[995b91a9] PlotUtils v1.5.0
[91a5bcdd] Plots v1.41.7
[aea7be01] PrecompileTools v1.3.4
[18f9eda6] QuantumInputOutput v0.5.3 `~/work/QuantumInputOutput.jl/QuantumInputOutput.jl`
[5717a53b] QuantumInterface v0.4.4
[6e0679c1] QuantumOptics v1.2.10
[4f57444f] QuantumOpticsBase v0.5.16
[3cdcf5f2] RecipesBase v1.3.4
[01d81517] RecipesPipeline v0.6.12
[731186ca] RecursiveArrayTools v4.5.3
[189a3867] Reexport v1.2.2
[05181044] RelocatableFolders v1.0.1
[ae029012] Requires v1.3.1
[0bca4576] SciMLBase v3.56.1
[431bcebd] SciMLPublic v1.3.0
[6c6a2e73] Scratch v1.3.0
⌅ [f7aa4685] SecondQuantizedAlgebra v0.11.0
[992d4aef] Showoff v1.1.1
[276daf66] SpecialFunctions v2.9.0
[90137ffa] StaticArrays v1.9.22
[10745b16] Statistics v1.11.5
[2913bbd2] StatsBase v0.34.13
[789caeaf] StochasticDiffEq v7.2.0
[d1185830] SymbolicUtils v4.48.0
[0c5d862f] Symbolics v7.41.1
[8ea1fca8] TermInterface v2.0.0
[1cfade01] UnicodeFun v0.4.1
[41fe7b60] Unzip v0.2.0
[2a0f44e3] Base64 v1.11.0
[ade2ca70] Dates v1.11.0
[f43a241f] Downloads v1.7.0
[37e2e46d] LinearAlgebra v1.13.0
[44cfe95a] Pkg v1.13.0
[de0858da] Printf v1.11.0
[3fa0cd96] REPL v1.11.0
[9a3f8284] Random v1.11.0
[2f01184e] SparseArrays v1.13.0
[fa267f1f] TOML v1.0.3
[cf7118a7] UUIDs v1.11.0
Info Packages marked with ⌅ have new versions available but compatibility constraints restrict them from upgrading. To see why use `status --outdated -m`
This page was generated using Literate.jl.