From 4c9dd3dff8614d72cb189b506c6e48f6bb0963d0 Mon Sep 17 00:00:00 2001 From: "Documenter.jl" Date: Mon, 27 Nov 2023 22:43:38 +0000 Subject: [PATCH] build based on 1aaa8cf --- .../examples/single_qubit/index.html | 2 +- .../man/problem_templates/index.html | 4 +- dev/generated/man/utils/index.html | 2 +- dev/generated/quickstart/index.html | 170 +++++++++--------- dev/index.html | 4 +- dev/lib/index.html | 10 +- dev/search/index.html | 2 +- dev/search_index.js | 2 +- 8 files changed, 98 insertions(+), 98 deletions(-) diff --git a/dev/generated/examples/single_qubit/index.html b/dev/generated/examples/single_qubit/index.html index c081cccc..9a378bb5 100644 --- a/dev/generated/examples/single_qubit/index.html +++ b/dev/generated/examples/single_qubit/index.html @@ -1,2 +1,2 @@ -Single Qubit · QuantumCollocation.jl
+Single Qubit · QuantumCollocation.jl
diff --git a/dev/generated/man/problem_templates/index.html b/dev/generated/man/problem_templates/index.html index d1c1d1c2..63055814 100644 --- a/dev/generated/man/problem_templates/index.html +++ b/dev/generated/man/problem_templates/index.html @@ -1,5 +1,5 @@ -Problem Templates · QuantumCollocation.jl

Problem Templates

We provide a number of problem templates for making it simple and easy to set up and solve certain types of quantum optimal control problems. These templates all construct a QuantumControlProblem object. The problem templates are:

Unitary Smooth Pulse Problem

QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblemFunction
UnitarySmoothPulseProblem(H_drift, H_drives, U_goal, T, Δt; kwargs...)
+Problem Templates · QuantumCollocation.jl

Problem Templates

We provide a number of problem templates for making it simple and easy to set up and solve certain types of quantum optimal control problems. These templates all construct a QuantumControlProblem object. The problem templates are:

Unitary Smooth Pulse Problem

QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblemFunction
UnitarySmoothPulseProblem(H_drift, H_drives, U_goal, T, Δt; kwargs...)
 UnitarySmoothPulseProblem(system::QuantumSystem, U_goal, T, Δt; kwargs...)

Construct a QuantumControlProblem for a free-time unitary gate problem with smooth control pulses enforced by constraining the second derivative of the pulse trajectory, i.e.,

\[\begin{aligned} \underset{\vec{\tilde{U}}, a, \dot{a}, \ddot{a}, \Delta t}{\text{minimize}} & \quad Q \cdot \ell\qty(\vec{\tilde{U}}_T, \vec{\tilde{U}}_{\text{goal}}) + \frac{1}{2} \sum_t \qty(R_a a_t^2 + R_{\dot{a}} \dot{a}_t^2 + R_{\ddot{a}} \ddot{a}_t^2) \\ @@ -10,4 +10,4 @@ & \quad |\ddot{a}_t| \leq \ddot{a}_{\text{bound}} \\ & \quad \Delta t_{\text{min}} \leq \Delta t_t \leq \Delta t_{\text{max}} \\ \end{aligned}\]

where, for $U \in SU(N)$,

\[\ell\qty(\vec{\tilde{U}}_T, \vec{\tilde{U}}_{\text{goal}}) = -\abs{1 - \frac{1}{N} \abs{ \tr \qty(U_{\text{goal}}, U_T)} }\]

is the infidelity objective function, $Q$ is a weight, $R_a$, $R_{\dot{a}}$, and $R_{\ddot{a}}$ are weights on the regularization terms, and $\vb{P}^{(n)}$ is the $n$th-order Pade integrator.

Arguments

  • H_drift::AbstractMatrix{<:Number}: the drift hamiltonian
  • H_drives::Vector{<:AbstractMatrix{<:Number}}: the control hamiltonians

or

  • system::QuantumSystem: the system to be controlled

with

  • U_goal::AbstractMatrix{<:Number}: the target unitary
  • T::Int: the number of timesteps
  • Δt::Float64: the (initial) time step size

Keyword Arguments

  • free_time::Bool=true: whether or not to allow the time steps to vary
  • init_trajectory::Union{NamedTrajectory, Nothing}=nothing: an initial trajectory to use
  • a_bound::Float64=1.0: the bound on the control pulse
  • a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives)): the bounds on the control pulses, one for each drive
  • a_guess::Union{Matrix{Float64}, Nothing}=nothing: an initial guess for the control pulses
  • dda_bound::Float64=1.0: the bound on the control pulse derivative
  • dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): the bounds on the control pulse derivatives, one for each drive
  • Δt_min::Float64=0.5 * Δt: the minimum time step size
  • Δt_max::Float64=1.5 * Δt: the maximum time step size
  • drive_derivative_σ::Float64=0.01: the standard deviation of the initial guess for the control pulse derivatives
  • Q::Float64=100.0: the weight on the infidelity objective
  • R=1e-2: the weight on the regularization terms
  • R_a::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulses
  • R_da::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse derivatives
  • R_dda::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse second derivatives
  • leakage_suppression::Bool=false: whether or not to suppress leakage to higher energy states
  • leakage_indices::Union{Nothing, Vector{Int}}=nothing: the indices of $\vec{\tilde{U}}$ corresponding leakage operators that should be suppressed
  • system_levels::Union{Nothing, Vector{Int}}=nothing: the number of levels in each subsystem
  • R_leakage=1e-1: the weight on the leakage suppression term
  • max_iter::Int=1000: the maximum number of iterations for the solver
  • linear_solver::String="mumps": the linear solver to use
  • ipopt_options::Options=Options(): the options for the Ipopt solver
  • constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: additional constraints to add to the problem
  • timesteps_all_equal::Bool=true: whether or not to enforce that all time steps are equal
  • verbose::Bool=false: whether or not to print constructor output
  • U_init::Union{AbstractMatrix{<:Number},Nothing}=nothing: an initial guess for the unitary
  • integrator=Integrators.fourth_order_pade: the integrator to use for the unitary
  • geodesic=true: whether or not to use the geodesic as the initial guess for the unitary
  • pade_order=4: the order of the Pade approximation to use for the unitary integrator
  • autodiff=pade_order != 4: whether or not to use automatic differentiation for the unitary integrator
  • subspace=nothing: the subspace to use for the unitary integrator
  • jacobian_structure=true: whether or not to use the jacobian structure
  • hessian_approximation=false: whether or not to use L-BFGS hessian approximation in Ipopt
  • blas_multithreading=true: whether or not to use multithreading in BLAS
source

Unitary Minimum Time Problem


This page was generated using Literate.jl.

+\abs{1 - \frac{1}{N} \abs{ \tr \qty(U_{\text{goal}}, U_T)} }\]

is the infidelity objective function, $Q$ is a weight, $R_a$, $R_{\dot{a}}$, and $R_{\ddot{a}}$ are weights on the regularization terms, and $\vb{P}^{(n)}$ is the $n$th-order Pade integrator.

Arguments

  • H_drift::AbstractMatrix{<:Number}: the drift hamiltonian
  • H_drives::Vector{<:AbstractMatrix{<:Number}}: the control hamiltonians

or

  • system::QuantumSystem: the system to be controlled

with

  • U_goal::AbstractMatrix{<:Number}: the target unitary
  • T::Int: the number of timesteps
  • Δt::Float64: the (initial) time step size

Keyword Arguments

  • free_time::Bool=true: whether or not to allow the time steps to vary
  • init_trajectory::Union{NamedTrajectory, Nothing}=nothing: an initial trajectory to use
  • a_bound::Float64=1.0: the bound on the control pulse
  • a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives)): the bounds on the control pulses, one for each drive
  • a_guess::Union{Matrix{Float64}, Nothing}=nothing: an initial guess for the control pulses
  • dda_bound::Float64=1.0: the bound on the control pulse derivative
  • dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): the bounds on the control pulse derivatives, one for each drive
  • Δt_min::Float64=0.5 * Δt: the minimum time step size
  • Δt_max::Float64=1.5 * Δt: the maximum time step size
  • drive_derivative_σ::Float64=0.01: the standard deviation of the initial guess for the control pulse derivatives
  • Q::Float64=100.0: the weight on the infidelity objective
  • R=1e-2: the weight on the regularization terms
  • R_a::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulses
  • R_da::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse derivatives
  • R_dda::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse second derivatives
  • leakage_suppression::Bool=false: whether or not to suppress leakage to higher energy states
  • leakage_indices::Union{Nothing, Vector{Int}}=nothing: the indices of $\vec{\tilde{U}}$ corresponding leakage operators that should be suppressed
  • system_levels::Union{Nothing, Vector{Int}}=nothing: the number of levels in each subsystem
  • R_leakage=1e-1: the weight on the leakage suppression term
  • max_iter::Int=1000: the maximum number of iterations for the solver
  • linear_solver::String="mumps": the linear solver to use
  • ipopt_options::Options=Options(): the options for the Ipopt solver
  • constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: additional constraints to add to the problem
  • timesteps_all_equal::Bool=true: whether or not to enforce that all time steps are equal
  • verbose::Bool=false: whether or not to print constructor output
  • U_init::Union{AbstractMatrix{<:Number},Nothing}=nothing: an initial guess for the unitary
  • integrator=Integrators.fourth_order_pade: the integrator to use for the unitary
  • geodesic=true: whether or not to use the geodesic as the initial guess for the unitary
  • pade_order=4: the order of the Pade approximation to use for the unitary integrator
  • autodiff=pade_order != 4: whether or not to use automatic differentiation for the unitary integrator
  • subspace=nothing: the subspace to use for the unitary integrator
  • jacobian_structure=true: whether or not to use the jacobian structure
  • hessian_approximation=false: whether or not to use L-BFGS hessian approximation in Ipopt
  • blas_multithreading=true: whether or not to use multithreading in BLAS
source

Unitary Minimum Time Problem


This page was generated using Literate.jl.

diff --git a/dev/generated/man/utils/index.html b/dev/generated/man/utils/index.html index ebe15ad9..115d9b42 100644 --- a/dev/generated/man/utils/index.html +++ b/dev/generated/man/utils/index.html @@ -1,2 +1,2 @@ -Utilities · QuantumCollocation.jl
+Utilities · QuantumCollocation.jl diff --git a/dev/generated/quickstart/index.html b/dev/generated/quickstart/index.html index f4bdf2af..7c546813 100644 --- a/dev/generated/quickstart/index.html +++ b/dev/generated/quickstart/index.html @@ -1,5 +1,5 @@ -Quickstart Guide · QuantumCollocation.jl

Quickstart Guide

To set up and solve a quantum optimal control problems we provide high level problem templates to quickly get started. For unitary gate problems, where we want to realize a gate $U_{\text{goal}}$, with a system Hamiltonian of the form,

\[H(t) = H_0 + \sum_i a^i(t) H_i\]

there is the UnitarySmoothPulseProblem constructor which only requires

  • the drift Hamiltonian, $H_0$
  • the drive Hamiltonians, $\qty{H_i}$
  • the target unitary, $U_{\text{goal}}$
  • the number of timesteps, $T$
  • the (initial) time step size, $\Delta t$

Basic Usage

For example, to create a problem for a single qubit $X$ gate (with a bound on the drive of $|a| < a_{\text{bound}}$), i.e., with system hamiltonian

\[H(t) = \frac{\omega}{2} \sigma_z + a^1(t) \sigma_x + a^2(t) \sigma_y\]

we can do the following:

using NamedTrajectories
+Quickstart Guide · QuantumCollocation.jl

Quickstart Guide

To set up and solve a quantum optimal control problems we provide high level problem templates to quickly get started. For unitary gate problems, where we want to realize a gate $U_{\text{goal}}$, with a system Hamiltonian of the form,

\[H(t) = H_0 + \sum_i a^i(t) H_i\]

there is the UnitarySmoothPulseProblem constructor which only requires

  • the drift Hamiltonian, $H_0$
  • the drive Hamiltonians, $\qty{H_i}$
  • the target unitary, $U_{\text{goal}}$
  • the number of timesteps, $T$
  • the (initial) time step size, $\Delta t$

Basic Usage

For example, to create a problem for a single qubit $X$ gate (with a bound on the drive of $|a| < a_{\text{bound}}$), i.e., with system hamiltonian

\[H(t) = \frac{\omega}{2} \sigma_z + a^1(t) \sigma_x + a^2(t) \sigma_y\]

we can do the following:

using NamedTrajectories
 using QuantumCollocation
 
 # set time parameters
@@ -63,62 +63,62 @@
         inequality constraints with only upper bounds:        0
 
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-   0  3.2865522e-01 1.82e+00 7.45e-04  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
-   1  5.1485409e+01 3.80e-01 4.99e+01  -1.0 3.29e+00    -  2.34e-02 1.00e+00h  1
-   2  6.0231611e+01 5.40e-02 1.84e+03  -1.0 9.21e-01   2.0 5.30e-01 1.00e+00h  1
-   3  6.7845411e+01 3.77e-02 1.58e+03  -1.0 1.13e+00   2.4 8.95e-01 3.05e-01h  1
-   4  7.6282934e+01 1.52e-02 4.87e+02  -1.0 8.50e-01   1.9 1.00e+00 6.07e-01h  1
-   5  8.9657398e+01 7.45e-03 3.40e+02  -1.0 4.41e-01   1.5 9.05e-01 8.70e-01h  1
-   6  8.7139569e+01 3.33e-04 4.94e+01  -1.0 1.07e-01   1.9 1.00e+00 1.00e+00f  1
-   7  8.0398244e+01 9.24e-05 1.82e+00  -1.0 7.01e-02   1.4 1.00e+00 1.00e+00f  1
-   8  6.0724265e+01 7.46e-04 1.73e+00  -1.0 1.97e-01   0.9 1.00e+00 1.00e+00f  1
-   9  1.1371278e+01 6.16e-03 5.25e+00  -1.0 4.98e-01   0.5 8.78e-01 1.00e+00f  1
+   0  3.6134872e-01 1.84e+00 7.73e-04  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
+   1  8.0505444e+01 3.31e-01 8.10e+01  -1.0 2.59e+00    -  1.20e-02 1.00e+00h  1
+   2  3.6438626e+01 5.20e-02 2.08e+03  -1.0 1.02e+00   2.0 1.51e-01 1.00e+00f  1
+   3  2.3166917e+01 1.55e-01 2.40e+03  -1.0 2.11e+00   1.5 5.08e-01 1.00e+00f  1
+   4  5.3411061e+01 3.63e-02 2.19e+03  -1.0 1.09e+00   1.9 7.22e-01 1.00e+00h  1
+   5  6.9928573e+01 2.61e-02 1.62e+03  -1.0 9.23e-01   1.5 8.50e-01 3.09e-01h  1
+   6  6.4999434e+01 1.54e-02 9.98e+02  -1.0 3.84e-01   1.9 1.00e+00 4.11e-01f  1
+   7  5.4174654e+01 6.48e-04 4.16e+01  -1.0 2.29e-01   1.4 1.00e+00 1.00e+00f  1
+   8  4.4027933e+01 3.05e-04 6.73e+00  -1.0 1.06e-01   0.9 1.00e+00 1.00e+00f  1
+   9  2.4515993e+01 1.52e-03 1.45e+00  -1.0 3.37e-01   0.5 1.00e+00 1.00e+00f  1
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  10  1.2185168e+00 3.68e-03 9.99e+01  -1.0 6.01e-01  -0.0 1.00e+00 1.00e+00F  1
-  11  1.6067400e+00 1.75e-03 1.00e+02  -1.0 2.62e-01  -0.5 1.00e+00 1.00e+00h  1
-  12  3.2819501e-01 4.62e-05 1.26e+00  -1.0 3.62e-02   0.8 1.00e+00 1.00e+00f  1
-  13  1.8254973e-01 1.48e-02 1.00e+02  -1.0 1.06e+00    -  1.00e+00 5.00e-01f  2
-  14  1.4312884e+00 1.49e-02 1.90e+00  -1.0 3.73e+00    -  4.18e-01 1.86e-02h  5
-  15  3.8022225e-01 1.57e-02 9.91e+01  -1.0 8.57e-01    -  9.89e-01 5.00e-01f  2
-  16  4.8615720e-01 1.57e-02 1.52e+00  -1.0 4.54e+00    -  4.14e-01 4.45e-03h  7
-  17  5.4097888e-01 8.94e-03 9.93e+01  -1.0 5.56e-01    -  1.00e+00 5.00e-01f  2
-  18  6.9215755e-01 8.90e-03 1.37e+00  -1.0 4.55e+00    -  4.29e-01 6.84e-03h  7
-  19  3.5594127e+00 1.84e-03 1.00e+02  -1.0 1.84e-01    -  1.00e+00 1.00e+00h  1
+  10  3.5508764e+00 5.25e-03 9.97e+01  -1.0 4.53e-01  -0.0 9.30e-01 1.00e+00f  1
+  11  1.6544264e+01 2.43e-03 9.99e+01  -1.0 4.95e-01  -0.5 7.83e-01 1.00e+00H  1
+  12  9.8577410e+00 3.61e-04 1.14e+01  -1.0 1.21e-01   0.8 1.00e+00 1.00e+00f  1
+  13  4.3759193e+00 4.93e-04 7.56e-01  -1.0 1.22e-01   0.4 1.00e+00 1.00e+00f  1
+  14  1.5615115e+00 2.26e-02 9.99e+01  -1.7 1.90e+00    -  3.66e-01 4.03e-01f  1
+  15  4.0587529e+01 1.93e-02 9.97e+01  -1.7 7.17e-01  -0.1 2.49e-01 1.00e+00h  1
+  16  5.1606930e+00 1.93e-03 2.21e+01  -1.7 3.54e-01   1.2 1.00e+00 1.00e+00f  1
+  17  3.8495225e+00 1.41e-03 9.95e+01  -1.7 2.27e-01   0.7 1.00e+00 1.00e+00f  1
+  18  9.2348603e-01 4.53e-05 9.99e+01  -1.7 5.64e-02   0.3 1.00e+00 1.00e+00f  1
+  19  3.5046087e-01 9.09e-05 2.69e+00  -1.7 5.48e-02   0.7 1.00e+00 1.00e+00f  1
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  20  7.9678660e-02 8.96e-03 8.34e+01  -1.0 2.74e+00    -  1.00e+00 1.66e-01f  3
-  21  3.3217237e+00 1.45e-03 9.99e+01  -1.0 1.75e-01   0.4 1.00e+00 1.00e+00h  1
-  22  2.3236235e-01 3.15e-05 2.61e+00  -1.0 3.28e-02   0.8 1.00e+00 1.00e+00f  1
-  23  2.2293927e-01 9.83e-06 1.45e-01  -1.0 1.68e-02   0.3 1.00e+00 1.00e+00h  1
-  24  9.4153854e-02 2.82e-04 1.00e+02  -2.5 6.18e-02    -  9.46e-01 1.00e+00F  1
-  25  1.0382933e-01 2.91e-04 3.12e+00  -2.5 9.13e-01    -  5.60e-01 3.12e-02h  6
-  26  9.2972196e-02 2.20e-06 1.00e+02  -2.5 5.73e-03  -0.2 1.00e+00 1.00e+00h  1
-  27  4.6456534e-02 5.31e-03 1.00e+02  -2.5 3.04e-01    -  1.00e+00 1.00e+00f  1
-  28  1.0708486e-01 1.77e-04 3.20e+00  -2.5 5.62e-02   1.2 1.00e+00 1.00e+00h  1
-  29  6.5339602e-02 9.75e-07 6.06e-02  -2.5 6.33e-03   0.7 1.00e+00 1.00e+00h  1
+  20  3.7758747e-01 3.71e-05 1.23e-01  -1.7 3.23e-02   0.2 1.00e+00 1.00e+00h  1
+  21  3.4396165e-01 6.66e-04 1.00e+02  -2.5 1.55e-01    -  8.72e-01 1.00e+00f  1
+  22  3.2765853e-01 2.12e-03 9.68e+00  -2.5 2.63e+00    -  2.93e-01 9.68e-02f  4
+  23  3.5046717e-01 1.08e-04 1.00e+02  -2.5 3.64e-02  -0.3 1.00e+00 1.00e+00h  1
+  24  1.8257575e-01 8.37e-03 5.00e+01  -2.5 7.97e-01    -  1.00e+00 5.00e-01f  2
+  25  2.5810400e+00 1.20e-03 3.27e+01  -2.5 3.28e-01   0.2 1.00e+00 1.00e+00H  1
+  26  1.2625273e+00 8.42e-05 8.23e-01  -2.5 5.68e-02   0.6 1.00e+00 1.00e+00f  1
+  27  4.1989900e-01 1.56e-04 1.00e+02  -2.5 7.52e-02   0.1 1.00e+00 1.00e+00f  1
+  28  7.3947826e-01 8.50e-05 1.00e+02  -2.5 4.32e-02  -0.4 1.00e+00 1.00e+00h  1
+  29  5.3180544e-01 1.47e-05 2.46e+00  -2.5 2.20e-02   1.0 1.00e+00 1.00e+00f  1
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  30  5.0239738e-02 1.47e-06 1.00e+02  -2.5 9.49e-03   0.2 1.00e+00 1.00e+00h  1
+  30  2.9054445e-01 1.60e-05 8.20e-02  -2.5 2.70e-02   0.5 1.00e+00 1.00e+00f  1
 
 Number of Iterations....: 30
 
                                    (scaled)                 (unscaled)
-Objective...............:   5.0239737783438820e-02    5.0239737783438820e-02
-Dual infeasibility......:   9.9999726990805073e+01    9.9999726990805073e+01
-Constraint violation....:   1.4715037973678236e-06    1.4715037973678236e-06
+Objective...............:   2.9054445495569414e-01    2.9054445495569414e-01
+Dual infeasibility......:   8.1962196152606623e-02    8.1962196152606623e-02
+Constraint violation....:   1.5959784889219009e-05    1.5959784889219009e-05
 Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
-Complementarity.........:   2.8284271247461909e-03    2.8284271247461909e-03
-Overall NLP error.......:   9.9999726990805073e+01    9.9999726990805073e+01
+Complementarity.........:   2.8284271247400942e-03    2.8284271247400942e-03
+Overall NLP error.......:   8.1962196152606623e-02    8.1962196152606623e-02
 
 
-Number of objective function evaluations             = 69
+Number of objective function evaluations             = 45
 Number of objective gradient evaluations             = 31
-Number of equality constraint evaluations            = 69
+Number of equality constraint evaluations            = 45
 Number of inequality constraint evaluations          = 0
 Number of equality constraint Jacobian evaluations   = 31
 Number of inequality constraint Jacobian evaluations = 0
 Number of Lagrangian Hessian evaluations             = 30
-Total seconds in IPOPT                               = 11.377
+Total seconds in IPOPT                               = 11.430
 
-EXIT: Maximum Number of Iterations Exceeded.

The above output comes from the Ipopt.jl solver. To see the final fidelity we can use the unitary_fidelity function exported by QuantumCollocation.jl.

println("Final fidelity: ", unitary_fidelity(prob))
Final fidelity: 0.9999648888750698

We can also easily plot the solutions using the plot function exported by NamedTrajectories.jl.

plot(prob.trajectory, [:Ũ⃗, :a])

Minimum Time Problems

We can also easily set up and solve a minimum time problem, where we enforce a constraint on the final fidelity:

\[\mathcal{F}(U_T, U_{\text{goal}}) \geq \mathcal{F}_{\text{min}}\]

Using the problem we just solved we can do the following:

# final fidelity constraint
+EXIT: Maximum Number of Iterations Exceeded.

The above output comes from the Ipopt.jl solver. To see the final fidelity we can use the unitary_fidelity function exported by QuantumCollocation.jl.

println("Final fidelity: ", unitary_fidelity(prob))
Final fidelity: 0.9982650392477267

We can also easily plot the solutions using the plot function exported by NamedTrajectories.jl.

plot(prob.trajectory, [:Ũ⃗, :a])

Minimum Time Problems

We can also easily set up and solve a minimum time problem, where we enforce a constraint on the final fidelity:

\[\mathcal{F}(U_T, U_{\text{goal}}) \geq \mathcal{F}_{\text{min}}\]

Using the problem we just solved we can do the following:

# final fidelity constraint
 final_fidelity = 0.99
 
 # weight on the minimum time objective
@@ -154,66 +154,66 @@
         inequality constraints with only upper bounds:        0
 
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-   0  1.0812072e+00 1.47e-06 1.87e-02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
-   1  1.0838011e+00 3.22e-09 1.00e+02  -1.0 2.21e-04   2.0 1.00e+00 1.00e+00h  1
-   2  1.0835418e+00 1.24e-08 2.84e-02  -1.0 5.48e-04   1.5 1.00e+00 1.00e+00f  1
-   3  1.0716495e+00 6.11e-05 1.00e+02  -2.5 4.52e-02    -  1.00e+00 1.00e+00f  1
-   4  1.0684735e+00 5.73e-08 1.00e+02  -2.5 9.77e-04   1.0 1.00e+00 1.00e+00h  1
-   5  1.0679942e+00 4.77e-08 6.59e-02  -2.5 7.68e-04   0.6 1.00e+00 1.00e+00h  1
-   6  1.0670665e+00 1.94e-07 2.22e-03  -2.5 1.80e-03   0.1 1.00e+00 1.00e+00h  1
-   7  1.0641621e+00 1.79e-06 2.22e-03  -3.8 5.46e-03  -0.4 1.00e+00 1.00e+00h  1
-   8  1.0555558e+00 1.62e-05 2.22e-03  -3.8 1.65e-02  -0.9 1.00e+00 1.00e+00h  1
-   9  1.0309645e+00 1.41e-04 1.00e+02  -3.8 4.95e-02  -1.3 1.00e+00 1.00e+00h  1
+   0  1.0655842e+00 1.60e-05 7.60e-02  -1.0 0.00e+00    -  0.00e+00 0.00e+00   0
+   1  1.3342841e+00 7.63e-04 1.00e+02  -1.0 9.84e-02    -  9.96e-01 1.00e+00f  1
+   2  1.8718484e+00 3.03e-02 1.00e+02  -1.0 7.13e-01    -  1.00e+00 1.00e+00f  1
+   3  4.8185833e+00 5.12e-03 2.22e+02  -1.0 2.27e-01   2.0 6.41e-02 1.00e+00h  1
+   4  1.9504039e+00 5.04e-04 8.95e+01  -1.0 9.35e-02   1.5 1.00e+00 9.07e-01f  1
+   5  1.0274773e+00 9.86e-05 8.60e+00  -1.0 4.97e-02   1.0 1.00e+00 1.00e+00f  1
+   6  1.1192929e+00 1.18e-05 1.26e+00  -1.0 2.01e-02   0.6 1.00e+00 1.00e+00h  1
+   7  1.1484144e+00 2.01e-03 1.00e+02  -1.0 2.10e-01    -  1.00e+00 1.00e+00f  1
+   8  1.2867442e+00 1.31e-04 1.00e+02  -1.0 5.06e-02   0.1 1.00e+00 1.00e+00h  1
+   9  1.0900219e+00 4.39e-05 1.00e+02  -1.0 3.21e-02   0.5 1.00e+00 1.00e+00f  1
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  10  1.0333690e+00 1.25e-04 1.25e+01  -3.8 2.95e-01  -1.8 1.00e+00 1.25e-01h  4
-  11  1.0020021e+00 4.12e-04 1.00e+02  -3.8 7.46e-02  -1.4 1.00e+00 1.00e+00h  1
-  12  9.8875417e-01 3.89e-04 9.71e+00  -3.8 1.14e-01  -1.0 1.00e+00 1.00e+00H  1
-  13  9.7978464e-01 3.21e-07 1.00e+02  -3.8 3.64e-03   1.3 1.00e+00 1.00e+00h  1
-  14  9.7886353e-01 1.21e-07 1.00e+02  -3.8 1.85e-03   0.8 1.00e+00 1.00e+00h  1
-  15  9.7871144e-01 9.07e-08 1.00e+02  -3.8 1.22e-03   0.3 1.00e+00 1.00e+00h  1
-  16  9.7825404e-01 9.76e-08 5.34e-02  -3.8 1.65e-03   0.7 1.00e+00 1.00e+00h  1
-  17  9.7792495e-01 4.88e-08 2.06e-03  -3.8 1.13e-03   0.3 1.00e+00 1.00e+00h  1
-  18  9.7660206e-01 4.39e-07 2.05e-03  -3.8 3.37e-03  -0.2 1.00e+00 1.00e+00h  1
-  19  9.7270334e-01 3.92e-06 1.98e-03  -3.8 9.99e-03  -0.7 1.00e+00 1.00e+00h  1
+  10  1.1818788e+00 1.70e-05 1.00e+02  -1.0 2.38e-02   0.0 1.00e+00 1.00e+00h  1
+  11  1.0470394e+00 2.97e-05 1.25e+01  -1.0 1.97e-01   0.5 7.96e-01 1.25e-01f  4
+  12  1.1515428e+00 5.41e-06 1.00e+02  -1.0 1.46e-02   0.9 1.00e+00 1.00e+00h  1
+  13  1.0547082e+00 1.62e-05 9.37e+01  -1.0 3.39e-01   0.4 5.97e-01 6.25e-02f  5
+  14  1.0616378e+00 2.53e-06 1.99e-01  -1.0 1.07e-02   0.8 1.00e+00 1.00e+00h  1
+  15  1.0544169e+00 1.96e-05 1.00e+02  -2.5 1.77e-02    -  9.99e-01 1.00e+00f  1
+  16  8.0395487e-01 1.33e-02 1.75e+01  -2.5 5.47e-01    -  1.00e+00 1.00e+00f  1
+  17  1.8542042e+00 3.47e-03 1.00e+02  -2.5 2.23e-01   0.4 1.00e+00 7.91e-01h  1
+  18  1.5442275e+00 1.82e-04 3.43e+00  -2.5 6.20e-02   0.8 1.00e+00 1.00e+00h  1
+  19  1.2357364e+00 3.34e-05 2.55e+01  -2.5 3.30e-02   0.3 5.22e-01 1.00e+00f  1
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  20  9.6147592e-01 3.39e-05 2.65e-03  -3.8 2.87e-02  -1.2 1.00e+00 1.00e+00h  1
-  21  9.3163749e-01 2.66e-04 1.00e+02  -3.8 7.56e-02  -1.6 1.00e+00 1.00e+00h  1
-  22  9.4956646e-01 2.72e-04 6.25e+00  -3.8 7.58e-01  -2.1 1.00e+00 6.25e-02h  5
-  23  9.0930748e-01 6.98e-04 1.00e+02  -3.8 1.31e-01  -1.7 1.00e+00 1.00e+00h  1
-  24  9.1647411e-01 6.28e-04 1.25e+01  -3.8 3.17e-01  -1.3 1.00e+00 1.25e-01h  4
-  25  8.8760371e-01 6.17e-04 1.00e+02  -3.8 1.31e-01  -1.7 1.00e+00 1.00e+00h  1
-  26  8.6674571e-01 5.89e-04 1.25e+01  -3.8 3.86e-01  -1.3 1.00e+00 1.25e-01h  4
-  27  8.4534097e-01 5.21e-06 1.00e+02  -3.8 1.57e-02  -0.9 1.00e+00 1.00e+00h  1
-  28  8.3116512e-01 4.71e-05 1.00e+02  -3.8 3.35e-02  -1.4 1.00e+00 1.00e+00h  1
-  29  8.3064120e-01 3.22e-08 1.36e-01  -3.8 1.26e-03   0.9 1.00e+00 1.00e+00h  1
+  20  1.1805693e+00 1.38e-04 1.00e+02  -2.5 7.05e-02  -0.2 1.00e+00 1.00e+00f  1
+  21  8.9582307e-01 1.25e-05 1.00e+02  -2.5 3.08e-02  -0.6 1.00e+00 1.00e+00f  1
+  22  8.6850725e-01 2.80e-06 1.03e+00  -2.5 1.06e-02   0.7 1.00e+00 1.00e+00h  1
+  23  8.6038707e-01 7.44e-07 1.12e-02  -2.5 6.92e-03   0.2 1.00e+00 1.00e+00h  1
+  24  8.0213434e-01 1.31e-02 1.00e+02  -3.8 5.47e-01    -  7.62e-01 1.00e+00f  1
+  25  1.8128187e+00 1.31e-02 8.65e-01  -3.8 8.13e+00    -  7.68e-02 6.74e-03h  1
+  26  1.7939620e+00 1.62e-03 2.03e+00  -3.8 2.83e-01    -  3.20e-01 1.00e+00h  1
+  27  1.5723072e+00 6.30e-03 1.98e+00  -3.8 3.24e-01    -  2.27e-01 8.86e-02F  1
+  28  8.4327569e-01 2.60e-03 1.00e+02  -3.8 3.16e-01    -  2.68e-01 1.00e+00f  1
+  29  7.8056136e-01 2.60e-03 5.58e-01  -3.8 5.59e+00    -  4.03e-02 2.94e-03f  5
 iter    objective    inf_pr   inf_du lg(mu)  ||d||  lg(rg) alpha_du alpha_pr  ls
-  30  7.9687101e-01 7.00e-04 1.00e+02  -3.8 1.31e-01    -  1.00e+00 1.00e+00f  1
+  30  8.2968081e-01 1.50e-03 1.00e+02  -3.8 2.87e-01    -  9.72e-01 1.00e+00h  1
 
 Number of Iterations....: 30
 
                                    (scaled)                 (unscaled)
-Objective...............:   7.9687100813201683e-01    7.9687100813201683e-01
-Dual infeasibility......:   1.0000008671013686e+02    1.0000008671013686e+02
-Constraint violation....:   7.0011322413687793e-04    7.0011322413687793e-04
+Objective...............:   8.2968081297708718e-01    8.2968081297708718e-01
+Dual infeasibility......:   1.0000002378116011e+02    1.0000002378116011e+02
+Constraint violation....:   1.4968302677493828e-03    1.4968302677493828e-03
 Variable bound violation:   0.0000000000000000e+00    0.0000000000000000e+00
-Complementarity.........:   1.5042412372345582e-04    1.5042412372345582e-04
-Overall NLP error.......:   1.0000008671013686e+02    1.0000008671013686e+02
+Complementarity.........:   2.4338582258984229e-04    2.4338582258984229e-04
+Overall NLP error.......:   1.0000002378116011e+02    1.0000002378116011e+02
 
 
-Number of objective function evaluations             = 49
+Number of objective function evaluations             = 50
 Number of objective gradient evaluations             = 31
-Number of equality constraint evaluations            = 49
-Number of inequality constraint evaluations          = 49
+Number of equality constraint evaluations            = 50
+Number of inequality constraint evaluations          = 50
 Number of equality constraint Jacobian evaluations   = 31
 Number of inequality constraint Jacobian evaluations = 31
 Number of Lagrangian Hessian evaluations             = 30
-Total seconds in IPOPT                               = 8.062
+Total seconds in IPOPT                               = 8.059
 
-EXIT: Maximum Number of Iterations Exceeded.

We can see that the final fidelity is indeed greater than the minimum fidelity we set.

println("Final fidelity:    ", unitary_fidelity(prob_min_time))
Final fidelity:    0.9999280093545919

and that the duration of the pulse has decreased.

initial_dur = times(prob.trajectory)[end]
+EXIT: Maximum Number of Iterations Exceeded.

We can see that the final fidelity is indeed greater than the minimum fidelity we set.

println("Final fidelity:    ", unitary_fidelity(prob_min_time))
Final fidelity:    0.9998599142083162

and that the duration of the pulse has decreased.

initial_dur = times(prob.trajectory)[end]
 min_time_dur = times(prob_min_time.trajectory)[end]
 
 println("Initial duration:  ", initial_dur)
 println("Minimum duration:  ", min_time_dur)
-println("Duration decrease: ", initial_dur - min_time_dur)
Initial duration:  10.206578029385184
-Minimum duration:  6.456239213807268
-Duration decrease: 3.7503388155779165

We can also plot the solutions for the minimum time problem.

plot(prob_min_time.trajectory, [:Ũ⃗, :a])

This page was generated using Literate.jl.

+println("Duration decrease: ", initial_dur - min_time_dur)
Initial duration:  7.672893926408225
+Minimum duration:  5.507298517827605
+Duration decrease: 2.1655954085806197

We can also plot the solutions for the minimum time problem.

plot(prob_min_time.trajectory, [:Ũ⃗, :a])

This page was generated using Literate.jl.

diff --git a/dev/index.html b/dev/index.html index 9fed2312..67e659ab 100644 --- a/dev/index.html +++ b/dev/index.html @@ -1,9 +1,9 @@ -Home · QuantumCollocation.jl

QuantumCollocation.jl

Direct Collocation for Quantum Optimal Control (arXiv)

Motivation

In quantum optimal control, we are interested in finding a pulse sequence $a_{1:T-1}$ to drive a quantum system and realize a target gate $U_{\text{goal}}$. We formulate this problem as a nonlinear program (NLP) of the form

\[\begin{aligned} +Home · QuantumCollocation.jl

QuantumCollocation.jl

Direct Collocation for Quantum Optimal Control (arXiv)

Motivation

In quantum optimal control, we are interested in finding a pulse sequence $a_{1:T-1}$ to drive a quantum system and realize a target gate $U_{\text{goal}}$. We formulate this problem as a nonlinear program (NLP) of the form

\[\begin{aligned} \underset{U_{1:T}, a_{1:T-1}}{\text{minimize}} & \quad \ell(U_T, U_{\text{goal}})\\ \text{ subject to } & \quad f(U_{t+1}, U_t, a_t) = 0 \\ \end{aligned}\]

where $f$ defines the dynamics, implicitly, as constraints on the states and controls, $U_{1:T}$ and $a_{1:T-1}$, which are both free variables in the solver. This optimization framework is called direct collocation. For details of our implementation please see our award-winning paper Direct Collocation for Quantum Optimal Control.

The gist of the method is that the dynamics are given by the solution to the Schrodinger equation, which is results in unitary evolution given by $\exp(-i H(a_t))$, where $H(a_t)$ is the Hamiltonian of the system. We can approximate this evolution using Pade approximants:

\[\begin{aligned} f(U_{t+1}, U_t, a_t) &= U_{t+1} - \exp(-i H(a_t)) U_t \\ &\approx U_{t+1} - B^{-1}(a_t) F(a_t) U_t \\ &= B(a_t) U_{t+1} - F(a_t) U_t \\ -\end{aligned}\]

where $B(a_t)$ and $F(a_t)$ are the backward and forward Pade operators, and are just polynomials in $H(a_t)$.

This implementation is possible because direct collocation allows for the dynamics to be implicit. Since numerically calculating matrix exponentials inherently requires an approximation – the Padé approximant is commonly used – utilizing this formulation significantly improves performance, as, at least here, no matrix inversion is required.

+\end{aligned}\]

where $B(a_t)$ and $F(a_t)$ are the backward and forward Pade operators, and are just polynomials in $H(a_t)$.

This implementation is possible because direct collocation allows for the dynamics to be implicit. Since numerically calculating matrix exponentials inherently requires an approximation – the Padé approximant is commonly used – utilizing this formulation significantly improves performance, as, at least here, no matrix inversion is required.

Index

diff --git a/dev/lib/index.html b/dev/lib/index.html index 9191e586..47fb2fd7 100644 --- a/dev/lib/index.html +++ b/dev/lib/index.html @@ -1,19 +1,19 @@ -Library · QuantumCollocation.jl

Library

QuantumUtils

QuantumCollocation.QuantumUtils.GATESConstant
GATES::Dict{Symbol, Matrix{ComplexF64}}

Dictionary of common quantum gates.

Elements

  • :I - identity, $I$
  • :X - Pauli X, $\sigma_x$
  • :Y - Pauli Y, $\sigma_y$
  • :Z - Pauli Z, $\sigma_z$
  • :H - Hadamard, $H$
  • :CX - controlled-X, $C_X$
  • :XI - $-i X \otimes I$
  • :sqrtiSWAP - $\sqrt{i \text{SWAP}}$
source
QuantumCollocation.QuantumUtils.liftMethod
lift(
+Library · QuantumCollocation.jl

Library

QuantumUtils

QuantumCollocation.QuantumUtils.GATESConstant
GATES::Dict{Symbol, Matrix{ComplexF64}}

Dictionary of common quantum gates.

Elements

  • :I - identity, $I$
  • :X - Pauli X, $\sigma_x$
  • :Y - Pauli Y, $\sigma_y$
  • :Z - Pauli Z, $\sigma_z$
  • :H - Hadamard, $H$
  • :CX - controlled-X, $C_X$
  • :XI - $-i X \otimes I$
  • :sqrtiSWAP - $\sqrt{i \text{SWAP}}$
source
QuantumCollocation.QuantumUtils.liftMethod
lift(
     U::AbstractMatrix{<:Number},
     i::Int,
     n::Int;
     levels::Int=size(U, 1)
-)

Lift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,

\[U \mapsto I_1 \otimes \cdots \otimes I_{i-1} \otimes U \otimes I_{i+1} \otimes \cdots \otimes I_n\]

source
QuantumCollocation.QuantumUtils.liftMethod
lift(
+)

Lift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,

\[U \mapsto I_1 \otimes \cdots \otimes I_{i-1} \otimes U \otimes I_{i+1} \otimes \cdots \otimes I_n\]

source
QuantumCollocation.QuantumUtils.liftMethod
lift(
     op::AbstractMatrix{<:Number},
     i::Int,
     levels::Vector{Int}
-)

Lift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,

\[U \mapsto I_1 \otimes \cdots \otimes I_{i-1} \otimes U \otimes I_{i+1} \otimes \cdots \otimes I_n\]

source

QuantumSystems

QuantumCollocation.QuantumSystems.QuantumSystemMethod
QuantumSystem(
+)

Lift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,

\[U \mapsto I_1 \otimes \cdots \otimes I_{i-1} \otimes U \otimes I_{i+1} \otimes \cdots \otimes I_n\]

source

QuantumSystems

QuantumCollocation.QuantumSystems.QuantumSystemMethod
QuantumSystem(
     H_drift::Matrix{<:Number},
     H_drives::Vector{Matrix{<:Number}};
     params=Dict{Symbol, Any}(),
     kwargs...
-)::QuantumSystem

Constructs a QuantumSystem object from the drift and drive Hamiltonian terms.

source
QuantumCollocation.QuantumSystems.GMethod
G(H::AbstractMatrix)::Matrix{Float64}

Returns the isomorphism of $-iH$:

\[G(H) = \widetilde{- i H} = \mqty(1 & 0 \\ 0 & 1) \otimes \Im(H) - \mqty(0 & -1 \\ 1 & 0) \otimes \Re(H)\]

where $\Im(H)$ and $\Re(H)$ are the imaginary and real parts of $H$ and the tilde indicates the standard isomorphism of a complex valued matrix:

\[\widetilde{H} = \mqty(1 & 0 \\ 0 & 1) \otimes \Re(H) + \mqty(0 & -1 \\ 1 & 0) \otimes \Im(H)\]

source
QuantumCollocation.QuantumSystems.GMethod
G(H::AbstractMatrix)::Matrix{Float64}

Returns the isomorphism of $-iH$:

\[G(H) = \widetilde{- i H} = \mqty(1 & 0 \\ 0 & 1) \otimes \Im(H) - \mqty(0 & -1 \\ 1 & 0) \otimes \Re(H)\]

where $\Im(H)$ and $\Re(H)$ are the imaginary and real parts of $H$ and the tilde indicates the standard isomorphism of a complex valued matrix:

\[\widetilde{H} = \mqty(1 & 0 \\ 0 & 1) \otimes \Re(H) + \mqty(0 & -1 \\ 1 & 0) \otimes \Im(H)\]

source

Integrators

+ \right)\]

source

Integrators

diff --git a/dev/search/index.html b/dev/search/index.html index 189642a8..d1b02b8e 100644 --- a/dev/search/index.html +++ b/dev/search/index.html @@ -1,2 +1,2 @@ -Search · QuantumCollocation.jl

Loading search...

    +Search · QuantumCollocation.jl

    Loading search...

      diff --git a/dev/search_index.js b/dev/search_index.js index e56c38d9..f5d86f3f 100644 --- a/dev/search_index.js +++ b/dev/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"lib/#Library","page":"Library","title":"Library","text":"","category":"section"},{"location":"lib/#QuantumUtils","page":"Library","title":"QuantumUtils","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.QuantumUtils]","category":"page"},{"location":"lib/#QuantumCollocation.QuantumUtils.GATES","page":"Library","title":"QuantumCollocation.QuantumUtils.GATES","text":"GATES::Dict{Symbol, Matrix{ComplexF64}}\n\nDictionary of common quantum gates.\n\nElements\n\n:I - identity, I\n:X - Pauli X, sigma_x\n:Y - Pauli Y, sigma_y\n:Z - Pauli Z, sigma_z\n:H - Hadamard, H\n:CX - controlled-X, C_X\n:XI - -i X otimes I\n:sqrtiSWAP - sqrti textSWAP\n\n\n\n\n\n","category":"constant"},{"location":"lib/#QuantumCollocation.QuantumUtils.:⊗-Tuple{AbstractVecOrMat, AbstractVecOrMat}","page":"Library","title":"QuantumCollocation.QuantumUtils.:⊗","text":"⊗(A::AbstractVecOrMat, B::AbstractVecOrMat)\n\nKronecker product of two vectors or matrices.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.apply-Tuple{Symbol, Vector{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumUtils.apply","text":"apply(gate::Symbol, ψ::Vector{<:Number})\n\nApply a gate from the GATES dictionary to a quantum state.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.gate-Tuple{Symbol}","page":"Library","title":"QuantumCollocation.QuantumUtils.gate","text":"gate(U::Symbol)\n\nGet a gate from the GATES dictionary.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.lift-Tuple{AbstractMatrix{<:Number}, Int64, Int64}","page":"Library","title":"QuantumCollocation.QuantumUtils.lift","text":"lift(\n U::AbstractMatrix{<:Number},\n i::Int,\n n::Int;\n levels::Int=size(U, 1)\n)\n\nLift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,\n\nU mapsto I_1 otimes cdots otimes I_i-1 otimes U otimes I_i+1 otimes cdots otimes I_n\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.lift-Tuple{AbstractMatrix{<:Number}, Int64, Vector{Int64}}","page":"Library","title":"QuantumCollocation.QuantumUtils.lift","text":"lift(\n op::AbstractMatrix{<:Number},\n i::Int,\n levels::Vector{Int}\n)\n\nLift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,\n\nU mapsto I_1 otimes cdots otimes I_i-1 otimes U otimes I_i+1 otimes cdots otimes I_n\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.qubit_system_state-Tuple{String}","page":"Library","title":"QuantumCollocation.QuantumUtils.qubit_system_state","text":"qubit_system_state(ket::String)\n\nGet a quantum state from a string of qubit states, e.g. \"01\" -> ket01.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumSystems","page":"Library","title":"QuantumSystems","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.QuantumSystems]","category":"page"},{"location":"lib/#QuantumCollocation.QuantumSystems.AbstractSystem","page":"Library","title":"QuantumCollocation.QuantumSystems.AbstractSystem","text":"AbstractSystem\n\nAbstract type for defining systems.\n\n\n\n\n\n","category":"type"},{"location":"lib/#QuantumCollocation.QuantumSystems.QuantumSystem","page":"Library","title":"QuantumCollocation.QuantumSystems.QuantumSystem","text":"QuantumSystemNew <: AbstractSystem\n\nA struct for storing the isomorphisms of the system's drift and drive Hamiltonians, as well as the system's parameters.\n\n\n\n\n\n","category":"type"},{"location":"lib/#QuantumCollocation.QuantumSystems.QuantumSystem-Tuple{Matrix{<:Number}, Vector{<:Matrix{<:Number}}}","page":"Library","title":"QuantumCollocation.QuantumSystems.QuantumSystem","text":"QuantumSystem(\n H_drift::Matrix{<:Number},\n H_drives::Vector{Matrix{<:Number}};\n params=Dict{Symbol, Any}(),\n kwargs...\n)::QuantumSystem\n\nConstructs a QuantumSystem object from the drift and drive Hamiltonian terms.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.G-Tuple{AbstractMatrix{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumSystems.G","text":"G(H::AbstractMatrix)::Matrix{Float64}\n\nReturns the isomorphism of -iH:\n\nG(H) = widetilde- i H = mqty(1 0 0 1) otimes Im(H) - mqty(0 -1 1 0) otimes Re(H)\n\nwhere Im(H) and Re(H) are the imaginary and real parts of H and the tilde indicates the standard isomorphism of a complex valued matrix:\n\nwidetildeH = mqty(1 0 0 1) otimes Re(H) + mqty(0 -1 1 0) otimes Im(H)\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.H-Tuple{AbstractMatrix{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumSystems.H","text":"H(G::AbstractMatrix{<:Number})::Matrix{ComplexF64}\n\nReturns the inverse of G(H) = iso(-iH), i.e. returns H\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.MultiModeSystem-Tuple{Int64, Int64}","page":"Library","title":"QuantumCollocation.QuantumSystems.MultiModeSystem","text":"MultiModeSystem(\n transmon_levels::Int,\n cavity_levels::Int;\n χ=2π * -0.5459e-3,\n κ=2π * 4e-6,\n χGF=2π * -1.01540302914e-3,\n α=-2π * 0.143,\n n_cavities=1\n)::QuantumSystem\n\nCreate a new QuantumSystemNew object for a transmon qubit with transmon_levels levels coupled to a single cavity with cavity_levels levels.\n\nThe Hamiltonian for this system is given by\n\nhat H =\n frackappa2 hata^ dagger hata left( hata^daggerhata-1right) +\n 2 chi dyade hata^daggerhata +\n left(\n epsilon_c(t) +\n epsilon_q(t) +\n mathrmcc\n right)\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.lie_subalgebra_dim-Tuple{Vector{<:AbstractMatrix}}","page":"Library","title":"QuantumCollocation.QuantumSystems.lie_subalgebra_dim","text":"lie_subalgebra_dim(Hs::Vector{<:AbstractMatrix})\n\nReturns the dimension of the Lie subalgebra generated by the operators in Hs.\n\n\n\n\n\n","category":"method"},{"location":"lib/#Integrators","page":"Library","title":"Integrators","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.Integrators]","category":"page"},{"location":"lib/#QuantumCollocation.Integrators.UnitaryPadeIntegrator","page":"Library","title":"QuantumCollocation.Integrators.UnitaryPadeIntegrator","text":"\n\n\n\n","category":"type"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"EditURL = \"../../../literate/examples/single_qubit.jl\"","category":"page"},{"location":"generated/examples/single_qubit/#Single-Qubit","page":"Single Qubit","title":"Single Qubit","text":"","category":"section"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"","category":"page"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"EditURL = \"../../literate/quickstart.jl\"","category":"page"},{"location":"generated/quickstart/#Quickstart-Guide","page":"Quickstart Guide","title":"Quickstart Guide","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"To set up and solve a quantum optimal control problems we provide high level problem templates to quickly get started. For unitary gate problems, where we want to realize a gate U_textgoal, with a system Hamiltonian of the form,","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"H(t) = H_0 + sum_i a^i(t) H_i","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"there is the UnitarySmoothPulseProblem constructor which only requires","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"the drift Hamiltonian, H_0\nthe drive Hamiltonians, qtyH_i\nthe target unitary, U_textgoal\nthe number of timesteps, T\nthe (initial) time step size, Delta t","category":"page"},{"location":"generated/quickstart/#Basic-Usage","page":"Quickstart Guide","title":"Basic Usage","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"For example, to create a problem for a single qubit X gate (with a bound on the drive of a a_textbound), i.e., with system hamiltonian","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"H(t) = fracomega2 sigma_z + a^1(t) sigma_x + a^2(t) sigma_y","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"we can do the following:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"using NamedTrajectories\nusing QuantumCollocation\n\n# set time parameters\nT = 100\nΔt = 0.1\n\n# use the exported gate dictionary to get the gates we need\nσx = gate(:X)\nσy = gate(:Y)\nσz = gate(:Z)\n\n# define drift and drive Hamiltonians\nH_drift = 0.5 * σz\nH_drives = [σx, σy]\n\n# define target unitary\nU_goal = σx\n\n# set bound on the drive\na_bound = 1.0\n\n# build the problem\nprob = UnitarySmoothPulseProblem(\n H_drift,\n H_drives,\n U_goal,\n T,\n Δt;\n a_bound=a_bound,\n)\n\n# solve the problem\nsolve!(prob; max_iter=30)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"The above output comes from the Ipopt.jl solver. To see the final fidelity we can use the unitary_fidelity function exported by QuantumCollocation.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"println(\"Final fidelity: \", unitary_fidelity(prob))","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also easily plot the solutions using the plot function exported by NamedTrajectories.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"plot(prob.trajectory, [:Ũ⃗, :a])","category":"page"},{"location":"generated/quickstart/#Minimum-Time-Problems","page":"Quickstart Guide","title":"Minimum Time Problems","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also easily set up and solve a minimum time problem, where we enforce a constraint on the final fidelity:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"mathcalF(U_T U_textgoal) geq mathcalF_textmin","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"Using the problem we just solved we can do the following:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"# final fidelity constraint\nfinal_fidelity = 0.99\n\n# weight on the minimum time objective\nD = 10.0\n\nprob_min_time = UnitaryMinimumTimeProblem(\n prob;\n final_fidelity=final_fidelity,\n D=D\n)\n\nsolve!(prob_min_time; max_iter=30)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can see that the final fidelity is indeed greater than the minimum fidelity we set.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"println(\"Final fidelity: \", unitary_fidelity(prob_min_time))","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"and that the duration of the pulse has decreased.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"initial_dur = times(prob.trajectory)[end]\nmin_time_dur = times(prob_min_time.trajectory)[end]\n\nprintln(\"Initial duration: \", initial_dur)\nprintln(\"Minimum duration: \", min_time_dur)\nprintln(\"Duration decrease: \", initial_dur - min_time_dur)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also plot the solutions for the minimum time problem.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"plot(prob_min_time.trajectory, [:Ũ⃗, :a])","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = QuantumCollocation","category":"page"},{"location":"#QuantumCollocation.jl","page":"Home","title":"QuantumCollocation.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Direct Collocation for Quantum Optimal Control (arXiv)","category":"page"},{"location":"#Motivation","page":"Home","title":"Motivation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In quantum optimal control, we are interested in finding a pulse sequence a_1T-1 to drive a quantum system and realize a target gate U_textgoal. We formulate this problem as a nonlinear program (NLP) of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginaligned\nundersetU_1T a_1T-1textminimize quad ell(U_T U_textgoal)\ntext subject to quad f(U_t+1 U_t a_t) = 0 \nendaligned","category":"page"},{"location":"","page":"Home","title":"Home","text":"where f defines the dynamics, implicitly, as constraints on the states and controls, U_1T and a_1T-1, which are both free variables in the solver. This optimization framework is called direct collocation. For details of our implementation please see our award-winning paper Direct Collocation for Quantum Optimal Control.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The gist of the method is that the dynamics are given by the solution to the Schrodinger equation, which is results in unitary evolution given by exp(-i H(a_t)), where H(a_t) is the Hamiltonian of the system. We can approximate this evolution using Pade approximants:","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginaligned\nf(U_t+1 U_t a_t) = U_t+1 - exp(-i H(a_t)) U_t \napprox U_t+1 - B^-1(a_t) F(a_t) U_t \n= B(a_t) U_t+1 - F(a_t) U_t \nendaligned","category":"page"},{"location":"","page":"Home","title":"Home","text":"where B(a_t) and F(a_t) are the backward and forward Pade operators, and are just polynomials in H(a_t). ","category":"page"},{"location":"","page":"Home","title":"Home","text":"This implementation is possible because direct collocation allows for the dynamics to be implicit. Since numerically calculating matrix exponentials inherently requires an approximation – the Padé approximant is commonly used – utilizing this formulation significantly improves performance, as, at least here, no matrix inversion is required.","category":"page"},{"location":"","page":"Home","title":"Home","text":"","category":"page"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"EditURL = \"../../../literate/man/utils.jl\"","category":"page"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"","category":"page"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"EditURL = \"../../../literate/man/problem_templates.jl\"","category":"page"},{"location":"generated/man/problem_templates/#Problem-Templates","page":"Problem Templates","title":"Problem Templates","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"We provide a number of problem templates for making it simple and easy to set up and solve certain types of quantum optimal control problems. These templates all construct a QuantumControlProblem object. The problem templates are:","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"UnitarySmoothPulseProblem\nUnitaryMinimumTimeProblem","category":"page"},{"location":"generated/man/problem_templates/#Unitary-Smooth-Pulse-Problem","page":"Problem Templates","title":"Unitary Smooth Pulse Problem","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"UnitarySmoothPulseProblem","category":"page"},{"location":"generated/man/problem_templates/#QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblem","page":"Problem Templates","title":"QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblem","text":"UnitarySmoothPulseProblem(H_drift, H_drives, U_goal, T, Δt; kwargs...)\nUnitarySmoothPulseProblem(system::QuantumSystem, U_goal, T, Δt; kwargs...)\n\nConstruct a QuantumControlProblem for a free-time unitary gate problem with smooth control pulses enforced by constraining the second derivative of the pulse trajectory, i.e.,\n\nbeginaligned\nundersetvectildeU a dota ddota Delta ttextminimize quad\nQ cdot ellqty(vectildeU_T vectildeU_textgoal) + frac12 sum_t qty(R_a a_t^2 + R_dota dota_t^2 + R_ddota ddota_t^2) \ntext subject to quad vbP^(n)qty(vectildeU_t+1 vectildeU_t a_t Delta t_t) = 0 \n a_t+1 - a_t - dota_t Delta t_t = 0 \n quad dota_t+1 - dota_t - ddota_t Delta t_t = 0 \n quad a_t leq a_textbound \n quad ddota_t leq ddota_textbound \n quad Delta t_textmin leq Delta t_t leq Delta t_textmax \nendaligned\n\nwhere, for U in SU(N),\n\nellqty(vectildeU_T vectildeU_textgoal) =\nabs1 - frac1N abs tr qty(U_textgoal U_T) \n\nis the infidelity objective function, Q is a weight, R_a, R_dota, and R_ddota are weights on the regularization terms, and vbP^(n) is the nth-order Pade integrator.\n\nArguments\n\nH_drift::AbstractMatrix{<:Number}: the drift hamiltonian\nH_drives::Vector{<:AbstractMatrix{<:Number}}: the control hamiltonians\n\nor\n\nsystem::QuantumSystem: the system to be controlled\n\nwith\n\nU_goal::AbstractMatrix{<:Number}: the target unitary\nT::Int: the number of timesteps\nΔt::Float64: the (initial) time step size\n\nKeyword Arguments\n\nfree_time::Bool=true: whether or not to allow the time steps to vary\ninit_trajectory::Union{NamedTrajectory, Nothing}=nothing: an initial trajectory to use\na_bound::Float64=1.0: the bound on the control pulse\na_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives)): the bounds on the control pulses, one for each drive\na_guess::Union{Matrix{Float64}, Nothing}=nothing: an initial guess for the control pulses\ndda_bound::Float64=1.0: the bound on the control pulse derivative\ndda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): the bounds on the control pulse derivatives, one for each drive\nΔt_min::Float64=0.5 * Δt: the minimum time step size\nΔt_max::Float64=1.5 * Δt: the maximum time step size\ndrive_derivative_σ::Float64=0.01: the standard deviation of the initial guess for the control pulse derivatives\nQ::Float64=100.0: the weight on the infidelity objective\nR=1e-2: the weight on the regularization terms\nR_a::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulses\nR_da::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse derivatives\nR_dda::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse second derivatives\nleakage_suppression::Bool=false: whether or not to suppress leakage to higher energy states\nleakage_indices::Union{Nothing, Vector{Int}}=nothing: the indices of vectildeU corresponding leakage operators that should be suppressed\nsystem_levels::Union{Nothing, Vector{Int}}=nothing: the number of levels in each subsystem\nR_leakage=1e-1: the weight on the leakage suppression term\nmax_iter::Int=1000: the maximum number of iterations for the solver\nlinear_solver::String=\"mumps\": the linear solver to use\nipopt_options::Options=Options(): the options for the Ipopt solver\nconstraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: additional constraints to add to the problem\ntimesteps_all_equal::Bool=true: whether or not to enforce that all time steps are equal\nverbose::Bool=false: whether or not to print constructor output\nU_init::Union{AbstractMatrix{<:Number},Nothing}=nothing: an initial guess for the unitary\nintegrator=Integrators.fourth_order_pade: the integrator to use for the unitary\ngeodesic=true: whether or not to use the geodesic as the initial guess for the unitary\npade_order=4: the order of the Pade approximation to use for the unitary integrator\nautodiff=pade_order != 4: whether or not to use automatic differentiation for the unitary integrator\nsubspace=nothing: the subspace to use for the unitary integrator\njacobian_structure=true: whether or not to use the jacobian structure\nhessian_approximation=false: whether or not to use L-BFGS hessian approximation in Ipopt\nblas_multithreading=true: whether or not to use multithreading in BLAS\n\n\n\n\n\n","category":"function"},{"location":"generated/man/problem_templates/#Unitary-Minimum-Time-Problem","page":"Problem Templates","title":"Unitary Minimum Time Problem","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"This page was generated using Literate.jl.","category":"page"}] +[{"location":"lib/#Library","page":"Library","title":"Library","text":"","category":"section"},{"location":"lib/#QuantumUtils","page":"Library","title":"QuantumUtils","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.QuantumUtils]","category":"page"},{"location":"lib/#QuantumCollocation.QuantumUtils.GATES","page":"Library","title":"QuantumCollocation.QuantumUtils.GATES","text":"GATES::Dict{Symbol, Matrix{ComplexF64}}\n\nDictionary of common quantum gates.\n\nElements\n\n:I - identity, I\n:X - Pauli X, sigma_x\n:Y - Pauli Y, sigma_y\n:Z - Pauli Z, sigma_z\n:H - Hadamard, H\n:CX - controlled-X, C_X\n:XI - -i X otimes I\n:sqrtiSWAP - sqrti textSWAP\n\n\n\n\n\n","category":"constant"},{"location":"lib/#QuantumCollocation.QuantumUtils.:⊗-Tuple{AbstractVecOrMat, AbstractVecOrMat}","page":"Library","title":"QuantumCollocation.QuantumUtils.:⊗","text":"⊗(A::AbstractVecOrMat, B::AbstractVecOrMat)\n\nKronecker product of two vectors or matrices.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.apply-Tuple{Symbol, Vector{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumUtils.apply","text":"apply(gate::Symbol, ψ::Vector{<:Number})\n\nApply a gate from the GATES dictionary to a quantum state.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.gate-Tuple{Symbol}","page":"Library","title":"QuantumCollocation.QuantumUtils.gate","text":"gate(U::Symbol)\n\nGet a gate from the GATES dictionary.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.lift-Tuple{AbstractMatrix{<:Number}, Int64, Int64}","page":"Library","title":"QuantumCollocation.QuantumUtils.lift","text":"lift(\n U::AbstractMatrix{<:Number},\n i::Int,\n n::Int;\n levels::Int=size(U, 1)\n)\n\nLift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,\n\nU mapsto I_1 otimes cdots otimes I_i-1 otimes U otimes I_i+1 otimes cdots otimes I_n\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.lift-Tuple{AbstractMatrix{<:Number}, Int64, Vector{Int64}}","page":"Library","title":"QuantumCollocation.QuantumUtils.lift","text":"lift(\n op::AbstractMatrix{<:Number},\n i::Int,\n levels::Vector{Int}\n)\n\nLift a matrix to a larger Hilbert space by placing it on the i-th qubit of a n-qubit system. I.e.,\n\nU mapsto I_1 otimes cdots otimes I_i-1 otimes U otimes I_i+1 otimes cdots otimes I_n\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumUtils.qubit_system_state-Tuple{String}","page":"Library","title":"QuantumCollocation.QuantumUtils.qubit_system_state","text":"qubit_system_state(ket::String)\n\nGet a quantum state from a string of qubit states, e.g. \"01\" -> ket01.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumSystems","page":"Library","title":"QuantumSystems","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.QuantumSystems]","category":"page"},{"location":"lib/#QuantumCollocation.QuantumSystems.AbstractSystem","page":"Library","title":"QuantumCollocation.QuantumSystems.AbstractSystem","text":"AbstractSystem\n\nAbstract type for defining systems.\n\n\n\n\n\n","category":"type"},{"location":"lib/#QuantumCollocation.QuantumSystems.QuantumSystem","page":"Library","title":"QuantumCollocation.QuantumSystems.QuantumSystem","text":"QuantumSystemNew <: AbstractSystem\n\nA struct for storing the isomorphisms of the system's drift and drive Hamiltonians, as well as the system's parameters.\n\n\n\n\n\n","category":"type"},{"location":"lib/#QuantumCollocation.QuantumSystems.QuantumSystem-Tuple{Matrix{<:Number}, Vector{<:Matrix{<:Number}}}","page":"Library","title":"QuantumCollocation.QuantumSystems.QuantumSystem","text":"QuantumSystem(\n H_drift::Matrix{<:Number},\n H_drives::Vector{Matrix{<:Number}};\n params=Dict{Symbol, Any}(),\n kwargs...\n)::QuantumSystem\n\nConstructs a QuantumSystem object from the drift and drive Hamiltonian terms.\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.G-Tuple{AbstractMatrix{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumSystems.G","text":"G(H::AbstractMatrix)::Matrix{Float64}\n\nReturns the isomorphism of -iH:\n\nG(H) = widetilde- i H = mqty(1 0 0 1) otimes Im(H) - mqty(0 -1 1 0) otimes Re(H)\n\nwhere Im(H) and Re(H) are the imaginary and real parts of H and the tilde indicates the standard isomorphism of a complex valued matrix:\n\nwidetildeH = mqty(1 0 0 1) otimes Re(H) + mqty(0 -1 1 0) otimes Im(H)\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.H-Tuple{AbstractMatrix{<:Number}}","page":"Library","title":"QuantumCollocation.QuantumSystems.H","text":"H(G::AbstractMatrix{<:Number})::Matrix{ComplexF64}\n\nReturns the inverse of G(H) = iso(-iH), i.e. returns H\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.MultiModeSystem-Tuple{Int64, Int64}","page":"Library","title":"QuantumCollocation.QuantumSystems.MultiModeSystem","text":"MultiModeSystem(\n transmon_levels::Int,\n cavity_levels::Int;\n χ=2π * -0.5459e-3,\n κ=2π * 4e-6,\n χGF=2π * -1.01540302914e-3,\n α=-2π * 0.143,\n n_cavities=1\n)::QuantumSystem\n\nCreate a new QuantumSystemNew object for a transmon qubit with transmon_levels levels coupled to a single cavity with cavity_levels levels.\n\nThe Hamiltonian for this system is given by\n\nhat H =\n frackappa2 hata^ dagger hata left( hata^daggerhata-1right) +\n 2 chi dyade hata^daggerhata +\n left(\n epsilon_c(t) +\n epsilon_q(t) +\n mathrmcc\n right)\n\n\n\n\n\n","category":"method"},{"location":"lib/#QuantumCollocation.QuantumSystems.lie_subalgebra_dim-Tuple{Vector{<:AbstractMatrix}}","page":"Library","title":"QuantumCollocation.QuantumSystems.lie_subalgebra_dim","text":"lie_subalgebra_dim(Hs::Vector{<:AbstractMatrix})\n\nReturns the dimension of the Lie subalgebra generated by the operators in Hs.\n\n\n\n\n\n","category":"method"},{"location":"lib/#Integrators","page":"Library","title":"Integrators","text":"","category":"section"},{"location":"lib/","page":"Library","title":"Library","text":"Modules = [QuantumCollocation.Integrators]","category":"page"},{"location":"lib/#QuantumCollocation.Integrators.UnitaryPadeIntegrator","page":"Library","title":"QuantumCollocation.Integrators.UnitaryPadeIntegrator","text":"\n\n\n\n","category":"type"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"EditURL = \"../../../literate/examples/single_qubit.jl\"","category":"page"},{"location":"generated/examples/single_qubit/#Single-Qubit","page":"Single Qubit","title":"Single Qubit","text":"","category":"section"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"","category":"page"},{"location":"generated/examples/single_qubit/","page":"Single Qubit","title":"Single Qubit","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"EditURL = \"../../literate/quickstart.jl\"","category":"page"},{"location":"generated/quickstart/#Quickstart-Guide","page":"Quickstart Guide","title":"Quickstart Guide","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"To set up and solve a quantum optimal control problems we provide high level problem templates to quickly get started. For unitary gate problems, where we want to realize a gate U_textgoal, with a system Hamiltonian of the form,","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"H(t) = H_0 + sum_i a^i(t) H_i","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"there is the UnitarySmoothPulseProblem constructor which only requires","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"the drift Hamiltonian, H_0\nthe drive Hamiltonians, qtyH_i\nthe target unitary, U_textgoal\nthe number of timesteps, T\nthe (initial) time step size, Delta t","category":"page"},{"location":"generated/quickstart/#Basic-Usage","page":"Quickstart Guide","title":"Basic Usage","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"For example, to create a problem for a single qubit X gate (with a bound on the drive of a a_textbound), i.e., with system hamiltonian","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"H(t) = fracomega2 sigma_z + a^1(t) sigma_x + a^2(t) sigma_y","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"we can do the following:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"using NamedTrajectories\nusing QuantumCollocation\n\n# set time parameters\nT = 100\nΔt = 0.1\n\n# use the exported gate dictionary to get the gates we need\nσx = gate(:X)\nσy = gate(:Y)\nσz = gate(:Z)\n\n# define drift and drive Hamiltonians\nH_drift = 0.5 * σz\nH_drives = [σx, σy]\n\n# define target unitary\nU_goal = σx\n\n# set bound on the drive\na_bound = 1.0\n\n# build the problem\nprob = UnitarySmoothPulseProblem(\n H_drift,\n H_drives,\n U_goal,\n T,\n Δt;\n a_bound=a_bound,\n)\n\n# solve the problem\nsolve!(prob; max_iter=30)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"The above output comes from the Ipopt.jl solver. To see the final fidelity we can use the unitary_fidelity function exported by QuantumCollocation.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"println(\"Final fidelity: \", unitary_fidelity(prob))","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also easily plot the solutions using the plot function exported by NamedTrajectories.jl.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"plot(prob.trajectory, [:Ũ⃗, :a])","category":"page"},{"location":"generated/quickstart/#Minimum-Time-Problems","page":"Quickstart Guide","title":"Minimum Time Problems","text":"","category":"section"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also easily set up and solve a minimum time problem, where we enforce a constraint on the final fidelity:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"mathcalF(U_T U_textgoal) geq mathcalF_textmin","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"Using the problem we just solved we can do the following:","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"# final fidelity constraint\nfinal_fidelity = 0.99\n\n# weight on the minimum time objective\nD = 10.0\n\nprob_min_time = UnitaryMinimumTimeProblem(\n prob;\n final_fidelity=final_fidelity,\n D=D\n)\n\nsolve!(prob_min_time; max_iter=30)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can see that the final fidelity is indeed greater than the minimum fidelity we set.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"println(\"Final fidelity: \", unitary_fidelity(prob_min_time))","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"and that the duration of the pulse has decreased.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"initial_dur = times(prob.trajectory)[end]\nmin_time_dur = times(prob_min_time.trajectory)[end]\n\nprintln(\"Initial duration: \", initial_dur)\nprintln(\"Minimum duration: \", min_time_dur)\nprintln(\"Duration decrease: \", initial_dur - min_time_dur)","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"We can also plot the solutions for the minimum time problem.","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"plot(prob_min_time.trajectory, [:Ũ⃗, :a])","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"","category":"page"},{"location":"generated/quickstart/","page":"Quickstart Guide","title":"Quickstart Guide","text":"This page was generated using Literate.jl.","category":"page"},{"location":"","page":"Home","title":"Home","text":"CurrentModule = QuantumCollocation","category":"page"},{"location":"#QuantumCollocation.jl","page":"Home","title":"QuantumCollocation.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"Direct Collocation for Quantum Optimal Control (arXiv)","category":"page"},{"location":"#Motivation","page":"Home","title":"Motivation","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"In quantum optimal control, we are interested in finding a pulse sequence a_1T-1 to drive a quantum system and realize a target gate U_textgoal. We formulate this problem as a nonlinear program (NLP) of the form","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginaligned\nundersetU_1T a_1T-1textminimize quad ell(U_T U_textgoal)\ntext subject to quad f(U_t+1 U_t a_t) = 0 \nendaligned","category":"page"},{"location":"","page":"Home","title":"Home","text":"where f defines the dynamics, implicitly, as constraints on the states and controls, U_1T and a_1T-1, which are both free variables in the solver. This optimization framework is called direct collocation. For details of our implementation please see our award-winning paper Direct Collocation for Quantum Optimal Control.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The gist of the method is that the dynamics are given by the solution to the Schrodinger equation, which is results in unitary evolution given by exp(-i H(a_t)), where H(a_t) is the Hamiltonian of the system. We can approximate this evolution using Pade approximants:","category":"page"},{"location":"","page":"Home","title":"Home","text":"beginaligned\nf(U_t+1 U_t a_t) = U_t+1 - exp(-i H(a_t)) U_t \napprox U_t+1 - B^-1(a_t) F(a_t) U_t \n= B(a_t) U_t+1 - F(a_t) U_t \nendaligned","category":"page"},{"location":"","page":"Home","title":"Home","text":"where B(a_t) and F(a_t) are the backward and forward Pade operators, and are just polynomials in H(a_t). ","category":"page"},{"location":"","page":"Home","title":"Home","text":"This implementation is possible because direct collocation allows for the dynamics to be implicit. Since numerically calculating matrix exponentials inherently requires an approximation – the Padé approximant is commonly used – utilizing this formulation significantly improves performance, as, at least here, no matrix inversion is required.","category":"page"},{"location":"#Index","page":"Home","title":"Index","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"","category":"page"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"EditURL = \"../../../literate/man/utils.jl\"","category":"page"},{"location":"generated/man/utils/#Utilities","page":"Utilities","title":"Utilities","text":"","category":"section"},{"location":"generated/man/utils/#Gates","page":"Utilities","title":"Gates","text":"","category":"section"},{"location":"generated/man/utils/#States","page":"Utilities","title":"States","text":"","category":"section"},{"location":"generated/man/utils/#Operators","page":"Utilities","title":"Operators","text":"","category":"section"},{"location":"generated/man/utils/#Isomorphisms","page":"Utilities","title":"Isomorphisms","text":"","category":"section"},{"location":"generated/man/utils/#Measurements","page":"Utilities","title":"Measurements","text":"","category":"section"},{"location":"generated/man/utils/#Subspaces","page":"Utilities","title":"Subspaces","text":"","category":"section"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"","category":"page"},{"location":"generated/man/utils/","page":"Utilities","title":"Utilities","text":"This page was generated using Literate.jl.","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"EditURL = \"../../../literate/man/problem_templates.jl\"","category":"page"},{"location":"generated/man/problem_templates/#Problem-Templates","page":"Problem Templates","title":"Problem Templates","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"We provide a number of problem templates for making it simple and easy to set up and solve certain types of quantum optimal control problems. These templates all construct a QuantumControlProblem object. The problem templates are:","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"UnitarySmoothPulseProblem\nUnitaryMinimumTimeProblem","category":"page"},{"location":"generated/man/problem_templates/#Unitary-Smooth-Pulse-Problem","page":"Problem Templates","title":"Unitary Smooth Pulse Problem","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"UnitarySmoothPulseProblem","category":"page"},{"location":"generated/man/problem_templates/#QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblem","page":"Problem Templates","title":"QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblem","text":"UnitarySmoothPulseProblem(H_drift, H_drives, U_goal, T, Δt; kwargs...)\nUnitarySmoothPulseProblem(system::QuantumSystem, U_goal, T, Δt; kwargs...)\n\nConstruct a QuantumControlProblem for a free-time unitary gate problem with smooth control pulses enforced by constraining the second derivative of the pulse trajectory, i.e.,\n\nbeginaligned\nundersetvectildeU a dota ddota Delta ttextminimize quad\nQ cdot ellqty(vectildeU_T vectildeU_textgoal) + frac12 sum_t qty(R_a a_t^2 + R_dota dota_t^2 + R_ddota ddota_t^2) \ntext subject to quad vbP^(n)qty(vectildeU_t+1 vectildeU_t a_t Delta t_t) = 0 \n a_t+1 - a_t - dota_t Delta t_t = 0 \n quad dota_t+1 - dota_t - ddota_t Delta t_t = 0 \n quad a_t leq a_textbound \n quad ddota_t leq ddota_textbound \n quad Delta t_textmin leq Delta t_t leq Delta t_textmax \nendaligned\n\nwhere, for U in SU(N),\n\nellqty(vectildeU_T vectildeU_textgoal) =\nabs1 - frac1N abs tr qty(U_textgoal U_T) \n\nis the infidelity objective function, Q is a weight, R_a, R_dota, and R_ddota are weights on the regularization terms, and vbP^(n) is the nth-order Pade integrator.\n\nArguments\n\nH_drift::AbstractMatrix{<:Number}: the drift hamiltonian\nH_drives::Vector{<:AbstractMatrix{<:Number}}: the control hamiltonians\n\nor\n\nsystem::QuantumSystem: the system to be controlled\n\nwith\n\nU_goal::AbstractMatrix{<:Number}: the target unitary\nT::Int: the number of timesteps\nΔt::Float64: the (initial) time step size\n\nKeyword Arguments\n\nfree_time::Bool=true: whether or not to allow the time steps to vary\ninit_trajectory::Union{NamedTrajectory, Nothing}=nothing: an initial trajectory to use\na_bound::Float64=1.0: the bound on the control pulse\na_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives)): the bounds on the control pulses, one for each drive\na_guess::Union{Matrix{Float64}, Nothing}=nothing: an initial guess for the control pulses\ndda_bound::Float64=1.0: the bound on the control pulse derivative\ndda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): the bounds on the control pulse derivatives, one for each drive\nΔt_min::Float64=0.5 * Δt: the minimum time step size\nΔt_max::Float64=1.5 * Δt: the maximum time step size\ndrive_derivative_σ::Float64=0.01: the standard deviation of the initial guess for the control pulse derivatives\nQ::Float64=100.0: the weight on the infidelity objective\nR=1e-2: the weight on the regularization terms\nR_a::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulses\nR_da::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse derivatives\nR_dda::Union{Float64, Vector{Float64}}=R: the weight on the regularization term for the control pulse second derivatives\nleakage_suppression::Bool=false: whether or not to suppress leakage to higher energy states\nleakage_indices::Union{Nothing, Vector{Int}}=nothing: the indices of vectildeU corresponding leakage operators that should be suppressed\nsystem_levels::Union{Nothing, Vector{Int}}=nothing: the number of levels in each subsystem\nR_leakage=1e-1: the weight on the leakage suppression term\nmax_iter::Int=1000: the maximum number of iterations for the solver\nlinear_solver::String=\"mumps\": the linear solver to use\nipopt_options::Options=Options(): the options for the Ipopt solver\nconstraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: additional constraints to add to the problem\ntimesteps_all_equal::Bool=true: whether or not to enforce that all time steps are equal\nverbose::Bool=false: whether or not to print constructor output\nU_init::Union{AbstractMatrix{<:Number},Nothing}=nothing: an initial guess for the unitary\nintegrator=Integrators.fourth_order_pade: the integrator to use for the unitary\ngeodesic=true: whether or not to use the geodesic as the initial guess for the unitary\npade_order=4: the order of the Pade approximation to use for the unitary integrator\nautodiff=pade_order != 4: whether or not to use automatic differentiation for the unitary integrator\nsubspace=nothing: the subspace to use for the unitary integrator\njacobian_structure=true: whether or not to use the jacobian structure\nhessian_approximation=false: whether or not to use L-BFGS hessian approximation in Ipopt\nblas_multithreading=true: whether or not to use multithreading in BLAS\n\n\n\n\n\n","category":"function"},{"location":"generated/man/problem_templates/#Unitary-Minimum-Time-Problem","page":"Problem Templates","title":"Unitary Minimum Time Problem","text":"","category":"section"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"","category":"page"},{"location":"generated/man/problem_templates/","page":"Problem Templates","title":"Problem Templates","text":"This page was generated using Literate.jl.","category":"page"}] }