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
└── 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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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}, saveat::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusGL4, 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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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.MagnusGL4Cache{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.08755356180895857 -0.02900143051127036 … -0.11291451236645576 -0.1349297948943124; -0.07470397661634814 0.012412397060725552 … -0.08569073125531322 0.002199126402341263], [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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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}, saveat::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusGL4, 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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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.MagnusGL4Cache{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.9947396920805778 - 0.09982459483479288im 0.014914588396549591 + 0.01747999766784457im; -0.01491458839654959 + 0.017479997667844572im 0.9947396920805781 + 0.09982459483479289im], [0.9797203513284078 - 0.1987611923728714im 0.013541523901407485 + 0.021416085774077366im; -0.013541523901407485 + 0.02141608577407737im 0.9797203513284084 + 0.19876119237287146im], [0.9550486759765133 - 0.2956651492607843im 0.011195202119066473 + 0.018406886690043204im; -0.011195202119066473 + 0.018406886690043207im 0.9550486759765138 + 0.29566514926078435im], [0.9194693194665813 - 0.38918938312962686im 0.027921830981396265 + 0.04825107225221482im; -0.027921830981396254 + 0.04825107225221481im 0.9194693194665817 + 0.3891893831296269im], [0.8746500678424851 - 0.47906233685564437im 0.033107880784469045 + 0.06626012722223379im; -0.03310788078446904 + 0.06626012722223376im 0.8746500678424856 + 0.4790623368556445im], [0.8208307540867685 - 0.5611035998416094im 0.0731329493971619 + 0.07778942796168191im; -0.07313294939716189 + 0.0777894279616819im 0.8208307540867691 + 0.5611035998416096im], [0.7592730622717755 - 0.6391870392898056im 0.09154276422156564 + 0.08102017051973966im; -0.09154276422156561 + 0.08102017051973961im 0.7592730622717759 + 0.6391870392898058im], [0.695081335222198 - 0.7124244268972919im 0.0868270151096309 + 0.042124135990464016im; -0.08682701510963088 + 0.04212413599046398im 0.6950813352221984 + 0.7124244268972921im], [0.6214087921952086 - 0.7780946147574017im 0.08870924646275244 + 0.023463867115913202im; -0.08870924646275243 + 0.023463867115913167im 0.621408792195209 + 0.7780946147574019im]  …  [-0.9023542411897384 - 0.2988517959197726im -0.2119664438351133 - 0.22696839905659622im; 0.21196644383511307 - 0.22696839905659613im -0.9023542411897397 + 0.29885179591977395im], [-0.9216959591527049 - 0.20638831680355696im -0.2479395079190872 - 0.21542149841975308im; 0.24793950791908692 - 0.21542149841975297im -0.9216959591527062 + 0.20638831680355807im], [-0.9412126775698624 - 0.10727301768808194im -0.250465783384292 - 0.1996949839419018im; 0.25046578338429165 - 0.19969498394190166im -0.9412126775698637 + 0.10727301768808291im], [-0.9388301661229176 - 0.006095453161968201im -0.278392533202119 - 0.20262863096234235im; 0.2783925332021186 - 0.2026286309623422im -0.938830166122919 + 0.006095453161969024im], [-0.9392921116745662 + 0.0848682354692875im -0.2913094329998104 - 0.1602077582378391im; 0.29130943299981 - 0.16020775823783898im -0.9392921116745676 - 0.08486823546928682im], [-0.9340658111140108 + 0.1808973705410119im -0.28200225128071893 - 0.12357965897298927im; 0.28200225128071865 - 0.1235796589729892im -0.9340658111140123 - 0.1808973705410114im], [-0.9172390046153204 + 0.2708569807673056im -0.28143974750420847 - 0.07810744463035639im; 0.2814397475042082 - 0.07810744463035638im -0.917239004615322 - 0.2708569807673052im], [-0.8871403937033763 + 0.3603111926616106im -0.2848630164706989 - 0.04484225852699141im; 0.2848630164706986 - 0.04484225852699144im -0.8871403937033779 - 0.3603111926616103im], [-0.846216432268183 + 0.44468353502243146im -0.29337571627927583 - 0.010246586596708825im; 0.29337571627927567 - 0.0102465865967089im -0.846216432268185 - 0.44468353502243146im], [-0.792011235525825 + 0.5331909972483597im -0.29726749410774594 - 0.007589479630214592im; 0.2972674941077457 - 0.007589479630214637im -0.792011235525827 - 0.5331909972483598im]], 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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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}, saveat::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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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, 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.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], :saveat => [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]), SciMLBase.StandardODEProblem()), OrdinaryDiffEqLinear.MagnusGL4(false, 30, 0), 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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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.MagnusGL4Cache{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"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#28#29"{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, 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, 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.9947396920805778 - 0.09982459483479288im 0.014914588396549591 + 0.01747999766784457im; -0.01491458839654959 + 0.017479997667844572im 0.9947396920805781 + 0.09982459483479289im], [0.9797203513284078 - 0.1987611923728714im 0.013541523901407485 + 0.021416085774077366im; -0.013541523901407485 + 0.02141608577407737im 0.9797203513284084 + 0.19876119237287146im], [0.9550486759765133 - 0.2956651492607843im 0.011195202119066473 + 0.018406886690043204im; -0.011195202119066473 + 0.018406886690043207im 0.9550486759765138 + 0.29566514926078435im], [0.9194693194665813 - 0.38918938312962686im 0.027921830981396265 + 0.04825107225221482im; -0.027921830981396254 + 0.04825107225221481im 0.9194693194665817 + 0.3891893831296269im], [0.8746500678424851 - 0.47906233685564437im 0.033107880784469045 + 0.06626012722223379im; -0.03310788078446904 + 0.06626012722223376im 0.8746500678424856 + 0.4790623368556445im], [0.8208307540867685 - 0.5611035998416094im 0.0731329493971619 + 0.07778942796168191im; -0.07313294939716189 + 0.0777894279616819im 0.8208307540867691 + 0.5611035998416096im], [0.7592730622717755 - 0.6391870392898056im 0.09154276422156564 + 0.08102017051973966im; -0.09154276422156561 + 0.08102017051973961im 0.7592730622717759 + 0.6391870392898058im], [0.695081335222198 - 0.7124244268972919im 0.0868270151096309 + 0.042124135990464016im; -0.08682701510963088 + 0.04212413599046398im 0.6950813352221984 + 0.7124244268972921im], [0.6214087921952086 - 0.7780946147574017im 0.08870924646275244 + 0.023463867115913202im; -0.08870924646275243 + 0.023463867115913167im 0.621408792195209 + 0.7780946147574019im]  …  [-0.9023542411897384 - 0.2988517959197726im -0.2119664438351133 - 0.22696839905659622im; 0.21196644383511307 - 0.22696839905659613im -0.9023542411897397 + 0.29885179591977395im], [-0.9216959591527049 - 0.20638831680355696im -0.2479395079190872 - 0.21542149841975308im; 0.24793950791908692 - 0.21542149841975297im -0.9216959591527062 + 0.20638831680355807im], [-0.9412126775698624 - 0.10727301768808194im -0.250465783384292 - 0.1996949839419018im; 0.25046578338429165 - 0.19969498394190166im -0.9412126775698637 + 0.10727301768808291im], [-0.9388301661229176 - 0.006095453161968201im -0.278392533202119 - 0.20262863096234235im; 0.2783925332021186 - 0.2026286309623422im -0.938830166122919 + 0.006095453161969024im], [-0.9392921116745662 + 0.0848682354692875im -0.2913094329998104 - 0.1602077582378391im; 0.29130943299981 - 0.16020775823783898im -0.9392921116745676 - 0.08486823546928682im], [-0.9340658111140108 + 0.1808973705410119im -0.28200225128071893 - 0.12357965897298927im; 0.28200225128071865 - 0.1235796589729892im -0.9340658111140123 - 0.1808973705410114im], [-0.9172390046153204 + 0.2708569807673056im -0.28143974750420847 - 0.07810744463035639im; 0.2814397475042082 - 0.07810744463035638im -0.917239004615322 - 0.2708569807673052im], [-0.8871403937033763 + 0.3603111926616106im -0.2848630164706989 - 0.04484225852699141im; 0.2848630164706986 - 0.04484225852699144im -0.8871403937033779 - 0.3603111926616103im], [-0.846216432268183 + 0.44468353502243146im -0.29337571627927583 - 0.010246586596708825im; 0.29337571627927567 - 0.0102465865967089im -0.846216432268185 - 0.44468353502243146im], [-0.792011235525825 + 0.5331909972483597im -0.29726749410774594 - 0.007589479630214592im; 0.2972674941077457 - 0.007589479630214637im -0.792011235525827 - 0.5331909972483598im]], [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.MagnusGL4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}(ComplexF64[-0.792011235525825 + 0.5331909972483597im -0.29726749410774594 - 0.007589479630214592im; 0.2972674941077457 - 0.007589479630214637im -0.792011235525827 - 0.5331909972483598im], ComplexF64[-0.846216432268183 + 0.44468353502243146im -0.29337571627927583 - 0.010246586596708825im; 0.29337571627927567 - 0.0102465865967089im -0.846216432268185 - 0.44468353502243146im], ComplexF64[-0.846216432268183 + 0.44468353502243146im -0.29337571627927583 - 0.010246586596708825im; 0.29337571627927567 - 0.0102465865967089im -0.846216432268185 - 0.44468353502243146im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[0.2486383355007262 + 0.4553565545795827im -0.027424973665227816 + 0.013032485040324004im; 0.027424973665227687 + 0.013032485040324171im 0.24863833550072623 - 0.45535655457958374im], 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.2669658167591891 + 0.4361325499966517im 0.06989034490210355 + 0.04294038788992173im; -0.06989034490210351 + 0.04294038788992188im 0.2669658167591892 - 0.4361325499966527im], nothing), nothing, false), false, 0, SciMLBase.DEStats(101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 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
)
cached_solve!(qcp_base, "composition_base"; max_iter = 100)

fidelity(qcp_base)
0.9885895439819546
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)
cached_solve!(qcp_robust, "composition_robust"; max_iter = 100)

fidelity(qcp_robust)
3-element Vector{Float64}:
 0.9980471826762627
 0.9975560047502058
 0.9975649548135888

Step 4: Minimize Time

qcp_mintime = MinimumTimeProblem(qcp_robust; final_fidelity = 0.95, D = 100.0)
cached_solve!(qcp_mintime, "composition_mintime"; max_iter = 100)

fidelity(qcp_mintime)
3-element Vector{Float64}:
 0.9995427435268853
 0.9939786498096678
 0.9980825885242685
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.9995427435268853
Robust: Fidelity = [0.9995427435268853, 0.9939786498096678, 0.9980825885242685]
MinTime: Fidelity = [0.9995427435268853, 0.9939786498096678, 0.9980825885242685]

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.