Local Submodules
The following submodules of QuantumControl
are defined locally (as opposed to being re-exported from sub-packages).
$\gdef\tgt{\text{tgt}}$ $\gdef\tr{\operatorname{tr}}$ $\gdef\Re{\operatorname{Re}}$ $\gdef\Im{\operatorname{Im}}$
QuantumControl
also locally defines some unexported functions:
QuantumControl.Functionals
Public Members:
Re-exported Members:
Private Members:
Public members
QuantumControl.Functionals.J_T_re
— FunctionReal-part functional.
J_T_re(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[J_{T,\text{re}} = 1 - F_{\text{re}} \quad\in \begin{cases} [0, 2] & \text{in Hilbert space} \\ [0, 1] & \text{in Liouville space.} \end{cases}\]
All arguments are passed to f_tau
while evaluating $F_{\text{re}}$ in F_re
.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.J_T_sm
— FunctionSquare-modulus functional.
J_T_sm(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[J_{T,\text{sm}} = 1 - F_{\text{sm}} \quad\in [0, 1].\]
All arguments are passed to f_tau
while evaluating $F_{\text{sm}}$ in F_sm
.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.J_T_ss
— FunctionState-to-state phase-insensitive functional.
J_T_ss(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[J_{T,\text{ss}} = 1 - F_{\text{ss}} \in [0, 1].\]
All arguments are passed to F_ss
.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.J_a_fluence
— FunctionRunning cost for the pulse fluence.
J_a = J_a_fluence(pulsevals, tlist)
calculates
\[J_a = \sum_l \int_0^T |ϵ_l(t)|^2 dt = \left(\sum_{nl} |ϵ_{nl}|^2 \right) dt\]
where $ϵ_{nl}$ are the values in the (vectorized) pulsevals
, n
is the index of the intervals of the time grid, and $dt$ is the time step, taken from the first time interval of tlist
and assumed to be uniform.
QuantumControl.Functionals.gate_functional
— FunctionConvert a functional from acting on a gate to acting on propagated states.
J_T = gate_functional(J_T_U; kwargs...)
constructs a functional J_T
that meets the requirements for for Krotov/GRAPE and make_chi
. That is, the output J_T
takes positional positional arguments ϕ
and trajectories
. The input functional J_T_U
is assumed to have the signature J_T_U(U; kwargs...)
where U
is a matrix with elements $U_{ij} = ⟨Ψ_i|ϕ_j⟩$, where $|Ψ_i⟩$ is the initial_state
of the i'th trajectories
(assumed to be the i'th canonical basis state) and $|ϕ_j⟩$ is the result of forward-propagating $|Ψ_j⟩$. That is, U
is the projection of the time evolution operator into the subspace defined by the basis in the initial_states
of the trajectories
.
See also
make_gate_chi
— create a correspondingchi
function that acts more efficiently than the generalmake_chi
.
QuantumControl.Functionals.make_gate_chi
— FunctionReturn a function to evaluate $|χ_k⟩ = -∂J_T(Û)/∂⟨ϕ_k|$ via the chain rule.
chi! = make_gate_chi(J_T_U, trajectories; automatic=:default, kwargs...)
returns a function equivalent to
chi! = make_chi(
gate_functional(J_T_U; kwargs...),
trajectories;
mode=:automatic,
automatic,
)
\[\begin{split} |χ_k⟩ &= -\frac{∂}{∂⟨ϕ_k|} J_T \\ &= - \frac{1}{2} \sum_i (∇_U J_T)_{ik} \frac{∂ U_{ik}}{∂⟨ϕ_k|} \\ &= - \frac{1}{2} \sum_i (∇_U J_T)_{ik} |Ψ_i⟩ \end{split}\]
where $|Ψ_i⟩$ is the basis state stored as the initial_state
of the i'th trajectory, see gate_functional
.
The gradient $∇_U J_T$ is obtained via automatic differentiation (AD). This requires that an AD package has been loaded (e.g., using Zygote
). This package must either be passed as the automatic
keyword argument, or the package must be set as the default AD provider using QuantumControl.set_default_ad_framework
.
Compared to the more general make_chi
with mode=:automatic
, make_gate_chi
will generally have a slightly smaller numerical overhead, as it pushes the use of automatic differentiation down by one level.
Private members
QuantumControl.Functionals.chi_sm!
— FunctionBackward boundary states $|χ⟩$ for functional J_T_sm
.
chi_sm!(χ, ϕ, trajectories; τ=nothing) # or `tau=nothing`
sets the elements of χ
according to
\[|χ_k⟩ = -\frac{\partial J_{T,\text{sm}}}{\partial ⟨ϕ_k(T)|} = \frac{1}{N^2} w_k \sum_{j}^{N} w_j τ_j |ϕ_k^{\tgt}⟩\]
with $|ϕ^{\tgt}_k⟩$, $τ_j$ and $w_k$ as defined in f_tau
.
Note: this function can be obtained with make_chi(J_T_sm, trajectories)
.
QuantumControl.Functionals.F_sm
— FunctionSquare-modulus fidelity.
F_sm(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[F_{\text{sm}} = |f_τ|^2 = \left\vert\frac{1}{N} \sum_{k=1}^{N} w_k τ_k\right\vert^2 = \frac{1}{N^2} \sum_{k=1}^{N} \sum_{j=1}^{N} w_k w_j τ̄_k τ_j \quad\in [0, 1]\,,\]
with $w_k$ the weight for the k'th trajectory and $τ_k$ the overlap of the k'th propagated state with the k'th target state, $τ̄_k$ the complex conjugate of $τ_k$, and $N$ the number of trajectories.
All arguments are passed to f_tau
to evaluate $f_τ$.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.chi_ss!
— FunctionBackward boundary states $|χ⟩$ for functional J_T_ss
.
chi_ss!(χ, ϕ, trajectories; τ=nothing) # or `tau=nothing`
sets the elements of χ
according to
\[|χ_k⟩ = -\frac{∂ J_{T,\text{ss}}}{∂ ⟨ϕ_k(T)|} = \frac{1}{N} w_k τ_k |ϕ^{\tgt}_k⟩\,,\]
with $|ϕ^{\tgt}_k⟩$, $τ_k$ and $w_k$ as defined in f_tau
.
Note: this function can be obtained with make_chi(J_T_ss, trajectories)
.
QuantumControl.Functionals.F_re
— FunctionReal-part fidelity.
F_re(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[F_{\text{re}} = \Re[f_{τ}] = \Re\left[ \frac{1}{N} \sum_{k=1}^{N} w_k τ_k \right] \quad\in \begin{cases} [-1, 1] & \text{in Hilbert space} \\ [0, 1] & \text{in Liouville space.} \end{cases}\]
with $w_k$ the weight for the k'th trajectory and $τ_k$ the overlap of the k'th propagated state with the k'th target state, and $N$ the number of trajectories.
All arguments are passed to f_tau
to evaluate $f_τ$.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.f_tau
— FunctionAverage complex overlap of the target states with forward-propagated states.
f_tau(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[f_τ = \frac{1}{N} \sum_{k=1}^{N} w_k τ_k\]
with
\[τ_k = ⟨ϕ_k^\tgt|ϕ_k(T)⟩\]
in Hilbert space, or
\[τ_k = \tr[ρ̂_k^{\tgt\,\dagger} ρ̂_k(T)]\]
in Liouville space, where $|ϕ_k⟩$ or $ρ̂_k$ are the elements of ϕ
, and $|ϕ_k^\tgt⟩$ or $ρ̂_k^\tgt$ are the target states from the target_state
field of the trajectories
. If τ
is given as a keyword argument, it must contain the values τ_k
according to the above definition. Otherwise, the $τ_k$ values will be calculated internally.
$N$ is the number of trajectories, and $w_k$ is the weight
attribute for each trajectory. The weights are not automatically normalized, they are assumed to have values such that the resulting $f_τ$ lies in the unit circle of the complex plane. Usually, this means that the weights should sum to $N$.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.F_ss
— FunctionState-to-state phase-insensitive fidelity.
F_ss(ϕ, trajectories; τ=nothing) # or `tau=nothing`
calculates
\[F_{\text{ss}} = \frac{1}{N} \sum_{k=1}^{N} w_k |τ_k|^2 \quad\in [0, 1]\]
with $N$, $w_k$ and $τ_k$ as in f_tau
.
Reference
- [12] Palao and Kosloff, Phys. Rev. A 68, 062308 (2003)
QuantumControl.Functionals.chi_re!
— FunctionBackward boundary states $|χ⟩$ for functional J_T_re
.
chi_re!(χ, ϕ, trajectories; τ=nothing) # or `tau=nothing`
sets the elements of χ
according to
\[|χ_k⟩ = -\frac{∂ J_{T,\text{re}}}{∂ ⟨ϕ_k(T)|} = \frac{1}{2N} w_k |ϕ^{\tgt}_k⟩\]
with $|ϕ^{\tgt}_k⟩$ and $w_k$ as defined in f_tau
.
Note: this function can be obtained with make_chi(J_T_re, trajectories)
.
QuantumControl.Functionals.grad_J_a_fluence!
— FunctionAnalytic derivative for J_a_fluence
.
grad_J_a_fluence!(∇J_a, pulsevals, tlist)
sets the (vectorized) elements of ∇J_a
to $2 ϵ_{nl} dt$, where $ϵ_{nl}$ are the (vectorized) elements of pulsevals
and $dt$ is the time step, taken from the first time interval of tlist
and assumed to be uniform.
QuantumControl.PulseParametrizations
Public Members:
LogisticParametrization
LogisticSqParametrization
ParametrizedAmplitude
SquareParametrization
TanhParametrization
TanhSqParametrization
Private Members:
Public members
QuantumControl.PulseParametrizations.LogisticParametrization
— FunctionParametrization with a Logistic function that enforces a_min < a(t) < a_max
.
QuantumControl.PulseParametrizations.LogisticSqParametrization
— FunctionParametrization with a Logistic-Square function that enforces 0 ≤ a(t) < a_max
.
QuantumControl.PulseParametrizations.ParametrizedAmplitude
— TypeAn amplitude determined by a pulse parametrization.
That is, $a(t) = a(ϵ(t))$ with a bijective mapping between the value of $a(t)$ and $ϵ(t)$, e.g. $a(t) = ϵ^2(t)$ (a SquareParametrization
). Optionally, the amplitude may be multiplied with an additional shape function, cf. ShapedAmplitude
.
ampl = ParametrizedAmplitude(control; parametrization)
initializes $a(t) = a(ϵ(t)$ where $ϵ(t)$ is the control
, and the mandatory keyword argument parametrization
is a PulseParametrization
. The control
must either be a vector of values discretized to the midpoints of a time grid, or a callable control(t)
.
ampl = ParametrizedAmplitude(control; parametrization, shape=shape)
initializes $a(t) = S(t) a(ϵ(t))$ where $S(t)$ is the given shape
. It must be a vector if control
is a vector, or a callable shape(t)
if control
is a callable.
ampl = ParametrizedAmplitude(control, tlist; parametrization, shape=shape)
discretizes control
and shape
(if given) to the midpoints of tlist
before initialization.
ampl = ParametrizedAmplitude(
amplitude, tlist; parametrization, shape=shape, parametrize=true
)
initializes $ã(t) = S(t) a(t)$ where $a(t)$ is the input amplitude
. First, if amplitude
is a callable amplitude(t)
, it is discretized to the midpoints of tlist
. Then, a control
$ϵ(t)$ is calculated so that $a(t) ≈ a(ϵ(t))$. Clippling may occur if the values in amplitude
cannot represented with the given parametrization
. Lastly, ParametrizedAmplitude(control; parametrization, shape)
is initialized with the calculated control
.
Note that the tlist
keyword argument is required when parametrize=true
is given, even if amplitude
is already a vector.
QuantumControl.PulseParametrizations.SquareParametrization
— FunctionParametrization a(t) = ϵ²(t), enforcing pulse values $a(t) ≥ 0$.
QuantumControl.PulseParametrizations.TanhParametrization
— FunctionParametrization with a tanh function that enforces a_min < a(t) < a_max
.
QuantumControl.PulseParametrizations.TanhSqParametrization
— FunctionParametrization with a tanh² function that enforces 0 ≤ a(t) < a_max
.
Private members
QuantumControl.PulseParametrizations.PulseParametrization
— TypeSpecification for a "time-local" pulse parametrization.
The parametrization is given as a collection of three functions:
- $a(ϵ(t))$
- $ϵ(a(t))$
- $∂a/∂ϵ$ as a function of $ϵ(t)$.
QuantumControl.Workflows
Public Members:
Public members
QuantumControl.Workflows.@optimize_or_load
— MacroRun optimize
and store the result, or load the result if it exists.
result = @optimize_or_load(
file,
problem;
method,
force=false,
verbose=true,
metadata=nothing,
logfile=nothing,
kwargs...
)
runs result = optimize(problem; method, kwargs...)
and stores result
in file
in the JLD2 format. Note that the method
keyword argument is mandatory.
In addition to the result
, the data in the output file
can also contain metadata. By default, this is "script" with the file name and line number of where @optimize_or_load
was called, as well as data from the dict metadata
mapping arbitrary (string) keys to values. Lastly, the data contains truncated captured output (up to 1kB of both the beginning and end of the output) from the optimization.
If logfile
is given as the path to a file, both stdout
and stderr
from optimize
are redirected into the given file.
If file
already exists (and force=false
), load the result
from that file instead of running the optimization, and print any (truncated) captured output.
All other kwargs
are passed directly to optimize
.
For methods that support this, @optimize_or_load
will set up a callback to dump the optimization result to file
in case of an unexpected program shutdown, see set_atexit_save_optimization
.
Related Functions
run_or_load
— a function for more general long-running calculations.load_optimization
: Function to load a file produced by@optimize_or_load
QuantumControl.Workflows.load_optimization
— FunctionLoad a previously stored optimization.
result = load_optimization(file; verbose=false, kwargs...)
recovers a result
previously stored by @optimize_or_load
or save_optimization
.
result, metadata = load_optimization(file; return_metadata=true, kwargs...)
also obtains a metadata dict, see @optimize_or_load
. This dict maps string keys to values.
Calling load_optimization
with verbose=true
will @info
the metadata after loading the file
QuantumControl.Workflows.run_or_load
— FunctionRun some code and write the result to file, or load from the file if it exists.
data = run_or_load(
file;
save=(endswith(file, ".jld2") ? JLD2.save_object : FileIO.save),
load=(endswith(file, ".jld2") ? JLD2.load_object : FileIO.load),
force=false,
verbose=true,
kwargs...
) do
data = Dict() # ... # something that can be saved to / loaded from file
return data
end
runs the code in the block and stores data
in the given file
. If file
already exists, skip running the code and instead return the data in file
.
If force
is True
, run the code whether or not file
exists, potentially overwriting it.
With verbose=true
, information about the status of file
will be shown as @info
.
The data
returned by the code block must be compatible with the format of file
and the save
/load
functions. When using JLD2.save_object
and JLD2.load_object
, almost any data can be written, so this should be particularly safe. More generally, when using FileIO.save
and FileIO.load
, see the FileIO registry for details. A common examples would be a DataFrame
being written to a .csv
file.
See also
@optimize_or_load
— for wrapping aroundoptimize
DrWatson.@produce_or_load
— a similar but more opinionated function with automatic naming
QuantumControl.Workflows.save_optimization
— FunctionWrite an optimization result to file.
save_optimization(file, result; metadata=nothing)
writes the result obtained from a call to optimize
to the given file
in JLD2 format. If given, metadata
is a dict of additional data that will be stored with the result. The metadata
dict should use strings as keys.
See also
load_optimization
: Function to load a file produced by@optimize_or_load
orsave_optimization
@optimize_or_load
: Runoptimize
andsave_optimization
in one go.
QuantumControl
local unexported functions
QuantumControl.set_default_ad_framework
— FunctionSet the default provider for automatic differentiation.
QuantumControl.set_default_ad_framework(mod; quiet=false)
registers the given module (package) as the default AD framework.
This determines the default setting for the automatic
parameter in the following functions:
QuantumControl.Functionals.make_chi
QuantumControl.Functionals.make_gate_chi
QuantumControl.Functionals.make_grad_J_a
The given mod
must be a supported AD framework, e.g.,
import Zygote
QuantumControl.set_default_ad_framework(Zygote)
Currently, there is built-in support for Zygote
and FiniteDifferences
.
For other packages to be used as the default AD framework, the appropriate methods for make_chi
etc. must be defined.
Unless quiet=true
, calling set_default_ad_framework
will show a message to confirm the setting.
To unset the default AD framework, use
QuantumControl.set_default_ad_framework(nothing)
QuantumControl.print_versions
— FunctionPrint the versions of the packages constituting the QuantumControl
framework.
QuantumControl.print_versions()
import QuantumControl
QuantumControl.print_versions()
QuantumPropagators: 0.7.5+dev (/home/runner/.julia/dev/QuantumPropagators)
QuantumControlBase: 0.9.3+dev (/home/runner/.julia/dev/QuantumControlBase)
QuantumControl : 0.9.1