|
| 1 | +--- |
| 2 | +title: Quantum Fisher Information |
| 3 | +author: Orjan Ameye |
| 4 | +date: last-modified |
| 5 | +--- |
| 6 | + |
| 7 | +This notebook demonstrates the computation of Quantum Fisher Information (QFI) for a driven-dissipative Kerr Parametric Oscillator (KPO) using automatic differentiation. The QFI quantifies the ultimate precision limit for parameter estimation in quantum systems. |
| 8 | + |
| 9 | +We import the necessary packages for quantum simulations and automatic differentiation: |
| 10 | + |
| 11 | +```{julia} |
| 12 | +using QuantumToolbox # Quantum optics simulations |
| 13 | +using DifferentiationInterface # Unified automatic differentiation interface |
| 14 | +using SciMLSensitivity # Allows for ODE sensitivity analysis |
| 15 | +using FiniteDiff # Finite difference methods |
| 16 | +using LinearAlgebra # Linear algebra operations |
| 17 | +using CairoMakie # Plotting |
| 18 | +CairoMakie.activate!(type = "svg") |
| 19 | +``` |
| 20 | + |
| 21 | +## System Parameters and Hamiltonian |
| 22 | + |
| 23 | +The KPO system is governed by the Hamiltonian: |
| 24 | +$$H = -p_1 a^\dagger a + K (a^\dagger)^2 a^2 - G (a^\dagger a^\dagger + a a)$$ |
| 25 | + |
| 26 | +where: |
| 27 | + |
| 28 | +- $p_1$ is the parameter we want to estimate (detuning) |
| 29 | +- $K$ is the Kerr nonlinearity |
| 30 | +- $G$ is the parametric drive strength |
| 31 | +- $\gamma$ is the decay rate |
| 32 | + |
| 33 | +```{julia} |
| 34 | +function final_state(p, t) |
| 35 | + G, K, γ = 0.002, 0.001, 0.01 |
| 36 | +
|
| 37 | + N = 20 # cutoff of the Hilbert space dimension |
| 38 | + a = destroy(N) # annihilation operator |
| 39 | +
|
| 40 | + coef(p,t) = - p[1] |
| 41 | + H = QobjEvo(a' * a , coef) + K * a' * a' * a * a - G * (a' * a' + a * a) |
| 42 | + c_ops = [sqrt(γ)*a] |
| 43 | + ψ0 = fock(N, 0) # initial state |
| 44 | + |
| 45 | + tlist = range(0, 2000, 100) |
| 46 | + sol = mesolve(H, ψ0, tlist, c_ops; params = p, progress_bar = Val(false), saveat = [t]) |
| 47 | + return sol.states[end].data |
| 48 | +end |
| 49 | +``` |
| 50 | + |
| 51 | +## Quantum Fisher Information Calculation |
| 52 | + |
| 53 | +The QFI is computed using the symmetric logarithmic derivative (SLD). For a density matrix $\rho(\theta)$ parametrized by $\theta$: |
| 54 | + |
| 55 | +$$F_Q = \text{Tr}[\partial_\theta \rho \cdot L]$$ |
| 56 | + |
| 57 | +where $L$ is the SLD satisfying: $\partial_\theta \rho = \frac{1}{2}(\rho L + L \rho)$ |
| 58 | + |
| 59 | +```{julia} |
| 60 | +function compute_fisher_information(ρ, dρ) |
| 61 | + # Add small regularization to avoid numerical issues with zero eigenvalues |
| 62 | + reg = 1e-12 * I |
| 63 | + ρ_reg = ρ + reg |
| 64 | +
|
| 65 | + # Solve for the symmetric logarithmic derivative L |
| 66 | + # dρ = (1/2)(ρL + Lρ) |
| 67 | + # This is a Sylvester equation: ρL + Lρ = 2*dρ |
| 68 | + L = sylvester(ρ_reg, ρ_reg, -2*dρ) |
| 69 | +
|
| 70 | + # Fisher information F = Tr(dρ * L) |
| 71 | + F = real(tr(dρ * L)) |
| 72 | +
|
| 73 | + return F |
| 74 | +end |
| 75 | +``` |
| 76 | + |
| 77 | +## Automatic Differentiation Setup |
| 78 | + |
| 79 | +We use finite differences through DifferentiationInterface.jl to compute the derivative of the quantum state with respect to the parameter. This is a key step that enables efficient QFI computation without manual derivative calculations. |
| 80 | + |
| 81 | +```{julia} |
| 82 | +# Test the system |
| 83 | +final_state([0], 100) |
| 84 | +
|
| 85 | +# Define state function for automatic differentiation |
| 86 | +state(p) = final_state(p, 2000) |
| 87 | +
|
| 88 | +# Compute both the state and its derivative |
| 89 | +ρ, dρ = DifferentiationInterface.value_and_jacobian(state, AutoFiniteDiff(), [0.0]) |
| 90 | +
|
| 91 | +# Reshape the derivative back to matrix form |
| 92 | +dρ = QuantumToolbox.vec2mat(vec(dρ)) |
| 93 | +
|
| 94 | +# Compute QFI at final time |
| 95 | +qfi_final = compute_fisher_information(ρ, dρ) |
| 96 | +println("QFI at final time: ", qfi_final) |
| 97 | +``` |
| 98 | + |
| 99 | +## Time Evolution of Quantum Fisher Information |
| 100 | + |
| 101 | +Now we compute how the QFI evolves over time to understand the optimal measurement time for parameter estimation: |
| 102 | + |
| 103 | +```{julia} |
| 104 | +ts = range(0, 2000, 100) |
| 105 | +
|
| 106 | +QFI_t = map(ts) do t |
| 107 | + state(p) = final_state(p, t) |
| 108 | + ρ, dρ = DifferentiationInterface.value_and_jacobian(state, AutoFiniteDiff(), [0.0]) |
| 109 | + dρ = QuantumToolbox.vec2mat(vec(dρ)) |
| 110 | + compute_fisher_information(ρ, dρ) |
| 111 | +end |
| 112 | +
|
| 113 | +println("QFI computed for ", length(ts), " time points") |
| 114 | +``` |
| 115 | + |
| 116 | +## Visualization |
| 117 | + |
| 118 | +Plot the time evolution of the Quantum Fisher Information: |
| 119 | + |
| 120 | +```{julia} |
| 121 | +fig = Figure() |
| 122 | +ax = Axis( |
| 123 | + fig[1,1], |
| 124 | + xlabel = "Time", |
| 125 | + ylabel = "Quantum Fisher Information" |
| 126 | +) |
| 127 | +lines!(ax, ts, QFI_t) |
| 128 | +fig |
| 129 | +``` |
| 130 | + |
| 131 | +## Version Information |
| 132 | +```{julia} |
| 133 | +QuantumToolbox.versioninfo() |
| 134 | +``` |
| 135 | + |
| 136 | +```{julia} |
| 137 | +using Pkg |
| 138 | +Pkg.status() |
| 139 | +``` |
0 commit comments