Skip to content

Commit 8458b5a

Browse files
Use true automatic differentiation on quantum Fisher information notebook (#51)
1 parent 45e181b commit 8458b5a

File tree

2 files changed

+31
-25
lines changed

2 files changed

+31
-25
lines changed

Project.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
[deps]
22
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
3+
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
34
HierarchicalEOM = "a62dbcb7-80f5-4d31-9a88-8b19fd92b128"
45
QuantumToolbox = "6c2fb7c5-b903-41d2-bc5e-5a7c320b9fab"
56
QuartoNotebookRunner = "4c0109c6-14e9-4c88-93f0-2b974d3468f4"
6-
SciMLSensitivity = "1ed8b502-d754-442c-8d5d-10ac956f44a1"
7-
DifferentiationInterface = "a0c0ee7d-e4b9-4e03-894e-1c5f64a51d63"
8-
FiniteDiff = "6a86dc24-6348-571c-b903-95158fe2bd41"

QuantumToolbox.jl/time_evolution/Quantum_Fisher_Information_with_automatic_differentiation.qmd

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,10 @@ This notebook demonstrates the computation of Quantum Fisher Information (QFI) f
99
We import the necessary packages for quantum simulations and automatic differentiation:
1010

1111
```{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
1816
CairoMakie.activate!(type = "svg")
1917
```
2018

@@ -31,20 +29,24 @@ where:
3129
- $\gamma$ is the decay rate
3230

3331
```{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
3639
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)
3944
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)
4645
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))
4850
end
4951
```
5052

@@ -86,10 +88,13 @@ final_state([0], 100)
8688
state(p) = final_state(p, 2000)
8789
8890
# 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)
9095
9196
# 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)
9398
9499
# Compute QFI at final time
95100
qfi_final = compute_fisher_information(ρ, dρ)
@@ -103,10 +108,13 @@ Now we compute how the QFI evolves over time to understand the optimal measureme
103108
```{julia}
104109
ts = range(0, 2000, 100)
105110
106-
QFI_t = map(ts) do t
111+
@time QFI_t = map(ts) do t
107112
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+
110118
compute_fisher_information(ρ, dρ)
111119
end
112120

0 commit comments

Comments
 (0)