Core Concepts

This page introduces the fundamental concepts in Piccolo.jl. For detailed documentation, see the Concepts section.

The Quantum Optimal Control Problem

Quantum optimal control finds control pulses that steer a quantum system to achieve a desired outcome. In Piccolo.jl, this means:

  1. Define a system: What physical hardware are you controlling?
  2. Specify a goal: What gate or state do you want to achieve?
  3. Optimize controls: Find pulse shapes that achieve the goal

Key Objects

QuantumSystem

A QuantumSystem represents the physical hardware:

using Piccolo

# Hamiltonian: H(t) = H_drift + u₁(t)·H_drive₁ + u₂(t)·H_drive₂
H_drift = PAULIS[:Z]            # Always-on term
H_drives = [PAULIS[:X], PAULIS[:Y]]  # Controllable terms
drive_bounds = [1.0, 1.0]       # Maximum control amplitudes

sys = QuantumSystem(H_drift, H_drives, drive_bounds)
QuantumSystem: levels = 2, n_drives = 2

Pulse

A Pulse specifies how controls vary in time:

T = 10.0   # Total duration
N = 100    # Number of time points
times = collect(range(0, T, length = N))
controls = 0.1 * randn(2, N)  # Initial control values

pulse = ZeroOrderPulse(controls, times)
ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}(DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}([-0.05106165073408293 -0.005198116683408737 … -0.09739303141625383 0.042380849478247204; 0.1225364412724832 0.045435681100392866 … 0.07709273577197155 -0.01741239487943842], [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])

Trajectory

A Trajectory combines system, pulse, and goal:

U_goal = GATES[:X]  # Target: X gate
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"#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.05106165073408293 -0.005198116683408737 … -0.09739303141625383 0.042380849478247204; 0.1225364412724832 0.045435681100392866 … 0.07709273577197155 -0.01741239487943842], [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"#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.9949162009931328 - 0.09983048253011612im -0.012232872059755236 + 0.005097509231567758im; 0.012232872059755236 + 0.005097509231567758im 0.994916200993133 + 0.09983048253011614im], [0.9799108606740561 - 0.1986730149559464im -0.0162274608135415 + 0.006356711169294307im; 0.016227460813541497 + 0.006356711169294307im 0.9799108606740562 + 0.19867301495594644im], [0.9552931645681296 - 0.29556615186094176im -0.007058522933630617 + 0.0024076664052106967im; 0.007058522933630615 + 0.002407666405210695im 0.9552931645681296 + 0.2955661518609418im], [0.9208447938901851 - 0.38953533830574866im -0.011416866966076711 - 0.01329439449721832im; 0.011416866966076715 - 0.013294394497218321im 0.9208447938901851 + 0.3895353383057488im], [0.8774852875804932 - 0.47951745631442005im -0.008627052170042835 - 0.0028553704458632763im; 0.008627052170042839 - 0.0028553704458632763im 0.8774852875804932 + 0.4795174563144202im], [0.8252079619552707 - 0.5647377527562335im 0.010103616092798565 + 0.0010035334162101965im; -0.010103616092798565 + 0.0010035334162101944im 0.8252079619552707 + 0.5647377527562337im], [0.764416006341465 - 0.6440933338070055im 0.028444148726567465 + 0.0016961714428535672im; -0.02844414872656746 + 0.0016961714428535642im 0.7644160063414651 + 0.6440933338070057im], [0.6965563413682349 - 0.7171913343339141im 0.01974622125210251 - 0.00747930493440444im; -0.019746221252102507 - 0.00747930493440444im 0.6965563413682349 + 0.7171913343339144im], [0.6216083403562415 - 0.7833280979168668im -0.0003742912836680948 - 0.00014872638480583136im; 0.0003742912836680913 - 0.00014872638480582616im 0.6216083403562415 + 0.7833280979168671im]  …  [-0.9436978044872053 - 0.3074048310500086im 0.12201869191258959 - 0.006939919097540654im; -0.12201869191258968 - 0.006939919097540811im -0.9436978044872077 + 0.30740483105000954im], [-0.969075765577413 - 0.20994285280064762im 0.12944205637649622 - 0.007804688942927936im; -0.1294420563764963 - 0.0078046889429281355im -0.9690757655774158 + 0.20994285280064834im], [-0.9875163293281491 - 0.11109125925558115im 0.11138678611692965 - 0.007950805355717124im; -0.11138678611692972 - 0.00795080535571737im -0.9875163293281518 + 0.11109125925558157im], [-0.9917721705440915 - 0.010417314839609901im 0.12730630517145972 - 0.008517390996124311im; -0.1273063051714597 - 0.00851739099612459im -0.9917721705440941 + 0.010417314839610031im], [-0.989566268287535 + 0.08854604987772594im 0.11172770088579721 - 0.020859495998312348im; -0.1117277008857972 - 0.02085949599831263im -0.9895662682875374 - 0.08854604987772606im], [-0.974715058324255 + 0.18862191700979053im 0.11851792097841536 - 0.017487993208088158im; -0.1185179209784153 - 0.017487993208088477im -0.9747150583242573 - 0.18862191700979092im], [-0.9517375581247861 + 0.28435696701486113im 0.11015452450799931 - 0.034680203217273546im; -0.11015452450799923 - 0.034680203217273844im -0.9517375581247883 - 0.28435696701486174im], [-0.9183078839052895 + 0.37971923719847467im 0.10781929742854746 - 0.029982167380108546im; -0.10781929742854733 - 0.02998216738010886im -0.9183078839052917 - 0.37971923719847545im], [-0.8762737485275562 + 0.47006873293454526im 0.09941049236238317 - 0.03601746752676792im; -0.09941049236238303 - 0.03601746752676824im -0.8762737485275585 - 0.47006873293454626im], [-0.8237859062638481 + 0.5544739442116061im 0.10662494860751084 - 0.05066109124286543im; -0.10662494860751065 - 0.05066109124286572im -0.8237859062638502 - 0.5544739442116073im]], 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"#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, 10.0), SciMLBase.NullParameters(), Base.Pairs(:tstops => [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], :saveat => [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]), 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.9949162009931328 - 0.09983048253011612im -0.012232872059755236 + 0.005097509231567758im; 0.012232872059755236 + 0.005097509231567758im 0.994916200993133 + 0.09983048253011614im], [0.9799108606740561 - 0.1986730149559464im -0.0162274608135415 + 0.006356711169294307im; 0.016227460813541497 + 0.006356711169294307im 0.9799108606740562 + 0.19867301495594644im], [0.9552931645681296 - 0.29556615186094176im -0.007058522933630617 + 0.0024076664052106967im; 0.007058522933630615 + 0.002407666405210695im 0.9552931645681296 + 0.2955661518609418im], [0.9208447938901851 - 0.38953533830574866im -0.011416866966076711 - 0.01329439449721832im; 0.011416866966076715 - 0.013294394497218321im 0.9208447938901851 + 0.3895353383057488im], [0.8774852875804932 - 0.47951745631442005im -0.008627052170042835 - 0.0028553704458632763im; 0.008627052170042839 - 0.0028553704458632763im 0.8774852875804932 + 0.4795174563144202im], [0.8252079619552707 - 0.5647377527562335im 0.010103616092798565 + 0.0010035334162101965im; -0.010103616092798565 + 0.0010035334162101944im 0.8252079619552707 + 0.5647377527562337im], [0.764416006341465 - 0.6440933338070055im 0.028444148726567465 + 0.0016961714428535672im; -0.02844414872656746 + 0.0016961714428535642im 0.7644160063414651 + 0.6440933338070057im], [0.6965563413682349 - 0.7171913343339141im 0.01974622125210251 - 0.00747930493440444im; -0.019746221252102507 - 0.00747930493440444im 0.6965563413682349 + 0.7171913343339144im], [0.6216083403562415 - 0.7833280979168668im -0.0003742912836680948 - 0.00014872638480583136im; 0.0003742912836680913 - 0.00014872638480582616im 0.6216083403562415 + 0.7833280979168671im]  …  [-0.9436978044872053 - 0.3074048310500086im 0.12201869191258959 - 0.006939919097540654im; -0.12201869191258968 - 0.006939919097540811im -0.9436978044872077 + 0.30740483105000954im], [-0.969075765577413 - 0.20994285280064762im 0.12944205637649622 - 0.007804688942927936im; -0.1294420563764963 - 0.0078046889429281355im -0.9690757655774158 + 0.20994285280064834im], [-0.9875163293281491 - 0.11109125925558115im 0.11138678611692965 - 0.007950805355717124im; -0.11138678611692972 - 0.00795080535571737im -0.9875163293281518 + 0.11109125925558157im], [-0.9917721705440915 - 0.010417314839609901im 0.12730630517145972 - 0.008517390996124311im; -0.1273063051714597 - 0.00851739099612459im -0.9917721705440941 + 0.010417314839610031im], [-0.989566268287535 + 0.08854604987772594im 0.11172770088579721 - 0.020859495998312348im; -0.1117277008857972 - 0.02085949599831263im -0.9895662682875374 - 0.08854604987772606im], [-0.974715058324255 + 0.18862191700979053im 0.11851792097841536 - 0.017487993208088158im; -0.1185179209784153 - 0.017487993208088477im -0.9747150583242573 - 0.18862191700979092im], [-0.9517375581247861 + 0.28435696701486113im 0.11015452450799931 - 0.034680203217273546im; -0.11015452450799923 - 0.034680203217273844im -0.9517375581247883 - 0.28435696701486174im], [-0.9183078839052895 + 0.37971923719847467im 0.10781929742854746 - 0.029982167380108546im; -0.10781929742854733 - 0.02998216738010886im -0.9183078839052917 - 0.37971923719847545im], [-0.8762737485275562 + 0.47006873293454526im 0.09941049236238317 - 0.03601746752676792im; -0.09941049236238303 - 0.03601746752676824im -0.8762737485275585 - 0.47006873293454626im], [-0.8237859062638481 + 0.5544739442116061im 0.10662494860751084 - 0.05066109124286543im; -0.10662494860751065 - 0.05066109124286572im -0.8237859062638502 - 0.5544739442116073im]], [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.MagnusGL4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}(ComplexF64[-0.8237859062638481 + 0.5544739442116061im 0.10662494860751084 - 0.05066109124286543im; -0.10662494860751065 - 0.05066109124286572im -0.8237859062638502 - 0.5544739442116073im], ComplexF64[-0.8762737485275562 + 0.47006873293454526im 0.09941049236238317 - 0.03601746752676792im; -0.09941049236238303 - 0.03601746752676824im -0.8762737485275585 - 0.47006873293454626im], ComplexF64[-0.8762737485275562 + 0.47006873293454526im 0.09941049236238317 - 0.03601746752676792im; -0.09941049236238303 - 0.03601746752676824im -0.8762737485275585 - 0.47006873293454626im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[0.4812404101015685 + 0.8693685444290181im 0.07731829190687507 - 0.14851456445917774im; -0.0773182919068745 - 0.14851456445917746im 0.4812404101015695 - 0.8693685444290203im], 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.5504702884200847 + 0.8274226312356647im -0.0885042535080898 - 0.08136692137881336im; 0.08850425350808999 - 0.08136692137881324im 0.5504702884200859 - 0.827422631235667im], 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))

QuantumControlProblem

A QuantumControlProblem sets up the optimization:

qcp = SmoothPulseProblem(qtraj, N; Q = 100.0, R = 1e-2)
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"#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}}}
  System: 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{}}
  Goal: Matrix{ComplexF64}
  Trajectory: 100 knots
  State: Ũ⃗
  Controls: u

The Workflow

The typical Piccolo.jl workflow follows these steps:

┌─────────────────┐
│ Define System   │  sys = QuantumSystem(...)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Create Pulse    │  pulse = ZeroOrderPulse(...)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Set Goal        │  qtraj = UnitaryTrajectory(sys, pulse, U_goal)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Create Problem  │  qcp = SmoothPulseProblem(qtraj, N)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Solve!          │  solve!(qcp; max_iter=100)
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Analyze Results │  fidelity(qcp), plot(...)
└─────────────────┘

Let's run through the solve step now:

cached_solve!(qcp, "concepts_basic"; max_iter = 100)
fidelity(qcp)
0.9998622347176283

Key Parameters

Fidelity Weight (Q)

Q controls how much the optimizer prioritizes achieving high fidelity:

  • Q = 100 (default): Good balance
  • Q = 1000: Strongly prioritize fidelity
  • Q = 10: Allow more flexibility

Regularization (R)

R controls pulse smoothness:

  • R = 1e-2 (default): Moderate smoothness
  • R = 0.1: Very smooth pulses
  • R = 1e-4: Allow aggressive controls

Number of Timesteps (N)

N is the discretization resolution:

  • N = 50: Coarse, fast optimization
  • N = 100: Typical
  • N = 200+: Fine control, slower

Common Patterns

Gate Synthesis

Most common use case — synthesize a quantum gate:

qcp_gate = SmoothPulseProblem(UnitaryTrajectory(sys, pulse, GATES[:X]), N)
cached_solve!(qcp_gate, "concepts_gate"; max_iter = 100)
fidelity(qcp_gate)
0.9998622347176283

State Preparation

Prepare a specific quantum state:

ψ_init = ComplexF64[1.0, 0.0]  # |0⟩
ψ_goal = ComplexF64[0.0, 1.0]  # |1⟩
qcp_state = SmoothPulseProblem(KetTrajectory(sys, pulse, ψ_init, ψ_goal), N)
cached_solve!(qcp_state, "concepts_state"; max_iter = 100)
fidelity(qcp_state)
0.9999162206395058

Time-Optimal Control

Find the shortest gate duration:

qcp_base = SmoothPulseProblem(qtraj, N; Δt_bounds = (0.01, 0.5))
cached_solve!(qcp_base, "concepts_base_freetime"; max_iter = 100)

qcp_fast = MinimumTimeProblem(qcp_base; final_fidelity = 0.99)
cached_solve!(qcp_fast, "concepts_fast"; max_iter = 100)
fidelity(qcp_fast)
0.9928131581967247

Robust Control

Optimize for parameter uncertainty:

# Create perturbed systems
sys_low = QuantumSystem(0.9 * H_drift, H_drives, drive_bounds)
sys_nominal = sys
sys_high = QuantumSystem(1.1 * H_drift, H_drives, drive_bounds)

# Solve for nominal system first
qcp_nom = SmoothPulseProblem(qtraj, N)
cached_solve!(qcp_nom, "concepts_nominal"; max_iter = 100)

# Add robustness
perturbed_systems = [sys_low, sys_nominal, sys_high]
qcp_robust = SamplingProblem(qcp_nom, perturbed_systems)
cached_solve!(qcp_robust, "concepts_robust"; max_iter = 100)
fidelity(qcp_robust)
3-element Vector{Float64}:
 0.9979974843444708
 0.9983633876545465
 0.9972205814262113

Next Steps


This page was generated using Literate.jl.