Skip to content

Commit f4fc147

Browse files
committed
Update User Manual
1 parent d99df23 commit f4fc147

5 files changed

Lines changed: 40 additions & 13 deletions

File tree

docs/generate_api.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ open(outfile, "w") do out
7777
write(out, "```@meta\n")
7878
write(out, "EditURL = \"../../generate_api.jl\"\n")
7979
write(out, "```\n\n")
80-
write(out, "# QuantumControl\n\n")
80+
write(out, "# [QuantumControl](@id quantum-control-api)\n\n")
8181
if length(quantum_control_local_members) > 0
8282
println(out, "```@docs")
8383
for name quantum_control_local_members

docs/src/examples/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Examples
1+
# [Examples](@id examples-list)
22

33
## Krotov-specific examples
44

docs/src/glossary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ Examples for supported forms a Hamiltonian are the following, from the most gene
1414
<img src="../assets/controlhams.svg" width="80%"/>
1515
```
1616

17-
The ``Ĥ_0`` is the [Drift Term](@ref) and each term under the sum over ``l`` is a [Control Term](@ref). In the most general case, Eq. (G1), the control term is a Hamiltonian that depends on a set of control amplitudes. More commonly, the control term is separable into the [Control Amplitude](@ref) ``a_l(t)`` and the [Control Operator](@ref) ``Ĥ_l``. The control amplitude ``a_l(t)`` depends in term on the [Control Function](@ref) (or simply "control") ``ϵ_l(t)``, which is the function we can control directly. The control may further depend on a [Pulse Parametrization](@ref), ``ϵ_l(t) = ϵ_l(u_l(t))`` or a set of [Control Parameters](@ref), ``ϵ_l(t) = ϵ_l({u_n})``.
17+
The ``Ĥ_0`` is the [Drift Term](@ref) and each term under the sum over ``l`` is a [Control Term](@ref). In the most general case, Eq. (G1), the control term is a Hamiltonian that depends on a set of control amplitudes. More commonly, the control term is separable into the [Control Amplitude](@ref) ``a_l(t)`` and the [Control Operator](@ref) ``Ĥ_l``. The control amplitude ``a_l(t)`` depends in turn on the [Control Function](@ref) (or simply "control") ``ϵ_l(t)``, which is the function we can control directly. The control may further depend on a [Pulse Parametrization](@ref), ``ϵ_l(t) = ϵ_l(u_l(t))`` or a set of [Control Parameters](@ref), ``ϵ_l(t) = ϵ_l({u_n})``.
1818

1919
In an open quantum system, the structure of Eqs. (G1–G3) is the same, but with Liouvillian (super-)operators acting on density matrices instead of Hamiltonians acting on state vectors. See [`liouvillian`](@ref) with `convention=:TDSE`.
2020

docs/src/index.md

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# QuantumControl.jl
22

3-
[QuantumControl.jl](https://github.com/JuliaQuantumControl/QuantumControl.jl) is Julia framework for quantum optimal control.
3+
[QuantumControl.jl](https://github.com/JuliaQuantumControl/QuantumControl.jl@readme) is a [Julia framework for quantum optimal control](https://github.com/JuliaQuantumControl).
4+
5+
[Quantum optimal control](https://link.springer.com/article/10.1140%2Fepjd%2Fe2015-60464-1) attempts to steer a quantum system in some desired way by finding optimal control parameters or control fields inside the system Hamiltonian or Liouvillian. Typical control tasks are the preparation of a specific quantum state or the realization of a logical gate in a quantum computer (["pulse level control"](https://arxiv.org/abs/2004.06755)). Thus, quantum control theory is a critical part of realizing quantum technologies at the lowest level. Numerical methods of *open-loop* quantum control (methods that do not involve measurement feedback from a physical quantum device) such as [Krotov's method](https://github.com/JuliaQuantumControl/Krotov.jl) and [GRAPE](https://github.com/JuliaQuantumControl/GRAPE.jl) address the control problem by [simulating the dynamics of the system](https://github.com/JuliaQuantumControl/QuantumPropagators.jl) and then iteratively improving the value of a functional that encodes the desired outcome.
6+
7+
The `QuantumControl.jl` package collects the [packages](https://github.com/JuliaQuantumControl#packages) in the [JuliaQuantumControl](https://github.com/JuliaQuantumControl) organization and provides a single coherent [API](@ref quantum-control-api) for solving the quantum control problem.
8+
9+
10+
## Getting Started
11+
12+
* See the [installation instructions](https://github.com/JuliaQuantumControl/QuantumControl.jl#installation) on Github.
13+
14+
* Look at a [simple example for a state-to-state transition with Krotov's method](https://juliaquantumcontrol.github.io/Krotov.jl/stable/examples/simple_state_to_state/) to get a feeling for how the `QuantumControl` package is intended to be used, or look at the larger list of [Examples](@ref examples-list).
15+
16+
* Read the [Glossary](@ref) and [User Manual](@ref) to understand the philosophy of the framework.
417

518
## Contents
619

@@ -21,7 +34,7 @@ Pages = [
2134
]
2235
```
2336

24-
## API
37+
### API
2538

2639
```@contents
2740
Pages = [
@@ -30,7 +43,7 @@ Pages = [
3043
Depth = 1
3144
```
3245

33-
### Sub-Packages
46+
#### Sub-Packages
3447

3548
```@contents
3649
Pages = [

docs/src/manual.md

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,20 @@ The User Manual describes the API of the `QuantumControl` package by outlining t
44

55
## Setting up control problems
66

7-
* [`ControlProblem`](@ref)
8-
* [`Objective`](@ref)
9-
* [`WeightedObjective`](@ref)
7+
Quantum control problems are described by instantiating [`ControlProblem`](@ref). Remember that a quantum control problem aims to find control parameters in the dynamical generators (Hamiltonians, Liouvillians) of a quantum system to steer the dynamics of the system in some desired way. The dynamics of system are probed by one or more quantum states, each with its particular dynamical generator. To determine how well the system dynamics meet the desired behavior, we formulate an "objective" for each of those quantum states.
8+
9+
Most commonly, this is represented by instantiating an [`Objective`](@ref) which contains the initial state, the generator for that state's dynamics, and a target state. A time grid for the dynamics is part of [`ControlProblem`](@ref) as `tlist`. The objective is fulfilled when the control parameters are chosen such that the initial state evolves into the target state.
10+
11+
A control problem with a single such objective already encodes the common state-to-state problem, e.g. to initialize a system into an entangled state, or to control a chemical reaction. However, there are many control problems that require *simultaneously* solving more than one objective. For example, finding the control parameters that implement a two-qubit quantum gate ```` on a quantum computer naturally translates into four simultaneous objectives, one for each two-qubit basis state: ``|00⟩ → Ô |00⟩``, ``|01⟩ → Ô |01⟩``, ``|10⟩ → Ô |10⟩``, ``|00⟩ → Ô |11⟩``. By virtue of the linearity of Hilbert space, finding a simultaneous solution to these four objectives means the *any* state ``|Ψ⟩`` will then evolve as ``|Ψ⟩ → Ô |Ψ⟩``.
12+
13+
Some optimal control frameworks treat the optimization of quantum gates by numerically evolving the gate itself, ``Û(t=0) = I → Ô(t=T)``. This is perfectly compatible with our framework: we can have a single objective for an initial "state" ```` with a target "state" ````. However, this approach does not scale well numerically when the logical subspace of the two-qubit gate is embedded in a significantly larger physical Hilbert space: ```` is quadratically larger than ``|Ψ⟩``. Moreover, the various methods implemented in the `QuantumControl` package are inherently *parallel* with respect to multiple objectives. This is why we emphasize the formulation of the control problem in terms of multiple simultaneous objectives.
14+
15+
Sometimes, some of the objectives may be more important than others. In this case, instead of the standard [`Objective`](@ref), a [`WeightedObjective`](@ref) is available. There are also situations where the notion of a "target state" is not meaningful. Coming back to the example of two-qubit quantum gates, one may wish to maximize the entangling power of the quantum gate, without requiring a *specific* gate. We extract the information about the entangling power of the dynamical generator by tracking the time evolution of a set of states (the Bell basis, as it happens), but there is no meaningful notion of a "target state". In this example, a user may define their own objective as a subtype of [`QuantumControlBase.AbstractControlObjective`](@ref) and include only an initial state and the dynamical generator for that state, but no target state. Indeed, an initial state and a generator are the minimum components that constitute an objective.
16+
17+
Mathematically, the control problem is solved by minimizing a functional that is calculated from the time-propagated states in the objectives. By convention, this functional is passed as a keyword argument `J_T` when instantiating the [`ControlProblem`](@ref). Standard functionals are defined in [`QuantumControl.functionals`](../api/quantum_control/#QuantumControl.Functionals). Depending on the control method, there can be additional options, either mandatory (like the ``χ = ∂J_T/∂⟨ϕ|`` required for Krotov's method) or optional, like constraints on the control parameters. See the documentation of the various methods implementing [`optimize`](@ref) for the options required or supported by the different solvers. All of these options can be passed as keyword arguments when instantiating the [`ControlProblem`](@ref)[^1], or they can be passed later to [`optimize`](@ref)/[`@optimize_or_load`](@ref).
18+
19+
[^1]: The solvers that ship with `QuantumControl` ignore options they do not know about. So when setting up a [`ControlProblem`](@ref) it is safe to pass a superset of options for different optimization methods.
20+
1021

1122
## Controls and control parameters
1223

@@ -20,17 +31,20 @@ More generally, [`get_control_parameters`](@ref) extracts abstract "control para
2031

2132
## Time propagation
2233

23-
* [`propagate`](@ref)
24-
* [`propagate_objective`](@ref)
34+
The `QuantumControl` package uses (and includes) [`QuantumPropagators.jl`](https://github.com/JuliaQuantumControl/QuantumPropagators.jl) as the numerical back-end for simulating the time evolution of all quantum states. The main high-level function provided from that package is [`propagate`](@ref), which simulates the dynamics of a quantum state over an entire time grid. It does this by looping over calls to [`propstep`](@ref)/[`propstep!`](@ref), which simulate the dynamics for a single time step.
35+
36+
In the context of a [`ControlProblem`](@ref) consisting of one or more [`Objective`](@ref), there is also a [`propagate_objective`](@ref) function that provides a more convenient interface, automatically using the initial state and the dynamical generator from the objective.
37+
38+
A very typical overall workflow is to set up the control problem, then propagate the objectives with the guess control to see how the system behaves, run the optimization, and then propagate the objectives again with the optimized controls, to verify the success of the optimization. For plugging in the optimized controls, [`propagate_objective`](@ref) has a `controls_map` argument.
2539

2640

2741
## Optimization
2842

2943
The most direct way to solve a [`ControlProblem`](@ref) is with the [`optimize`](@ref) routine. It has a mandatory `method` argument that then delegates the optimization to the appropriate sub-package implementing that method. However, if the optimization takes more than a few minutes to complete, you should use [`@optimize_or_load`](@ref) instead of just [`optimize`](@ref). This routine runs the optimization and then write the result to file. When called again, it will then simply load the result instead of rerunning the optimization.
3044

31-
A workflow [`@optimize_or_load`](@ref) using integrates particularly well with using the [DrWatson](https://juliadynamics.github.io/DrWatson.jl/stable/) package to organize your research project[^1]. In fact, [`@optimize_or_load`](@ref) is directly inspired by [`DrWatson.produce_or_load`](https://juliadynamics.github.io/DrWatson.jl/stable/save/#Produce-or-Load-1) and uses it under the hood. Just like `produce_or_load`, [`@optimize_or_load`](@ref) by default chooses an automatic filename that includes the keyword arguments that define the [`ControlProblem`](@ref). That automatic filename is determined by the [`optimization_savename`](@ref) routine.
45+
A workflow [`@optimize_or_load`](@ref) using integrates particularly well with using the [DrWatson](https://juliadynamics.github.io/DrWatson.jl/stable/) package to organize your research project[^2]. In fact, [`@optimize_or_load`](@ref) is directly inspired by [`DrWatson.produce_or_load`](https://juliadynamics.github.io/DrWatson.jl/stable/save/#Produce-or-Load-1) and uses it under the hood. Just like `produce_or_load`, [`@optimize_or_load`](@ref) by default chooses an automatic filename that includes the keyword arguments that define the [`ControlProblem`](@ref). That automatic filename is determined by the [`optimization_savename`](@ref) routine.
3246

33-
[^1]: You are encouraged, but not *required* to use [DrWatson](https://juliadynamics.github.io/DrWatson.jl/stable/) for your projects. Here, we merely borrow some concepts from `DrWatson` for automatically storing computational results.
47+
[^2]: You are encouraged, but not *required* to use [DrWatson](https://juliadynamics.github.io/DrWatson.jl/stable/) for your projects. Here, we merely borrow some concepts from `DrWatson` for automatically storing computational results.
3448

3549
The [`@optimize_or_load`](@ref) also embeds some metadata in the output file, including (by default) the commit hash of the project repository containing the script that called [`@optimize_or_load`](@ref) and the filename of the script and line number where the call was made. This functionality is again borrowed from `DrWatson`.
3650

0 commit comments

Comments
 (0)