|
1 | 1 | module Functionals |
2 | 2 |
|
3 | 3 | export J_T_ss, J_T_sm, J_T_re |
4 | | -export J_a_fluence |
| 4 | +export J_a_fluence, J_a_avg_zero |
5 | 5 | export gate_functional |
6 | 6 | export make_gate_chi |
7 | 7 | export J_b |
|
973 | 973 | make_analytic_grad_J_a(::typeof(J_a_fluence), tlist) = grad_J_a_fluence |
974 | 974 |
|
975 | 975 |
|
| 976 | +@doc raw"""Running cost penalizing a non-zero pulse area. |
| 977 | +
|
| 978 | +```julia |
| 979 | +J_a = J_a_avg_zero(pulsevals, tlist) |
| 980 | +``` |
| 981 | +
|
| 982 | +calculates |
| 983 | +
|
| 984 | +```math |
| 985 | +J_a = \sum_l \left(\int_0^T ϵ_l(t)\, dt\right)^2 \approx \sum_l A_l^2\,, |
| 986 | +\quad A_l = \sum_n ϵ_{nl}\, dt_n\,, |
| 987 | +``` |
| 988 | +
|
| 989 | +where ``ϵ_{nl}`` and ``dt_n`` are as in [`J_a_fluence`](@ref). The functional |
| 990 | +is zero when every control integrates to zero over the time grid, and positive |
| 991 | +otherwise. |
| 992 | +
|
| 993 | +In conjunction with [`QuantumPropagators.Amplitudes.GuidedAmplitude`](@ref), |
| 994 | +this enables an optimization that preserves the pulse area of a given `guide`. |
| 995 | +
|
| 996 | +# See also |
| 997 | +
|
| 998 | +* [`grad_J_a_avg_zero`](@ref) — analytic (automatic) gradient |
| 999 | +""" |
| 1000 | +function J_a_avg_zero(pulsevals, tlist) |
| 1001 | + N_T = length(tlist) - 1 |
| 1002 | + dt = diff(tlist) # (N_T,) |
| 1003 | + pv = reshape(pulsevals, N_T, :) # (N_T, N_L), no copy |
| 1004 | + A = vec(dt' * pv) # (N_L,): time integral per control |
| 1005 | + return sum(abs2.(A)) |
| 1006 | +end |
| 1007 | + |
| 1008 | + |
| 1009 | +"""Analytic derivative for [`J_a_avg_zero`](@ref). |
| 1010 | +
|
| 1011 | +```julia |
| 1012 | +∇J_a = grad_J_a_avg_zero(pulsevals, tlist) |
| 1013 | +``` |
| 1014 | +
|
| 1015 | +returns `∇J_a` with elements ``2 A_l\\, dt_n``, where |
| 1016 | +``A_l = \\sum_n ϵ_{nl}\\, dt_n`` is the time integral of control `l`. |
| 1017 | +""" |
| 1018 | +function grad_J_a_avg_zero(pulsevals, tlist) |
| 1019 | + N_T = length(tlist) - 1 |
| 1020 | + dt = diff(tlist) # (N_T,) |
| 1021 | + pv = reshape(pulsevals, N_T, :) # (N_T, N_L), no copy |
| 1022 | + A = vec(dt' * pv) # (N_L,): time integral per control |
| 1023 | + return vec(2 .* reshape(dt, :, 1) .* reshape(A, 1, :)) |
| 1024 | +end |
| 1025 | + |
| 1026 | + |
| 1027 | +make_analytic_grad_J_a(::typeof(J_a_avg_zero), tlist) = grad_J_a_avg_zero |
| 1028 | + |
| 1029 | + |
976 | 1030 | """ |
977 | 1031 | Return a function that calculates ``|ξ_k(t_n)⟩ = -∂g_b/∂⟨Ψ_k(t_n)|``. |
978 | 1032 |
|
|
0 commit comments