using NamedTrajectories
using PiccoloQuantumObjects
using QuantumCollocationQuantum State Smooth Pulse Problem
QuantumCollocation.ProblemTemplates.QuantumStateSmoothPulseProblem — FunctionQuantumStateSmoothPulseProblem(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=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=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=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.
Each problem starts with a QuantumSystem object, which is used to define the system's Hamiltonian and control operators. The goal is to find a control pulse that drives the intial state, ψ_init, to a target state, ψ_goal.
define the quantum system
system = QuantumSystem(0.1 * PAULIS.Z, [PAULIS.X, PAULIS.Y])
ψ_init = Vector{ComplexF64}([1.0, 0.0])
ψ_goal = Vector{ComplexF64}([0.0, 1.0])
T = 51
Δt = 0.20.2create the smooth pulse problem
state_prob = QuantumStateSmoothPulseProblem(system, ψ_init, ψ_goal, T, Δt); constructing QuantumStateSmoothPulseProblem...
using integrator: typeof(KetIntegrator)
using 1 initial state(s)
applying timesteps_all_equal constraint: Δtcheck the fidelity before solving
println("Before: ", rollout_fidelity(state_prob.trajectory, system))Before: 0.5161226073103974solve the problem
solve!(state_prob, max_iter=100, verbose=true, print_level=1); initializing optimizer...
applying constraint: timesteps all equal constraint
applying constraint: initial value of ψ̃
applying constraint: initial value of a
applying constraint: final value of a
applying constraint: bounds on a
applying constraint: bounds on da
applying constraint: bounds on dda
applying constraint: bounds on Δtcheck the fidelity after solving
println("After: ", rollout_fidelity(state_prob.trajectory, system))After: 0.9999886223580653extract the control pulses
state_prob.trajectory.a |> size(2, 51)Quantum State Minimum Time Problem
QuantumCollocation.ProblemTemplates.QuantumStateMinimumTimeProblem — FunctionQuantumStateMinimumTimeProblem(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.
create the minimum time problem
min_state_prob = QuantumStateMinimumTimeProblem(state_prob, ψ_goal); constructing QuantumStateMinimumTimeProblem...
final fidelity: 1.0check the previous duration
println("Duration before: ", get_duration(state_prob.trajectory))Duration before: 6.034245376467106solve the minimum time problem
solve!(min_state_prob, max_iter=100, verbose=true, print_level=1); initializing optimizer...
applying constraint: timesteps all equal constraint
applying constraint: initial value of ψ̃
applying constraint: initial value of a
applying constraint: final value of a
applying constraint: bounds on a
applying constraint: bounds on da
applying constraint: bounds on dda
applying constraint: bounds on Δtcheck the new duration
println("Duration after: ", get_duration(min_state_prob.trajectory))Duration after: 5.000095011826651the fidelity is preserved by a constraint
println("Fidelity after: ", rollout_fidelity(min_state_prob.trajectory, system))Fidelity after: 0.99999999996561Quantum State Sampling Problem
QuantumCollocation.ProblemTemplates.QuantumStateSamplingProblem — Functioncreate a sampling problem
driftless_system = QuantumSystem([PAULIS.X, PAULIS.Y])
sampling_state_prob = QuantumStateSamplingProblem([system, driftless_system], ψ_init, ψ_goal, T, Δt); constructing QuantumStateSamplingProblem...
using integrator: typeof(KetIntegrator)
using 2 initial state(s)
applying timesteps_all_equal constraint: Δtnew keys are added to the trajectory for the new states
println(sampling_state_prob.trajectory.state_names)(:ψ̃1_system_1, :a, :da, :ψ̃1_system_2)solve the sampling problem for a few iterations
solve!(sampling_state_prob, max_iter=25, verbose=true, print_level=1); initializing optimizer...
applying constraint: timesteps all equal constraint
applying constraint: initial value of ψ̃1_system_1
applying constraint: initial value of a
applying constraint: initial value of ψ̃1_system_2
applying constraint: final value of a
applying constraint: bounds on a
applying constraint: bounds on da
applying constraint: bounds on dda
applying constraint: bounds on Δtcheck the fidelity of the sampling problem (use the updated key to get the initial and goal)
println("After (original system): ", rollout_fidelity(sampling_state_prob.trajectory, system, state_name=:ψ̃1_system_1))
println("After (new system): ", rollout_fidelity(sampling_state_prob.trajectory, driftless_system, state_name=:ψ̃1_system_1))After (original system): 0.9847946766520873
After (new system): 0.9851238501101708compare this to using the original problem on the new system
println("After (new system, original `prob`): ", rollout_fidelity(state_prob.trajectory, driftless_system))After (new system, original `prob`): 0.9474795456518124This page was generated using Literate.jl.