PiccoloOptions Reference
PiccoloOptions provides advanced configuration for problem templates. This page documents all available options and their effects.
using QuantumCollocation
using PiccoloQuantumObjectsCreating PiccoloOptions
Default options:
opts = PiccoloOptions()PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, false, false, 0.01, 0.01)Custom options:
opts_custom = PiccoloOptions(
verbose = true,
leakage_constraint = true,
bound_state = true
)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, true, true, 0.01, 0.01)Pass to any problem template:
system = QuantumSystem(0.1 * PAULIS.Z, [PAULIS.X, PAULIS.Y], [1.0, 1.0])
U_goal = EmbeddedOperator(GATES.H, system)
T = 10.0
qtraj = UnitaryTrajectory(system, U_goal, T)
N = 51
prob = SmoothPulseProblem(
qtraj, N;
piccolo_options = opts_custom
)QuantumControlProblem{PiccoloQuantumObjects.QuantumTrajectories.UnitaryTrajectory{PiccoloQuantumObjects.Pulses.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{PiccoloQuantumObjects.Rollouts.var"#update!#_construct_operator##2"{PiccoloQuantumObjects.QuantumSystems.QuantumSystem{PiccoloQuantumObjects.QuantumSystems.var"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, PiccoloQuantumObjects.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, PiccoloQuantumObjects.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{PiccoloQuantumObjects.Rollouts.var"#update!#_construct_operator##2"{PiccoloQuantumObjects.QuantumSystems.QuantumSystem{PiccoloQuantumObjects.QuantumSystems.var"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, PiccoloQuantumObjects.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, PiccoloQuantumObjects.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}, PiccoloQuantumObjects.EmbeddedOperators.EmbeddedOperator{ComplexF64}}}
System: PiccoloQuantumObjects.QuantumSystems.QuantumSystem{PiccoloQuantumObjects.QuantumSystems.var"#26#27"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, PiccoloQuantumObjects.QuantumSystems.var"#28#29"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}
Goal: PiccoloQuantumObjects.EmbeddedOperators.EmbeddedOperator{ComplexF64}
Trajectory: 51 knots
State: Ũ⃗
Controls: uGeneral Options
verbose::Bool = false
Print detailed information during problem setup.
opts_verbose = PiccoloOptions(verbose = true)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, false, false, 0.01, 0.01)Shows: constraint counts, objective terms, trajectory initialization details
free_time::Bool = false
Allow timesteps to vary (used internally by minimum time problems). Typically not set directly by users.
State and Unitary Options
bound_state::Bool = false
Constrain state/unitary to lie on unit sphere (for numerical stability). Recommended for difficult convergence.
opts_bounded = PiccoloOptions(bound_state = true)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, true, false, 0.01, 0.01)Adds constraint: ||ψ||² = 1 (ket) or ||U||² = N (unitary)
geodesic::Bool = true
Use geodesic interpolation for initial trajectory.
true: States evolve along shortest path on manifold (better initial guess)false: Linear interpolation (simpler but often worse)
opts_linear = PiccoloOptions(geodesic = false)PiccoloOptions(true, true, ExponentialAction.expv, false, false, nothing, 1.0, false, false, 0.01, 0.01)Control Initialization
init_trajectory::Union{NamedTrajectory, Nothing} = nothing
Provide custom initial trajectory instead of automatic initialization.
trajcustom = initializetrajectory(...) optsinit = PiccoloOptions(inittrajectory = traj_custom)
build_trajectory_constraints::Bool = true
Automatically extract constraints from trajectory bounds. Set to false if manually managing constraints.
Leakage Suppression (Multilevel Systems)
leakage_constraint::Bool = false
Add constraint to limit leakage population.
leakage_constraint_value::Float64 = 1e-3
Maximum allowed leakage: ∑ᵢ |⟨i|ψ⟩|² ≤ leakageconstraintvalue
leakage_cost::Float64 = 1.0
Penalty weight for leakage in objective (soft constraint).
opts_leakage = PiccoloOptions(
leakage_constraint = true,
leakage_constraint_value = 1e-2, # 1% max leakage
leakage_cost = 1e-1
)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, false, true, 0.01, 0.1)Example with embedded operator: systransmon = TransmonSystem(levels=5, δ=0.2) op = EmbeddedOperator(:X, systransmon) probleakage = UnitarySmoothPulseProblem( systransmon, op, T, Δt; piccolooptions = optsleakage )
Control Constraints
complex_control_norm_constraint_name::Union{Symbol, Nothing} = nothing
Apply norm constraint to complex control amplitudes.
For systems with complex drives (e.g., rotating frame): optsnorm = PiccoloOptions( complexcontrolnormconstraintname = :u, complexcontrolnormconstraintradius = 0.2 ) Enforces: |ureal + i*u_imag| ≤ radius
complex_control_norm_constraint_radius::Float64 = 1.0
Radius for complex control norm constraint.
Timestep Options
timesteps_all_equal::Bool = false
Force all timesteps to be equal: Δt[k] = Δt[1] ∀k. Useful for hardware with fixed sampling rates.
opts_equal_dt = PiccoloOptions(timesteps_all_equal = true)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, false, false, 0.01, 0.01)Derivative Constraints
zero_initial_and_final_derivative::Bool = false
Force derivatives to zero at boundaries: u̇[1] = u̇[T] = 0, ü[1] = ü[T] = 0. Creates "smooth ramp" pulses that start and end at zero derivative.
opts_smooth_edges = PiccoloOptions(zero_initial_and_final_derivative = true)PiccoloOptions(true, true, ExponentialAction.expv, true, true, nothing, 1.0, false, false, 0.01, 0.01)Common Configuration Patterns
Quick and dirty optimization
opts_quick = PiccoloOptions(
verbose = false,
geodesic = true
)PiccoloOptions(false, true, ExponentialAction.expv, true, false, nothing, 1.0, false, false, 0.01, 0.01)High-fidelity gate
opts_hifi = PiccoloOptions(
verbose = true,
bound_state = true,
geodesic = true,
)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, true, false, 0.01, 0.01)Multilevel system with leakage suppression
opts_multilevel = PiccoloOptions(
bound_state = true,
leakage_constraint = true,
leakage_constraint_value = 1e-2,
leakage_cost = 1e-1,
verbose = true
)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, true, true, 0.01, 0.1)Smooth pulses for hardware
opts_hardware = PiccoloOptions(
zero_initial_and_final_derivative = true,
timesteps_all_equal = true,
bound_state = true
)PiccoloOptions(true, true, ExponentialAction.expv, true, true, nothing, 1.0, true, false, 0.01, 0.01)Robust optimization
opts_robust = PiccoloOptions(
bound_state = true,
geodesic = true,
verbose = true
)PiccoloOptions(true, true, ExponentialAction.expv, true, false, nothing, 1.0, true, false, 0.01, 0.01)Tips and Tricks
When to use bound_state=true:
- Optimization struggling to converge
- Fidelity stuck below 0.99
- Numerical instabilities in state evolution
- Working with large Hilbert spaces
Leakage vs bounds:
- Leakage constraint enforces hard limit (may fail to converge)
- Leakage cost adds soft penalty (more forgiving)
- Use both for best results
Geodesic initialization:
- Almost always better than linear
- Only disable for debugging or special cases
- Particularly important for large T
Rollout integrator:
:padeis fast and usually sufficient:expmore accurate for sensitive systems- Both give same result for well-conditioned problems
This page was generated using Literate.jl.