Composing Templates

Problem templates in Piccolo.jl are designed to be composable. You can chain them together to build sophisticated optimization pipelines that combine multiple capabilities.

Composition Overview

The templates form a hierarchy:

Base Problems (create from trajectory):
├── SmoothPulseProblem
├── BangBangPulseProblem
└── SplinePulseProblem
        │
        ▼
Wrapper Problems (wrap existing problem):
├── SamplingProblem (adds robustness)
└── MinimumTimeProblem (adds time optimization)

Any wrapper can wrap another wrapper, enabling combinations like:

  • MinimumTimeProblem(SamplingProblem(SmoothPulseProblem(...)))
  • MinimumTimeProblem(SplinePulseProblem(...))

Full Pipeline Example

Here's a complete pipeline: base optimization → robust optimization → time-optimal control.

using Piccolo

Step 1: Setup

# Define nominal system
H_drift = 0.5 * PAULIS[:Z]
H_drives = [PAULIS[:X], PAULIS[:Y]]
sys_nominal = QuantumSystem(H_drift, H_drives, [1.0, 1.0])

# Create initial trajectory
T, N = 20.0, 100
times = collect(range(0, T, length = N))
pulse = ZeroOrderPulse(0.1 * randn(2, N), times)
qtraj = UnitaryTrajectory(sys_nominal, pulse, GATES[:X])
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.024840761942905906 -0.012931627044672853 … -0.09914270509328654 -0.04843623865514553; -0.007007304581276812 -0.08828303958590332 … 0.02838513673446787 -0.010964851916284272], [0.0, 0.20202020202020202, 0.40404040404040403, 0.6060606060606061, 0.8080808080808081, 1.0101010101010102, 1.2121212121212122, 1.4141414141414141, 1.6161616161616161, 1.8181818181818181  …  18.181818181818183, 18.383838383838384, 18.585858585858585, 18.78787878787879, 18.98989898989899, 19.19191919191919, 19.393939393939394, 19.595959595959595, 19.7979797979798, 20.0], Union{}[], nothing, :left, DataInterpolations.ExtrapolationType.None, DataInterpolations.ExtrapolationType.None, FindFirstFunctions.Guesser{Vector{Float64}}([0.0, 0.20202020202020202, 0.40404040404040403, 0.6060606060606061, 0.8080808080808081, 1.0101010101010102, 1.2121212121212122, 1.4141414141414141, 1.6161616161616161, 1.8181818181818181  …  18.181818181818183, 18.383838383838384, 18.585858585858585, 18.78787878787879, 18.98989898989899, 19.19191919191919, 19.393939393939394, 19.595959595959595, 19.7979797979798, 20.0], Base.RefValue{Int64}(100), true), false, true), 20.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.9949908641865791 - 0.09983297298085714im 0.0013991200978624883 - 0.004959854231740058im; -0.001399120097862489 - 0.00495985423174006im 0.9949908641865789 + 0.09983297298085711im], [0.9798867132626343 - 0.1987377280285841im 0.018018704700881 - 0.0008190911371980083im; -0.018018704700881003 - 0.00081909113719801im 0.9798867132626345 + 0.19873772802858414im], [0.9539477730972965 - 0.2954493060572705im 0.05176057141048548 + 0.0037678906892826677im; -0.051760571410485484 + 0.0037678906892826673im 0.9539477730972967 + 0.29544930605727054im], [0.9194361351839957 - 0.3897195418672042im 0.0516787493356702 + 0.00922924004644057im; -0.05167874933567019 + 0.009229240046440572im 0.9194361351839954 + 0.38971954186720414im], [0.8770471945881267 - 0.47958037397765435im 0.0267886531870392 - 0.008558704398169421im; -0.026788653187039192 - 0.008558704398169416im 0.8770471945881267 + 0.47958037397765446im], [0.8249844540430323 - 0.5650589698802819im 0.010257106343831634 + 0.001950106306413936im; -0.010257106343831637 + 0.0019501063064139281im 0.8249844540430327 + 0.5650589698802823im], [0.7643617958661555 - 0.6446127384049101im -0.014939569472428752 + 0.0015072393196495014im; 0.014939569472428756 + 0.0015072393196494914im 0.7643617958661554 + 0.64461273840491im], [0.6962125479887693 - 0.7177707812327274im -0.009650019103786362 + 0.00026601285792528717im; 0.009650019103786362 + 0.00026601285792527676im 0.6962125479887691 + 0.7177707812327272im], [0.6195007155890403 - 0.7825381998781603im -0.04595965006843106 - 0.04171977566696615im; 0.04595965006843108 - 0.04171977566696619im 0.6195007155890397 + 0.7825381998781595im]  …  [-0.8787045874093732 - 0.28006791769731676im -0.235571909520311 + 0.3065062560329791im; 0.2355719095203108 + 0.3065062560329794im -0.8787045874093724 + 0.28006791769731637im], [-0.8989044239248752 - 0.19191695757091368im -0.20428327985015673 + 0.3367596466601394im; 0.20428327985015654 + 0.33675964666013974im -0.8989044239248746 + 0.19191695757091348im], [-0.9056248167405144 - 0.10241469392640624im -0.17285534533564456 + 0.37346479266532256im; 0.17285534533564445 + 0.37346479266532306im -0.905624816740514 + 0.1024146939264062im], [-0.9181075022118586 - 0.011340098889724629im -0.13012235542119713 + 0.3741900441742149im; 0.13012235542119702 + 0.37419004417421536im -0.9181075022118582 + 0.011340098889724617im], [-0.9180462782311664 + 0.0752021040447556im -0.07817888411977288 + 0.38134464287691305im; 0.0781788841197727 + 0.3813446428769137im -0.918046278231166 - 0.07520210404475558im], [-0.9069556680561863 + 0.17115903737827276im -0.04963951388851915 + 0.38166990812140095im; 0.04963951388851892 + 0.3816699081214016im -0.906955668056186 - 0.1711590373782727im], [-0.8877465543362228 + 0.2566933921775147im 2.271133145572454e-6 + 0.3821185125996821im; -2.271133145868116e-6 + 0.38211851259968277im -0.8877465543362225 - 0.2566933921775147im], [-0.8525249543266193 + 0.34934637043930183im 0.022308781537524667 + 0.388150272417244im; -0.022308781537525 + 0.38815027241724437im -0.8525249543266186 - 0.34934637043930167im], [-0.8078207059964332 + 0.4243998944186706im 0.07518886305747637 + 0.402066003851305im; -0.07518886305747677 + 0.40206600385130553im -0.8078207059964327 - 0.42439989441867065im], [-0.7687780993192775 + 0.4990666877845331im 0.12790691320550931 + 0.3788832230450973im; -0.12790691320550981 + 0.3788832230450978im -0.7687780993192772 - 0.4990666877845332im]], nothing, nothing, [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8  …  18.2, 18.4, 18.6, 18.8, 19.0, 19.2, 19.4, 19.6, 19.8, 20.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, 20.0), SciMLBase.NullParameters(), Base.Pairs(:tstops => [0.0, 0.2, 0.20202020202020202, 0.4, 0.40404040404040403, 0.6, 0.6060606060606061, 0.8, 0.8080808080808081, 1.0  …  19.0, 19.19191919191919, 19.2, 19.393939393939394, 19.4, 19.595959595959595, 19.6, 19.7979797979798, 19.8, 20.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.9949908641865791 - 0.09983297298085714im 0.0013991200978624883 - 0.004959854231740058im; -0.001399120097862489 - 0.00495985423174006im 0.9949908641865789 + 0.09983297298085711im], [0.9798867132626343 - 0.1987377280285841im 0.018018704700881 - 0.0008190911371980083im; -0.018018704700881003 - 0.00081909113719801im 0.9798867132626345 + 0.19873772802858414im], [0.9539477730972965 - 0.2954493060572705im 0.05176057141048548 + 0.0037678906892826677im; -0.051760571410485484 + 0.0037678906892826673im 0.9539477730972967 + 0.29544930605727054im], [0.9194361351839957 - 0.3897195418672042im 0.0516787493356702 + 0.00922924004644057im; -0.05167874933567019 + 0.009229240046440572im 0.9194361351839954 + 0.38971954186720414im], [0.8770471945881267 - 0.47958037397765435im 0.0267886531870392 - 0.008558704398169421im; -0.026788653187039192 - 0.008558704398169416im 0.8770471945881267 + 0.47958037397765446im], [0.8249844540430323 - 0.5650589698802819im 0.010257106343831634 + 0.001950106306413936im; -0.010257106343831637 + 0.0019501063064139281im 0.8249844540430327 + 0.5650589698802823im], [0.7643617958661555 - 0.6446127384049101im -0.014939569472428752 + 0.0015072393196495014im; 0.014939569472428756 + 0.0015072393196494914im 0.7643617958661554 + 0.64461273840491im], [0.6962125479887693 - 0.7177707812327274im -0.009650019103786362 + 0.00026601285792528717im; 0.009650019103786362 + 0.00026601285792527676im 0.6962125479887691 + 0.7177707812327272im], [0.6195007155890403 - 0.7825381998781603im -0.04595965006843106 - 0.04171977566696615im; 0.04595965006843108 - 0.04171977566696619im 0.6195007155890397 + 0.7825381998781595im]  …  [-0.8787045874093732 - 0.28006791769731676im -0.235571909520311 + 0.3065062560329791im; 0.2355719095203108 + 0.3065062560329794im -0.8787045874093724 + 0.28006791769731637im], [-0.8989044239248752 - 0.19191695757091368im -0.20428327985015673 + 0.3367596466601394im; 0.20428327985015654 + 0.33675964666013974im -0.8989044239248746 + 0.19191695757091348im], [-0.9056248167405144 - 0.10241469392640624im -0.17285534533564456 + 0.37346479266532256im; 0.17285534533564445 + 0.37346479266532306im -0.905624816740514 + 0.1024146939264062im], [-0.9181075022118586 - 0.011340098889724629im -0.13012235542119713 + 0.3741900441742149im; 0.13012235542119702 + 0.37419004417421536im -0.9181075022118582 + 0.011340098889724617im], [-0.9180462782311664 + 0.0752021040447556im -0.07817888411977288 + 0.38134464287691305im; 0.0781788841197727 + 0.3813446428769137im -0.918046278231166 - 0.07520210404475558im], [-0.9069556680561863 + 0.17115903737827276im -0.04963951388851915 + 0.38166990812140095im; 0.04963951388851892 + 0.3816699081214016im -0.906955668056186 - 0.1711590373782727im], [-0.8877465543362228 + 0.2566933921775147im 2.271133145572454e-6 + 0.3821185125996821im; -2.271133145868116e-6 + 0.38211851259968277im -0.8877465543362225 - 0.2566933921775147im], [-0.8525249543266193 + 0.34934637043930183im 0.022308781537524667 + 0.388150272417244im; -0.022308781537525 + 0.38815027241724437im -0.8525249543266186 - 0.34934637043930167im], [-0.8078207059964332 + 0.4243998944186706im 0.07518886305747637 + 0.402066003851305im; -0.07518886305747677 + 0.40206600385130553im -0.8078207059964327 - 0.42439989441867065im], [-0.7687780993192775 + 0.4990666877845331im 0.12790691320550931 + 0.3788832230450973im; -0.12790691320550981 + 0.3788832230450978im -0.7687780993192772 - 0.4990666877845332im]], [0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8  …  18.2, 18.4, 18.6, 18.8, 19.0, 19.2, 19.4, 19.6, 19.8, 20.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.7687780993192775 + 0.4990666877845331im 0.12790691320550931 + 0.3788832230450973im; -0.12790691320550981 + 0.3788832230450978im -0.7687780993192772 - 0.4990666877845332im], ComplexF64[-0.7689146018052686 + 0.49883831077890844im 0.12774936720346167 + 0.37896012192444956im; -0.12774936720346217 + 0.37896012192445006im -0.7689146018052683 - 0.4988383107789085im], ComplexF64[-0.7689146018052686 + 0.49883831077890844im 0.12774936720346167 + 0.37896012192444956im; -0.12774936720346217 + 0.37896012192445006im -0.7689146018052683 - 0.4988383107789085im], ComplexF64[2.0e-8 + 0.0im 1.0e-8 + 0.0im; 1.0e-8 + 0.0im 2.0e-8 + 0.0im], ComplexF64[0.2154742070351946 + 0.36103504818639137im 0.2607619866063828 - 0.12594736355058211im; -0.26076198660638306 - 0.1259473635505824im 0.21547420703519465 - 0.36103504818639126im], 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.229779185316056 + 0.3823481183202277im 0.20518498670139496 - 0.10666236842214022im; -0.20518498670139518 - 0.1066623684221405im 0.22977918531605612 - 0.3823481183202276im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[-0.040689114391198884 + 0.01775044517217071im -0.04958433515799741 - 0.12830128658801748im; 0.049584335157997386 - 0.12830128658801743im -0.040689114391198884 - 0.01775044806856168im], nothing), nothing, false), false, 0, SciMLBase.DEStats(2376, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1440, 933, 0.0), nothing, SciMLBase.ReturnCode.Success, nothing, nothing, nothing))

Step 2: Base Problem (with free time enabled)

qcp_base = SmoothPulseProblem(
    qtraj,
    N;
    Q = 100.0,
    R = 1e-2,
    Δt_bounds = (0.05, 0.5),  ## Required for MinimumTimeProblem
)
solve!(qcp_base; max_iter = 100)

fidelity(qcp_base)
0.989797705664722
sum(get_timesteps(get_trajectory(qcp_base)))
21.966699602348307

Step 3: Add Robustness

# Create perturbed systems (±5% drift variation)
sys_high = QuantumSystem(1.05 * H_drift, H_drives, [1.0, 1.0])
sys_low = QuantumSystem(0.95 * H_drift, H_drives, [1.0, 1.0])

qcp_robust = SamplingProblem(qcp_base, [sys_nominal, sys_high, sys_low]; Q = 100.0)
solve!(qcp_robust; max_iter = 100)

fidelity(qcp_robust)
3-element Vector{Float64}:
 0.9999794169785005
 0.9999917626760731
 0.9999924228552589

Step 4: Minimize Time

qcp_mintime = MinimumTimeProblem(qcp_robust; final_fidelity = 0.95, D = 100.0)
solve!(qcp_mintime; max_iter = 100)

fidelity(qcp_mintime)
3-element Vector{Float64}:
 0.9997574757773747
 0.9973204700506145
 0.9953739450195523
sum(get_timesteps(get_trajectory(qcp_mintime)))
13.125869584312529

Common Composition Patterns

Pattern 1: Robust Gate

Optimize for parameter uncertainty without time constraints.

qcp_base = SmoothPulseProblem(qtraj, N; Q=100.0)
solve!(qcp_base)

qcp_robust = SamplingProblem(qcp_base, systems)
solve!(qcp_robust)

Pattern 2: Fast Gate

Minimize time without robustness requirements.

qcp_base = SmoothPulseProblem(qtraj, N; Q=100.0, Δt_bounds=(0.01, 0.5))
solve!(qcp_base)

qcp_fast = MinimumTimeProblem(qcp_base; final_fidelity=0.99)
solve!(qcp_fast)

Pattern 3: Fast + Robust Gate

The full pipeline for production-quality gates.

qcp_base = SmoothPulseProblem(qtraj, N; Q=100.0, Δt_bounds=(0.01, 0.5))
solve!(qcp_base)

qcp_robust = SamplingProblem(qcp_base, systems)
solve!(qcp_robust)

qcp_final = MinimumTimeProblem(qcp_robust; final_fidelity=0.95)
solve!(qcp_final)

Pattern 4: Spline Warm-Start Pipeline

Start with smooth problem, refine with splines.

# Initial optimization with piecewise constant
qcp_smooth = SmoothPulseProblem(qtraj_smooth, N; Q=100.0)
solve!(qcp_smooth)

# Extract optimized pulse and convert to spline
optimized_pulse = get_pulse(qcp_smooth.qtraj)
spline_pulse = CubicSplinePulse(optimized_pulse)
qtraj_spline = UnitaryTrajectory(sys, spline_pulse, U_goal)

# Refine with spline problem
qcp_spline = SplinePulseProblem(qtraj_spline; Q=100.0)
solve!(qcp_spline; max_iter=50)  # Quick refinement

Iteration and Refinement

You can iteratively refine solutions:

# First pass: coarse optimization
qcp = SmoothPulseProblem(qtraj, 50; Q=10.0)
solve!(qcp; max_iter=50)

# Second pass: increase resolution
# ... resample to higher N ...

# Third pass: tighten tolerances
solve!(qcp; max_iter=100, tol=1e-8)

Accessing Results Through the Chain

Each wrapper preserves access to the underlying trajectory:

# Access trajectory at any level
traj = get_trajectory(qcp_mintime)
sys = get_system(qcp_mintime)

# Fidelity evaluation uses the innermost trajectory type
fid = fidelity(qcp_mintime)

# Get optimized pulse
pulse = get_pulse(qcp_mintime.qtraj)

Order Matters

The order of composition affects the optimization:

MinimumTimeProblem(SamplingProblem(base)):

  • First achieves robustness, then minimizes time
  • Time minimization respects the robust solution
  • Generally preferred for production gates

SamplingProblem(MinimumTimeProblem(base)):

  • First minimizes time, then adds robustness
  • May require re-solving if time-optimal solution isn't robust
  • Less common, but useful for exploring trade-offs

Tips for Complex Pipelines

1. Solve Each Stage

Always solve! after each composition step:

qcp_base = SmoothPulseProblem(qtraj, N)
solve!(qcp_base)  # Important!

qcp_robust = SamplingProblem(qcp_base, systems)
solve!(qcp_robust)  # Important!

qcp_mintime = MinimumTimeProblem(qcp_robust)
solve!(qcp_mintime)  # Important!

2. Monitor Progress

Check fidelity at each stage to catch issues early:

for (name, prob) in [("Base", qcp_base), ("Robust", qcp_robust), ("MinTime", qcp_mintime)]
    println("$name: Fidelity = $(fidelity(prob))")
end
Base: Fidelity = 0.9997574757773747
Robust: Fidelity = [0.9997574757773747, 0.9973204700506145, 0.9953739450195523]
MinTime: Fidelity = [0.9997574757773747, 0.9973204700506145, 0.9953739450195523]

3. Adjust Parameters at Each Stage

Different stages may need different settings:

# Base: prioritize finding a solution
qcp_base = SmoothPulseProblem(qtraj, N; Q=100.0, R=1e-2)
solve!(qcp_base; max_iter=200)

# Robust: may need more iterations
qcp_robust = SamplingProblem(qcp_base, systems; Q=100.0)
solve!(qcp_robust; max_iter=300)

# MinTime: typically faster since starting from good solution
qcp_mintime = MinimumTimeProblem(qcp_robust; final_fidelity=0.95, D=100.0)
solve!(qcp_mintime; max_iter=100)

See Also


This page was generated using Literate.jl.