Library

Problem Templates

QuantumCollocation.ProblemTemplates.QuantumStateMinimumTimeProblemFunction
QuantumStateMinimumTimeProblem(traj, sys, obj, integrators, constraints; kwargs...)
QuantumStateMinimumTimeProblem(prob; kwargs...)

Construct a DirectTrajOptProblem for the minimum time problem of reaching a target state.

Keyword Arguments

  • state_name::Symbol=:ψ̃: The symbol for the state variables.
  • final_fidelity::Union{Real, Nothing}=nothing: The final fidelity.
  • D=1.0: The cost weight on the time.
  • piccolo_options::PiccoloOptions=PiccoloOptions(): The Piccolo options.
source
QuantumCollocation.ProblemTemplates.QuantumStateSmoothPulseProblemFunction
QuantumStateSmoothPulseProblem(system, ψ_inits, ψ_goals, T, Δt; kwargs...)
QuantumStateSmoothPulseProblem(system, ψ_init, ψ_goal, T, Δt; kwargs...)
QuantumStateSmoothPulseProblem(H_drift, H_drives, args...; kwargs...)

Create a quantum state smooth pulse problem. The goal is to find a control pulse a(t) that drives all of the initial states ψ_inits to the corresponding target states ψ_goals using T timesteps of size Δt. This problem also controls the first and second derivatives of the control pulse, da(t) and dda(t), to ensure smoothness.

Arguments

  • system::AbstractQuantumSystem: The quantum system.

or

  • H_drift::AbstractMatrix{<:Number}: The drift Hamiltonian.
  • H_drives::Vector{<:AbstractMatrix{<:Number}}: The control Hamiltonians.

with

  • ψ_inits::Vector{<:AbstractVector{<:ComplexF64}}: The initial states.
  • ψ_goals::Vector{<:AbstractVector{<:ComplexF64}}: The target states.

or

  • ψ_init::AbstractVector{<:ComplexF64}: The initial state.
  • ψ_goal::AbstractVector{<:ComplexF64}: The target state.

with

  • T::Int: The number of timesteps.
  • Δt::Float64: The timestep size.

Keyword Arguments

  • state_name::Symbol=:ψ̃: The name of the state variable.
  • control_name::Symbol=:a: The name of the control variable.
  • timestep_name::Symbol=:Δt: The name of the timestep variable.
  • init_trajectory::Union{NamedTrajectory, Nothing}=nothing: The initial trajectory.
  • 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 pulse.
  • a_guess::Union{Matrix{Float64}, Nothing}=nothing: The initial guess for the control pulse.
  • da_bound::Float64=Inf: The bound on the first derivative of the control pulse.
  • da_bounds::Vector{Float64}=fill(da_bound, length(system.G_drives)): The bounds on the first derivative of the control pulse.
  • dda_bound::Float64=1.0: The bound on the second derivative of the control pulse.
  • dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): The bounds on the second derivative of the control pulse.
  • Δt_min::Float64=0.5 * Δt: The minimum timestep size.
  • Δt_max::Float64=1.5 * Δt: The maximum timestep size.
  • drive_derivative_σ::Float64=0.01: The standard deviation of the drive derivative random initialization.
  • Q::Float64=100.0: The weight on the state objective.
  • R=1e-2: The weight on the control pulse and its derivatives.
  • R_a::Union{Float64, Vector{Float64}}=R: The weight on the control pulse.
  • R_da::Union{Float64, Vector{Float64}}=R: The weight on the first derivative of the control pulse.
  • R_dda::Union{Float64, Vector{Float64}}=R: The weight on the second derivative of the control pulse.
  • constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: The constraints.
  • piccolo_options::PiccoloOptions=PiccoloOptions(): The Piccolo options.
source
QuantumCollocation.ProblemTemplates.UnitaryMinimumTimeProblemFunction
UnitaryMinimumTimeProblem(
    goal::AbstractPiccoloOperator,
    trajectory::NamedTrajectory,
    objective::Objective,
    dynamics::TrajectoryDynamics,
    constraints::AbstractVector{<:AbstractConstraint};
    kwargs...
)

UnitaryMinimumTimeProblem(
    goal::AbstractPiccoloOperator,
    prob::DirectTrajOptProblem;
    kwargs...
)

Create a minimum-time problem for unitary control.

\[\begin{aligned} \underset{\vec{\tilde{U}}, a, \dot{a}, \ddot{a}, \Delta t}{\text{minimize}} & \quad J(\vec{\tilde{U}}, a, \dot{a}, \ddot{a}) + D \sum_t \Delta t_t \\ \text{ subject to } & \quad \vb{P}^{(n)}\qty(\vec{\tilde{U}}_{t+1}, \vec{\tilde{U}}_t, a_t, \Delta t_t) = 0 \\ & c(\vec{\tilde{U}}, a, \dot{a}, \ddot{a}) = 0 \\ & \quad \Delta t_{\text{min}} \leq \Delta t_t \leq \Delta t_{\text{max}} \\ \end{aligned}\]

Keyword Arguments

  • piccolo_options::PiccoloOptions=PiccoloOptions(): The Piccolo options.
  • unitary_name::Symbol=:Ũ⃗: The name of the unitary for the goal.
  • final_fidelity::Float64=1.0: The final fidelity constraint.
  • D::Float64=1.0: The scaling factor for the minimum-time objective.
source
QuantumCollocation.ProblemTemplates.UnitarySamplingProblemMethod
UnitarySamplingProblem(systemns, operator, T, Δt; kwargs...)

A UnitarySamplingProblem is a quantum control problem where the goal is to find a control pulse that generates a target unitary operator for a set of quantum systems. The controls are shared among all systems, and the optimization seeks to find the control pulse that achieves the operator for each system. The idea is to enforce a robust solution by including multiple systems reflecting the problem uncertainty.

Arguments

  • systems::AbstractVector{<:AbstractQuantumSystem}: A vector of quantum systems.
  • operators::AbstractVector{<:AbstractPiccoloOperator}: A vector of target operators.
  • T::Int: The number of time steps.
  • Δt::Union{Float64, Vector{Float64}}: The time step value or vector of time steps.

Keyword Arguments

  • system_labels::Vector{String} = string.(1:length(systems)): The labels for each system.
  • system_weights::Vector{Float64} = fill(1.0, length(systems)): The weights for each system.
  • init_trajectory::Union{NamedTrajectory, Nothing} = nothing: The initial trajectory.
  • state_name::Symbol = :Ũ⃗: The name of the state variable.
  • control_name::Symbol = :a: The name of the control variable.
  • timestep_name::Symbol = :Δt: The name of the timestep variable.
  • constraints::Vector{<:AbstractConstraint} = AbstractConstraint[]: The constraints.
  • a_bound::Float64 = 1.0: The bound for the control amplitudes.
  • a_bounds::Vector{Float64} = fill(a_bound, length(systems[1].G_drives)): The bounds for the control amplitudes.
  • a_guess::Union{Matrix{Float64}, Nothing} = nothing: The initial guess for the control amplitudes.
  • da_bound::Float64 = Inf: The bound for the control first derivatives.
  • da_bounds::Vector{Float64} = fill(da_bound, length(systems[1].G_drives)): The bounds for the control first derivatives.
  • dda_bound::Float64 = 1.0: The bound for the control second derivatives.
  • dda_bounds::Vector{Float64} = fill(dda_bound, length(systems[1].G_drives)): The bounds for the control second derivatives.
  • Δt_min::Float64 = 0.5 * Δt: The minimum time step size.
  • Δt_max::Float64 = 1.5 * Δt: The maximum time step size.
  • Q::Float64 = 100.0: The fidelity weight.
  • R::Float64 = 1e-2: The regularization weight.
  • R_a::Union{Float64, Vector{Float64}} = R: The regularization weight for the control amplitudes.
  • R_da::Union{Float64, Vector{Float64}} = R: The regularization weight for the control first derivatives.
  • R_dda::Union{Float64, Vector{Float64}} = R: The regularization weight for the control second derivatives.
  • piccolo_options::PiccoloOptions = PiccoloOptions(): The Piccolo options.
source
QuantumCollocation.ProblemTemplates.UnitarySmoothPulseProblemFunction
UnitarySmoothPulseProblem(system::AbstractQuantumSystem, operator, T, Δt; kwargs...)
UnitarySmoothPulseProblem(H_drift, H_drives, operator, T, Δt; kwargs...)

Construct a DirectTrajOptProblem 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) \\ \text{ subject to } & \quad \vb{P}^{(n)}\qty(\vec{\tilde{U}}_{t+1}, \vec{\tilde{U}}_t, a_t, \Delta t_t) = 0 \\ & \quad a_{t+1} - a_t - \dot{a}_t \Delta t_t = 0 \\ & \quad \dot{a}_{t+1} - \dot{a}_t - \ddot{a}_t \Delta t_t = 0 \\ & \quad |a_t| \leq a_{\text{bound}} \\ & \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

  • system::AbstractQuantumSystem: the system to be controlled

or

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

with

  • goal::AbstractPiccoloOperator: the target unitary, either in the form of an EmbeddedOperator or a `Matrix{ComplexF64}
  • T::Int: the number of timesteps
  • Δt::Float64: the (initial) time step size

Keyword Arguments

  • piccolo_options::PiccoloOptions=PiccoloOptions(): the options for the Piccolo solver
  • state_name::Symbol = :Ũ⃗: the name of the state
  • control_name::Symbol = :a: the name of the control
  • timestep_name::Symbol = :Δt: the name of the timestep
  • init_trajectory::Union{NamedTrajectory, Nothing}=nothing: an initial trajectory to use
  • a_guess::Union{Matrix{Float64}, Nothing}=nothing: an initial guess for the control pulses
  • 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
  • da_bound::Float64=Inf: the bound on the control pulse derivative
  • da_bounds::Vector{Float64}=fill(da_bound, length(system.G_drives)): the bounds on the control pulse derivatives, one for each drive
  • dda_bound::Float64=1.0: the bound on the control pulse second derivative
  • dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives)): the bounds on the control pulse second derivatives, one for each drive
  • Δt_min::Float64=Δt isa Float64 ? 0.5 * Δt : 0.5 * mean(Δt): the minimum time step size
  • Δt_max::Float64=Δt isa Float64 ? 1.5 * Δt : 1.5 * mean(Δt): the maximum time step size
  • 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
  • constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]: the constraints to enforce
source

Options

QuantumCollocation.Options.PiccoloOptionsType
PiccoloOptions

Options for the Piccolo quantum optimal control library.

Fields

  • verbose::Bool = true: Print verbose output
  • timesteps_all_equal::Bool = true: Use equal timesteps
  • rollout_integrator::Function = expv: Integrator to use for rollout
  • geodesic = true: Use the geodesic to initialize the optimization.
  • zero_initial_and_final_derivative::Bool=false: Zero the initial and final control pulse derivatives.
  • complex_control_norm_constraint_name::Union{Nothing, Symbol} = nothing: Name of the complex control norm constraint.
  • complex_control_norm_constraint_radius::Float64 = 1.0: Radius of the complex control norm constraint.
  • bound_state::Bool = false: Bound the state.
  • leakage_suppression::Bool = false: Suppress leakage.
  • R_leakage::Float64 = 1.0: Leakage suppression parameter.
source

Trajectory Initialization

QuantumCollocation.TrajectoryInitialization.unitary_geodesicFunction
unitary_geodesic(
    operator::EmbeddedOperator,
    samples::Int;
    kwargs...
)

unitary_geodesic(
    U_goal::AbstractMatrix{<:Number},
    samples::Int;
    kwargs...
)

unitary_geodesic(
    U₀::AbstractMatrix{<:Number},
    U₁::AbstractMatrix{<:Number},
    samples::Number;
    kwargs...
)

unitary_geodesic(
    U₀::AbstractMatrix{<:Number},
    U₁::AbstractMatrix{<:Number},
    timesteps::AbstractVector{<:Number};
    return_generator=false
)

Compute a geodesic connecting two unitary operators.

source
QuantumCollocation.TrajectoryInitialization.unitary_geodesicMethod
unitary_geodesic(U_init, U_goal, times; kwargs...)

Compute the geodesic connecting Uinit and Ugoal at the specified times. Allows for the possibility of unequal times and ranges outside [0,1].

Arguments

  • U_init::AbstractMatrix{<:Number}: The initial unitary operator.
  • U_goal::AbstractMatrix{<:Number}: The goal unitary operator.
  • times::AbstractVector{<:Number}: The times at which to evaluate the geodesic.

Keyword Arguments

  • return_unitary_isos::Bool=true: If true returns a matrix where each column is a unitary isovec, i.e. vec(vcat(real(U), imag(U))). If false, returns a vector of unitary matrices.
  • return_generator::Bool=false: If true, returns the effective Hamiltonian generating the geodesic.
source

Trajectory Interpolations

Quantum System Templates

QuantumCollocation.QuantumSystemTemplates.MultiTransmonSystemMethod
MultiTransmonSystem(
    ωs::AbstractVector{Float64},
    δs::AbstractVector{Float64},
    gs::AbstractMatrix{Float64};
    levels_per_transmon::Int = 3,
    subsystem_levels::AbstractVector{Int} = fill(levels_per_transmon, length(ωs)),
    lab_frame=false,
    subsystems::AbstractVector{Int} = 1:length(ωs),
    subsystem_drive_indices::AbstractVector{Int} = 1:length(ωs),
    kwargs...
) -> CompositeQuantumSystem

Returns a CompositeQuantumSystem object for a multi-transmon system.

source
QuantumCollocation.QuantumSystemTemplates.RydbergChainSystemMethod
RydbergChainSystem(;
    N::Int=3, # number of atoms
    C::Float64=862690*2π,
    distance::Float64=10.0, # μm
    cutoff_order::Int=2, # 1 is nearest neighbor, 2 is next-nearest neighbor, etc.
    local_detune::Bool=false, # If true, include one local detuning pattern.
    all2all::Bool=true, # If true, include all-to-all interactions.
    ignore_Y_drive::Bool=false, # If true, ignore the Y drive. (In the experiments, X&Y drives are implemented by Rabi amplitude and its phase.)
) -> QuantumSystem

Returns a QuantumSystem object for the Rydberg atom chain in the spin basis |g⟩ = |0⟩ = [1, 0], |r⟩ = |1⟩ = [0, 1].

\[H = \sum_i 0.5*\Omega_i(t)\cos(\phi_i(t)) \sigma_i^x - 0.5*\Omega_i(t)\sin(\phi_i(t)) \sigma_i^y - \sum_i \Delta_i(t)n_i + \sum_{i<j} \frac{C}{|i-j|^6} n_i n_j\]

Keyword Arguments

  • N: Number of atoms.
  • C: The Rydberg interaction strength in MHz*μm^6.
  • distance: The distance between atoms in μm.
  • cutoff_order: Interaction range cutoff, 1 is nearest neighbor, 2 is next nearest neighbor.
  • local_detune: If true, include one local detuning pattern.
  • all2all: If true, include all-to-all interactions.
  • ignore_Y_drive: If true, ignore the Y drive. (In the experiments, X&Y drives are implemented by Rabi amplitude and its phase.)
source
QuantumCollocation.QuantumSystemTemplates.TransmonDipoleCouplingFunction
TransmonDipoleCoupling(
    g_ij::Float64,
    pair::Tuple{Int, Int},
    subsystem_levels::Vector{Int};
    lab_frame::Bool=false,
) -> QuantumSystemCoupling

TransmonDipoleCoupling(
    g_ij::Float64,
    pair::Tuple{Int, Int},
    sub_systems::Vector{QuantumSystem};
    kwargs...
) -> QuantumSystemCoupling

Returns a QuantumSystemCoupling object for a transmon qubit. In the lab frame, the Hamiltonian coupling term is

\[H = g_{ij} (a_i + a_i^\dagger) (a_j + a_j^\dagger)\]

In the rotating frame, the Hamiltonian coupling term is

\[H = g_{ij} (a_i a_j^\dagger + a_i^\dagger a_j)\]

where a_i is the annihilation operator for the ith transmon.

source
QuantumCollocation.QuantumSystemTemplates.TransmonSystemMethod
TransmonSystem(;
    ω::Float64=4.4153,  # GHz
    δ::Float64=0.17215, # GHz
    levels::Int=3,
    lab_frame::Bool=false,
    frame_ω::Float64=ω,
) -> QuantumSystem

Returns a QuantumSystem object for a transmon qubit, with the Hamiltonian

\[H = \omega a^\dagger a - \frac{\delta}{2} a^\dagger a^\dagger a a\]

where a is the annihilation operator.

Keyword Arguments

  • ω: The frequency of the transmon, in GHz.
  • δ: The anharmonicity of the transmon, in GHz.
  • levels: The number of levels in the transmon.
  • lab_frame: Whether to use the lab frame Hamiltonian, or an ω-rotating frame.
  • frame_ω: The frequency of the rotating frame, in GHz.
  • mutiply_by_2π: Whether to multiply the Hamiltonian by 2π, set to true by default because the frequency is in GHz.
  • lab_frame_type: The type of lab frame Hamiltonian to use, one of (:duffing, :quartic, :cosine).
  • drives: Whether to include drives in the Hamiltonian.
source