@@ -9,12 +9,10 @@ This notebook demonstrates the computation of Quantum Fisher Information (QFI) f
9
9
We import the necessary packages for quantum simulations and automatic differentiation:
10
10
11
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
12
+ using QuantumToolbox # Quantum optics simulations
13
+ using ForwardDiff # For automatic differentiation
14
+ using LinearAlgebra # Linear algebra operations
15
+ using CairoMakie # Plotting
18
16
CairoMakie.activate!(type = "svg")
19
17
```
20
18
@@ -31,20 +29,24 @@ where:
31
29
- $\gamma$ is the decay rate
32
30
33
31
``` {julia}
34
- function final_state(p, t)
35
- G, K, γ = 0.002, 0.001, 0.01
32
+ const G, K, γ = 0.002, 0.001, 0.01
33
+
34
+ const N = 20 # cutoff of the Hilbert space dimension
35
+ const a = destroy(N) # annihilation operator
36
+
37
+ const c_ops = [sqrt(γ)*a]
38
+ const ψ0 = fock(N, 0) # initial state
36
39
37
- N = 20 # cutoff of the Hilbert space dimension
38
- a = destroy(N) # annihilation operator
40
+ const tlist = range(0, 2000, 100)
41
+
42
+ function final_state(p, t)
43
+ H = - p[1] * a' * a + K * a' * a' * a * a - G * (a' * a' + a * a)
39
44
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
45
sol = mesolve(H, ψ0, tlist, c_ops; params = p, progress_bar = Val(false), saveat = [t])
47
- return sol.states[end].data
46
+ ρ_vec = vec(sol.states[end].data)
47
+
48
+ # Split the real and imaginary parts of the density matrix to a real vector since ForwardDiff doesn't handle complex numbers directly
49
+ return vcat(real.(ρ_vec), imag.(ρ_vec))
48
50
end
49
51
```
50
52
@@ -86,10 +88,13 @@ final_state([0], 100)
86
88
state(p) = final_state(p, 2000)
87
89
88
90
# Compute both the state and its derivative
89
- ρ, dρ = DifferentiationInterface.value_and_jacobian(state, AutoFiniteDiff(), [0.0])
91
+ ρ, dρ = state([0.0]), ForwardDiff.jacobian(state, [0.0])
92
+
93
+ # Reshape back to complex matrix form
94
+ ρ = reshape(ρ[1:end÷2] + 1im * ρ[end÷2+1:end], N, N)
90
95
91
96
# Reshape the derivative back to matrix form
92
- dρ = QuantumToolbox.vec2mat(vec(dρ) )
97
+ dρ = reshape(dρ[1:end÷2] + 1im * dρ[end÷2+1:end], N, N )
93
98
94
99
# Compute QFI at final time
95
100
qfi_final = compute_fisher_information(ρ, dρ)
@@ -103,10 +108,13 @@ Now we compute how the QFI evolves over time to understand the optimal measureme
103
108
``` {julia}
104
109
ts = range(0, 2000, 100)
105
110
106
- QFI_t = map(ts) do t
111
+ @time QFI_t = map(ts) do t
107
112
state(p) = final_state(p, t)
108
- ρ, dρ = DifferentiationInterface.value_and_jacobian(state, AutoFiniteDiff(), [0.0])
109
- dρ = QuantumToolbox.vec2mat(vec(dρ))
113
+ ρ, dρ = state([0.0]), ForwardDiff.jacobian(state, [0.0])
114
+
115
+ ρ = reshape(ρ[1:end÷2] + 1im * ρ[end÷2+1:end], N, N)
116
+ dρ = reshape(dρ[1:end÷2] + 1im * dρ[end÷2+1:end], N, N)
117
+
110
118
compute_fisher_information(ρ, dρ)
111
119
end
112
120
0 commit comments