Quickstart Guide
This guide shows you how to set up and solve a quantum optimal control problem in Piccolo.jl. We'll synthesize a single-qubit X gate.
The Problem
We want to find control pulses that implement an X gate on a single qubit with system Hamiltonian:
\[H(t) = \frac{\omega}{2} \sigma_z + u_1(t) \sigma_x + u_2(t) \sigma_y\]
using PiccoloStep 1: Define the Quantum System
First, we define our quantum system by specifying the drift Hamiltonian (always-on), the drive Hamiltonians (controllable), and the bounds on control amplitudes.
# Drift Hamiltonian: qubit frequency term
H_drift = 0.5 * PAULIS[:Z]
# Drive Hamiltonians: X and Y controls
H_drives = [PAULIS[:X], PAULIS[:Y]]
# Maximum control amplitudes
drive_bounds = [1.0, 1.0]
# Create the quantum system
sys = QuantumSystem(H_drift, H_drives, drive_bounds)QuantumSystem: levels = 2, n_drives = 2Step 2: Create an Initial Pulse
We need an initial guess for the control pulse. ZeroOrderPulse represents piecewise constant controls.
# Time parameters
T = 10.0 # Total gate duration
N = 100 # Number of timesteps
# Create time vector
times = collect(range(0, T, length = N))
# Random initial controls (scaled by drive bounds)
initial_controls = 0.1 * randn(2, N)
# Create the pulse
pulse = ZeroOrderPulse(initial_controls, times)ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}(DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}([0.13505168807180154 -0.00017043774368383387 … 0.09191160969671607 0.10021322643579433; -0.15031490034069994 -0.06483022711387205 … 0.09472578354906547 0.06863589822838588], [0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091 … 9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Union{}[], nothing, :left, DataInterpolations.ExtrapolationType.None, DataInterpolations.ExtrapolationType.None, FindFirstFunctions.Guesser{Vector{Float64}}([0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091 … 9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Base.RefValue{Int64}(1), true), false, true), 10.0, 2, :u, [0.0, 0.0], [0.0, 0.0])Step 3: Define the Goal via a Trajectory
A UnitaryTrajectory combines the system, pulse, and target gate.
# Target: X gate
U_goal = GATES[:X]
# Create the trajectory
qtraj = UnitaryTrajectory(sys, pulse, U_goal)UnitaryTrajectory{ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}, SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, Matrix{ComplexF64}}(QuantumSystem: levels = 2, n_drives = 2, ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}(DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}([0.13505168807180154 -0.00017043774368383387 … 0.09191160969671607 0.10021322643579433; -0.15031490034069994 -0.06483022711387205 … 0.09472578354906547 0.06863589822838588], [0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091 … 9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Union{}[], nothing, :left, DataInterpolations.ExtrapolationType.None, DataInterpolations.ExtrapolationType.None, FindFirstFunctions.Guesser{Vector{Float64}}([0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091 … 9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Base.RefValue{Int64}(100), true), false, true), 10.0, 2, :u, [0.0, 0.0], [0.0, 0.0]), ComplexF64[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], ComplexF64[0.0 + 0.0im 1.0 + 0.0im; 1.0 + 0.0im 0.0 + 0.0im], SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}(Matrix{ComplexF64}[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], [0.9985461847611781 - 0.049975767396785546im 0.01502420499139564 - 0.01349862349923918im; -0.015024204991395642 - 0.013498623499239183im 0.9985461847611781 + 0.049975767396785546im], [0.9946793386338727 - 0.09990599069355205im 0.0208724418511671 - 0.014005266494804762im; -0.020872441851167104 - 0.014005266494804764im 0.9946793386338727 + 0.09990599069355208im], [0.9886095645374565 - 0.14973635423131215im 0.015142120592858403 - 0.0009323682354583224im; -0.015142120592858408 - 0.0009323682354583206im 0.9886095645374565 + 0.14973635423131218im], [0.9797802062587517 - 0.19870376889794913im 0.01573075921492902 - 0.01732347724418015im; -0.015730759214929026 - 0.017323477244180145im 0.979780206258752 + 0.19870376889794925im], [0.9683397185305563 - 0.24751954899927056im 0.02525248367930983 - 0.020361101330382728im; -0.02525248367930983 - 0.020361101330382728im 0.9683397185305567 + 0.24751954899927076im], [0.954381149474034 - 0.2956645849130596im 0.03427587183944368 - 0.0237537232124681im; -0.03427587183944369 - 0.023753723212468107im 0.9543811494740346 + 0.29566458491305986im], [0.9383835632256944 - 0.34301003609629477im 0.03378620931515955 - 0.025276381568158205im; -0.03378620931515954 - 0.025276381568158205im 0.9383835632256949 + 0.3430100360962949im], [0.9198755634671874 - 0.38902140951789865im 0.032596094246262905 - 0.03779927661371501im; -0.032596094246262884 - 0.037799276613714995im 0.9198755634671877 + 0.3890214095178988im], [0.899339602102191 - 0.4351573723133708im 0.03407456377495617 - 0.025792741528224274im; -0.034074563774956136 - 0.025792741528224243im 0.8993396021021908 + 0.43515737231337054im] … [-0.15964274711076035 + 0.9870232918515156im -0.017272375453027997 + 0.0009379145728905674im; 0.017272375453028094 + 0.0009379145728897893im -0.15964274711075904 - 0.9870232918515096im], [-0.11000021244679269 + 0.9935377856530287im -0.027890265238359833 - 0.0021805610013239203im; 0.027890265238360003 - 0.002180561001324713im -0.11000021244679166 - 0.9935377856530222im], [-0.060262745896775737 + 0.9976179518232772im -0.03354442396963678 + 0.0012630429387348327im; 0.03354442396963704 + 0.0012630429387340651im -0.06026274589677506 - 0.997617951823271im], [-0.010720204987534792 + 0.999485907664626im -0.026763180529449912 + 0.014026038385857358im; 0.026763180529450203 + 0.01402603838585668im -0.01072020498753444 - 0.9994859076646202im], [0.03912260673093089 + 0.9989132912602952im -0.019370349789413217 + 0.01632322686075674im; 0.019370349789413502 + 0.016323226860756074im 0.0391226067309309 - 0.9989132912602886im], [0.08886511724247736 + 0.9959554356314629im -0.0042432261188498415 + 0.012560103731219624im; 0.004243226118850074 + 0.01256010373121894im 0.08886511724247705 - 0.9959554356314564im], [0.13839517259535672 + 0.9902926249165185im 0.007451526087561413 + 0.010572038461452554im; -0.007451526087561215 + 0.010572038461451862im 0.1383951725953559 - 0.9902926249165113im], [0.18758975979359138 + 0.982189473612959im 0.00685210890879586 - 0.008183431309273485im; -0.006852108908795616 - 0.008183431309274302im 0.1875897597935902 - 0.982189473612952im], [0.23645847737827755 + 0.9716095347703657im -0.004633453111839342 + 0.006389955518706918im; 0.004633453111839701 + 0.006389955518706218im 0.23645847737827608 - 0.971609534770359im], [0.2847161472024357 + 0.9583900037975212im -0.015473127077975582 + 0.013634459344938886im; 0.015473127077976047 + 0.013634459344938255im 0.28471614720243377 - 0.9583900037975145im]], nothing, nothing, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 … 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0], Vector{Matrix{ComplexF64}}[[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im]]], nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}(SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}(MatrixOperator(2 × 2), LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, SciMLBase.DEFAULT_OBSERVED, nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(Dict{Symbol, Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(:U => CartesianIndices((2, 2)), :U_2_2 => CartesianIndex(2, 2), :U_1_1 => CartesianIndex(1, 1), :U_2_1 => CartesianIndex(2, 1), :U_1_2 => CartesianIndex(1, 2)), :t, Dict{Symbol, Float64}()), nothing, nothing), ComplexF64[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], (0.0, 10.0), SciMLBase.NullParameters(), Base.Pairs(:tstops => [0.0, 0.1, 0.10101010101010101, 0.2, 0.20202020202020202, 0.3, 0.30303030303030304, 0.4, 0.40404040404040403, 0.5 … 9.5, 9.595959595959595, 9.6, 9.696969696969697, 9.7, 9.797979797979798, 9.8, 9.8989898989899, 9.9, 10.0]), SciMLBase.StandardODEProblem()), OrdinaryDiffEqLinear.MagnusAdapt4(), OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}(SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}(MatrixOperator(2 × 2), LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, SciMLBase.DEFAULT_OBSERVED, nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(Dict{Symbol, Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(:U => CartesianIndices((2, 2)), :U_2_2 => CartesianIndex(2, 2), :U_1_1 => CartesianIndex(1, 1), :U_2_1 => CartesianIndex(2, 1), :U_1_2 => CartesianIndex(1, 2)), :t, Dict{Symbol, Float64}()), nothing, nothing), Matrix{ComplexF64}[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], [0.9985461847611781 - 0.049975767396785546im 0.01502420499139564 - 0.01349862349923918im; -0.015024204991395642 - 0.013498623499239183im 0.9985461847611781 + 0.049975767396785546im], [0.9946793386338727 - 0.09990599069355205im 0.0208724418511671 - 0.014005266494804762im; -0.020872441851167104 - 0.014005266494804764im 0.9946793386338727 + 0.09990599069355208im], [0.9886095645374565 - 0.14973635423131215im 0.015142120592858403 - 0.0009323682354583224im; -0.015142120592858408 - 0.0009323682354583206im 0.9886095645374565 + 0.14973635423131218im], [0.9797802062587517 - 0.19870376889794913im 0.01573075921492902 - 0.01732347724418015im; -0.015730759214929026 - 0.017323477244180145im 0.979780206258752 + 0.19870376889794925im], [0.9683397185305563 - 0.24751954899927056im 0.02525248367930983 - 0.020361101330382728im; -0.02525248367930983 - 0.020361101330382728im 0.9683397185305567 + 0.24751954899927076im], [0.954381149474034 - 0.2956645849130596im 0.03427587183944368 - 0.0237537232124681im; -0.03427587183944369 - 0.023753723212468107im 0.9543811494740346 + 0.29566458491305986im], [0.9383835632256944 - 0.34301003609629477im 0.03378620931515955 - 0.025276381568158205im; -0.03378620931515954 - 0.025276381568158205im 0.9383835632256949 + 0.3430100360962949im], [0.9198755634671874 - 0.38902140951789865im 0.032596094246262905 - 0.03779927661371501im; -0.032596094246262884 - 0.037799276613714995im 0.9198755634671877 + 0.3890214095178988im], [0.899339602102191 - 0.4351573723133708im 0.03407456377495617 - 0.025792741528224274im; -0.034074563774956136 - 0.025792741528224243im 0.8993396021021908 + 0.43515737231337054im] … [-0.15964274711076035 + 0.9870232918515156im -0.017272375453027997 + 0.0009379145728905674im; 0.017272375453028094 + 0.0009379145728897893im -0.15964274711075904 - 0.9870232918515096im], [-0.11000021244679269 + 0.9935377856530287im -0.027890265238359833 - 0.0021805610013239203im; 0.027890265238360003 - 0.002180561001324713im -0.11000021244679166 - 0.9935377856530222im], [-0.060262745896775737 + 0.9976179518232772im -0.03354442396963678 + 0.0012630429387348327im; 0.03354442396963704 + 0.0012630429387340651im -0.06026274589677506 - 0.997617951823271im], [-0.010720204987534792 + 0.999485907664626im -0.026763180529449912 + 0.014026038385857358im; 0.026763180529450203 + 0.01402603838585668im -0.01072020498753444 - 0.9994859076646202im], [0.03912260673093089 + 0.9989132912602952im -0.019370349789413217 + 0.01632322686075674im; 0.019370349789413502 + 0.016323226860756074im 0.0391226067309309 - 0.9989132912602886im], [0.08886511724247736 + 0.9959554356314629im -0.0042432261188498415 + 0.012560103731219624im; 0.004243226118850074 + 0.01256010373121894im 0.08886511724247705 - 0.9959554356314564im], [0.13839517259535672 + 0.9902926249165185im 0.007451526087561413 + 0.010572038461452554im; -0.007451526087561215 + 0.010572038461451862im 0.1383951725953559 - 0.9902926249165113im], [0.18758975979359138 + 0.982189473612959im 0.00685210890879586 - 0.008183431309273485im; -0.006852108908795616 - 0.008183431309274302im 0.1875897597935902 - 0.982189473612952im], [0.23645847737827755 + 0.9716095347703657im -0.004633453111839342 + 0.006389955518706918im; 0.004633453111839701 + 0.006389955518706218im 0.23645847737827608 - 0.971609534770359im], [0.2847161472024357 + 0.9583900037975212im -0.015473127077975582 + 0.013634459344938886im; 0.015473127077976047 + 0.013634459344938255im 0.28471614720243377 - 0.9583900037975145im]], [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 … 9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0], Vector{Matrix{ComplexF64}}[[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im]]], nothing, false, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}(ComplexF64[0.2847161472024357 + 0.9583900037975212im -0.015473127077975582 + 0.013634459344938886im; 0.015473127077976047 + 0.013634459344938255im 0.28471614720243377 - 0.9583900037975145im], ComplexF64[0.2841163761926485 + 0.9585713608089637im -0.015337519715722166 + 0.013549594273994634im; 0.015337519715722631 + 0.013549594273994003im 0.2841163761926466 - 0.9585713608089571im], ComplexF64[0.2841163761926485 + 0.9585713608089637im -0.015337519715722166 + 0.013549594273994634im; 0.015337519715722631 + 0.013549594273994003im 0.2841163761926466 - 0.9585713608089571im], ComplexF64[2.0e-8 + 0.0im 1.0e-8 + 0.0im; 1.0e-8 + 0.0im 2.0e-8 + 0.0im], ComplexF64[0.47907818685217096 - 0.14475138015652744im -0.10824218599809504 + 0.0723565896211196im; 0.10824218599809615 + 0.07235658962112029im 0.4790781868521678 + 0.14475138015652653im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[0.4794993430850257 - 0.14484449895275114im -0.10876787329525704 + 0.04498419857321191im; 0.10876787329525817 + 0.044984198573212404im 0.4794993430850224 + 0.14484449895275017im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[0.03838843507863771 - 0.008468335757492304im 0.3512740998708854 - 0.005725121097347173im; -0.3512741000408525 - 0.005725121267314257im 0.038388432302789606 + 0.008468341309188825im], nothing), nothing, false), false, 0, SciMLBase.DEStats(1844, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1158, 683, 0.0), nothing, SciMLBase.ReturnCode.Success, nothing, nothing, nothing))Step 4: Set Up the Optimization Problem
SmoothPulseProblem creates the optimization problem with:
- Fidelity objective (weight Q)
- Regularization for smooth controls (weight R)
- Derivative bounds for control smoothness
qcp = SmoothPulseProblem(
qtraj,
N;
Q = 100.0, # Fidelity weight
R = 1e-2, # Regularization weight
ddu_bound = 1.0, # Control acceleration bound
)QuantumControlProblem{UnitaryTrajectory{ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}, SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, Matrix{ComplexF64}}}
System: QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}
Goal: Matrix{ComplexF64}
Trajectory: 100 knots
State: Ũ⃗
Controls: uStep 5: Solve!
solve!(qcp; max_iter = 20, verbose = false, print_level = 1)Step 6: Analyze Results
After solving, we can check the fidelity and examine the optimized controls.
# Check final fidelity
fidelity(qcp)0.9999995867273045Access the trajectory and check the final unitary:
traj = get_trajectory(qcp)
U_final = iso_vec_to_operator(traj[:Ũ⃗][:, end])
round.(U_final, digits = 3)2×2 Matrix{ComplexF64}:
0.0+0.0im 0.001-1.0im
-0.001-1.0im 0.0-0.0imVisualization
Piccolo provides specialized plotting functions for quantum trajectories:
using CairoMakie
# Plot the unitary evolution (state populations over time)
fig = plot_unitary_populations(traj)
Minimum Time Optimization
Now let's find the shortest gate duration that achieves 99% fidelity.
First, we need to create a new problem with variable timesteps enabled:
# Create problem with free-time optimization
qcp_free = SmoothPulseProblem(
qtraj,
N;
Q = 100.0,
R = 1e-2,
ddu_bound = 1.0,
Δt_bounds = (0.01, 0.5), # Enable variable timesteps
)
solve!(
qcp_free;
max_iter = 20,
verbose = false,
print_level = 1,
)
# Convert to minimum time problem
qcp_mintime = MinimumTimeProblem(qcp_free; final_fidelity = 0.99)
solve!(
qcp_mintime;
max_iter = 20,
verbose = false,
print_level = 1,
) constructing SmoothPulseProblem for UnitaryTrajectory...
applying timesteps_all_equal constraint: Δt
constructing MinimumTimeProblem from QuantumControlProblem{UnitaryTrajectory{ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}, SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, Matrix{ComplexF64}}}...
final fidelity constraint: 0.99
minimum-time weight D: 100.0Compare durations:
initial_duration = sum(get_timesteps(get_trajectory(qcp_free)))
minimum_duration = sum(get_timesteps(get_trajectory(qcp_mintime)))
initial_duration12.429085117242698minimum_duration5.605073009405118fidelity(qcp_mintime)0.9908208074426424Plot the time-optimal solution:
fig_mintime = plot_unitary_populations(get_trajectory(qcp_mintime))
State Preparation
Instead of synthesizing a full unitary gate, you can prepare a specific quantum state using KetTrajectory:
ψ_init = ComplexF64[1.0, 0.0] # |0⟩
ψ_goal = ComplexF64[0.0, 1.0] # |1⟩
qcp_state = SmoothPulseProblem(KetTrajectory(sys, pulse, ψ_init, ψ_goal), N)
solve!(
qcp_state;
max_iter = 20,
verbose = false,
print_level = 1,
)
fidelity(qcp_state)0.994225519370145Robust Control
To optimize a pulse that works across parameter variations (e.g., uncertain qubit frequency), use SamplingProblem:
# Perturbed systems: ±10% drift Hamiltonian
sys_low = QuantumSystem(0.9 * H_drift, H_drives, drive_bounds)
sys_high = QuantumSystem(1.1 * H_drift, H_drives, drive_bounds)
# Start from a nominal solution, then add robustness
qcp_robust = SamplingProblem(qcp, [sys_low, sys, sys_high])
solve!(
qcp_robust;
max_iter = 20,
verbose = false,
print_level = 1,
)
fidelity(qcp_robust)3-element Vector{Float64}:
0.9970676593183584
0.9999785687241922
0.9971921002966301Next Steps
- See Concepts for the mathematical formulation
- Learn about different Problem Templates
- Explore Tutorials for more complex examples
This page was generated using Literate.jl.