Your First Gate

This tutorial walks through synthesizing your first quantum gate with Piccolo.jl. We'll implement an X gate (NOT gate) on a single qubit.

What We're Doing

We want to find control pulses that implement:

\[X = \begin{pmatrix} 0 & 1 \\ 1 & 0 \end{pmatrix}\]

Our qubit has Hamiltonian:

\[H(t) = \frac{\omega}{2}\sigma_z + u_x(t)\sigma_x + u_y(t)\sigma_y\]

The optimizer will find $u_x(t)$ and $u_y(t)$ that produce the X gate.

Setup

First, load the required packages:

using Piccolo
using CairoMakie
using Random
Random.seed!(42)  # For reproducibility
Random.TaskLocalRNG()

Step 1: Define the Quantum System

A QuantumSystem needs:

  • Drift Hamiltonian: Always-on terms (qubit frequency)
  • Drive Hamiltonians: Controllable interactions
  • Drive bounds: Maximum control amplitudes
# The drift Hamiltonian: ω/2 σ_z (qubit frequency)
# We set ω = 1.0 for simplicity
H_drift = 0.5 * PAULIS[:Z]

# The drive Hamiltonians: σ_x and σ_y controls
H_drives = [PAULIS[:X], PAULIS[:Y]]

# Maximum amplitude for each drive (in same units as H_drift)
drive_bounds = [1.0, 1.0]

# Create the system
sys = QuantumSystem(H_drift, H_drives, drive_bounds)
QuantumSystem: levels = 2, n_drives = 2

Let's check what we created:

sys.levels, sys.n_drives
(2, 2)

Step 2: Create an Initial Pulse

We need an initial guess for the control pulse. ZeroOrderPulse represents piecewise constant controls - the standard choice for most problems.

# Gate duration and discretization
T = 10.0   # Total time (in units where ω = 1)
N = 100    # Number of timesteps

# Time vector
times = collect(range(0, T, length = N))

# Random initial controls (small amplitude)
# Shape: (n_drives, N) = (2, 100)
initial_controls = 0.1 * randn(2, N)

# Create the pulse
pulse = ZeroOrderPulse(initial_controls, times)
ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}(DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}([-0.03633574814517775 -0.031498797116895606 … 0.17995350308617175 -0.1529323847225266; 0.02517372155742292 -0.03112524013244207 … -0.0844068143386927 -0.019509907821117518], [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])

Check the pulse:

duration(pulse)
10.0
n_drives(pulse)
2
pulse(5.0)
2-element Vector{Float64}:
  0.036820693581548374
 -0.004656094092083756

Step 3: Define the Goal

A UnitaryTrajectory combines the system, pulse, and target gate.

# Our target: the X gate
U_goal = GATES[:X]

U_goal

# Create the trajectory
qtraj = UnitaryTrajectory(sys, pulse, U_goal)
UnitaryTrajectory{ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}, SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, Matrix{ComplexF64}}(QuantumSystem: levels = 2, n_drives = 2, ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}(DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}([-0.03633574814517775 -0.031498797116895606 … 0.17995350308617175 -0.1529323847225266; 0.02517372155742292 -0.03112524013244207 … -0.0844068143386927 -0.019509907821117518], [0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091  …  9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Union{}[], nothing, :left, DataInterpolations.ExtrapolationType.None, DataInterpolations.ExtrapolationType.None, FindFirstFunctions.Guesser{Vector{Float64}}([0.0, 0.10101010101010101, 0.20202020202020202, 0.30303030303030304, 0.40404040404040403, 0.5050505050505051, 0.6060606060606061, 0.7070707070707071, 0.8080808080808081, 0.9090909090909091  …  9.090909090909092, 9.191919191919192, 9.292929292929292, 9.393939393939394, 9.494949494949495, 9.595959595959595, 9.696969696969697, 9.797979797979798, 9.8989898989899, 10.0], Base.RefValue{Int64}(100), true), false, true), 10.0, 2, :u, [0.0, 0.0], [0.0, 0.0]), ComplexF64[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], ComplexF64[0.0 + 0.0im 1.0 + 0.0im; 1.0 + 0.0im 0.0 + 0.0im], SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}(Matrix{ComplexF64}[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], [0.99874049446695 - 0.049979006477971294im -0.0025163151855861713 + 0.0036320491838595435im; 0.002516315185586171 + 0.0036320491838595435im 0.99874049446695 + 0.049979006477971294im], [0.9949810320689114 - 0.09981289144825772im 0.0005709258525007132 + 0.007057376813909546im; -0.0005709258525007129 + 0.007057376813909546im 0.9949810320689114 + 0.09981289144825772im], [0.9887658393613924 - 0.14943927490410971im -0.0028633575662276463 - 0.0013487815029180564im; 0.0028633575662276463 - 0.0013487815029180538im 0.9887658393613928 + 0.14943927490410983im], [0.979981762894018 - 0.19864605125380624im 0.009784354920096761 + 0.008930683915593065im; -0.009784354920096758 + 0.00893068391559306im 0.9799817628940185 + 0.19864605125380644im], [0.9684330490544085 - 0.2475426200748999im 0.006255019836320246 + 0.028652320542691984im; -0.006255019836320255 + 0.028652320542691963im 0.9684330490544096 + 0.24754262007490024im], [0.9545756768205786 - 0.2959077942999352im -0.0022411486341588046 + 0.03491177090724906im; 0.0022411486341587803 + 0.034911770907249035im 0.9545756768205799 + 0.2959077942999357im], [0.9387134809542094 - 0.3431380556891894im 0.0036526082710561735 + 0.03255662552373212im; -0.003652608271056193 + 0.03255662552373208im 0.9387134809542103 + 0.3431380556891899im], [0.9205157647071577 - 0.3899942142126536im -0.005319283447156803 + 0.022955283266838468im; 0.005319283447156781 + 0.022955283266838433im 0.9205157647071585 + 0.3899942142126542im], [0.8998651411970133 - 0.43524992055471023im 0.005299411419695657 + 0.02778759712899248im; -0.005299411419695668 + 0.027787597128992432im 0.899865141197014 + 0.4352499205547108im]  …  [-0.1565570398394763 + 0.9803405137174955im 0.0859168901893295 + 0.08390863138569517im; -0.08591689018932915 + 0.08390863138569477im -0.15655703983947478 - 0.980340513717495im], [-0.10627981428265139 + 0.9862998268384023im 0.08882399164098882 + 0.08959660241076312im; -0.08882399164098848 + 0.08959660241076271im -0.10627981428264989 - 0.9862998268384016im], [-0.05560307695161047 + 0.989411305209827im 0.09249529550753958 + 0.09704734548394092im; -0.09249529550753928 + 0.09704734548394052im -0.05560307695160901 - 0.9894113052098261im], [-0.005308097848379 + 0.9908356354709656im 0.09387395992606189 + 0.09697549806979967im; -0.09387395992606158 + 0.09697549806979934im -0.005308097848377577 - 0.990835635470965im], [0.0437323700313623 + 0.9910715170919516im 0.0946717279438635 + 0.08307822668200485im; -0.09467172794386322 + 0.08307822668200456im 0.043732370031363724 - 0.9910715170919514im], [0.0940074950298834 + 0.987961884274963im 0.09240819025740452 + 0.08096068472677832im; -0.0924081902574042 + 0.08096068472677803im 0.09400749502988479 - 0.9879618842749626im], [0.1421136661698235 + 0.9795879102004807im 0.11532998572347819 + 0.08312777195291275im; -0.11532998572347793 + 0.08312777195291249im 0.14211366616982493 - 0.9795879102004805im], [0.19017980779190863 + 0.9728869829525824im 0.11418657941947384 + 0.06545215191375613im; -0.11418657941947344 + 0.0654521519137558im 0.19017980779190974 - 0.9728869829525807im], [0.23711689646909526 + 0.9617476966304098im 0.1264142539474302 + 0.05325769272027365im; -0.12641425394742972 + 0.0532576927202733im 0.23711689646909623 - 0.9617476966304076im], [0.28472921676617113 + 0.9512275311815304im 0.11360437213046226 + 0.034489181997622145im; -0.11360437213046172 + 0.03448918199762179im 0.2847292167661721 - 0.951227531181528im]], nothing, nothing, [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9  …  9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0], Vector{Matrix{ComplexF64}}[[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im]]], nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}(SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}(MatrixOperator(2 × 2), LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, SciMLBase.DEFAULT_OBSERVED, nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(Dict{Symbol, Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(:U => CartesianIndices((2, 2)), :U_2_2 => CartesianIndex(2, 2), :U_1_1 => CartesianIndex(1, 1), :U_2_1 => CartesianIndex(2, 1), :U_1_2 => CartesianIndex(1, 2)), :t, Dict{Symbol, Float64}()), nothing, nothing), ComplexF64[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], (0.0, 10.0), SciMLBase.NullParameters(), Base.Pairs(:tstops => [0.0, 0.1, 0.10101010101010101, 0.2, 0.20202020202020202, 0.3, 0.30303030303030304, 0.4, 0.40404040404040403, 0.5  …  9.5, 9.595959595959595, 9.6, 9.696969696969697, 9.7, 9.797979797979798, 9.8, 9.8989898989899, 9.9, 10.0]), SciMLBase.StandardODEProblem()), OrdinaryDiffEqLinear.MagnusAdapt4(), OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}(SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}(MatrixOperator(2 × 2), LinearAlgebra.UniformScaling{Bool}(true), nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, nothing, SciMLBase.DEFAULT_OBSERVED, nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(Dict{Symbol, Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}(:U => CartesianIndices((2, 2)), :U_2_2 => CartesianIndex(2, 2), :U_1_1 => CartesianIndex(1, 1), :U_2_1 => CartesianIndex(2, 1), :U_1_2 => CartesianIndex(1, 2)), :t, Dict{Symbol, Float64}()), nothing, nothing), Matrix{ComplexF64}[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im], [0.99874049446695 - 0.049979006477971294im -0.0025163151855861713 + 0.0036320491838595435im; 0.002516315185586171 + 0.0036320491838595435im 0.99874049446695 + 0.049979006477971294im], [0.9949810320689114 - 0.09981289144825772im 0.0005709258525007132 + 0.007057376813909546im; -0.0005709258525007129 + 0.007057376813909546im 0.9949810320689114 + 0.09981289144825772im], [0.9887658393613924 - 0.14943927490410971im -0.0028633575662276463 - 0.0013487815029180564im; 0.0028633575662276463 - 0.0013487815029180538im 0.9887658393613928 + 0.14943927490410983im], [0.979981762894018 - 0.19864605125380624im 0.009784354920096761 + 0.008930683915593065im; -0.009784354920096758 + 0.00893068391559306im 0.9799817628940185 + 0.19864605125380644im], [0.9684330490544085 - 0.2475426200748999im 0.006255019836320246 + 0.028652320542691984im; -0.006255019836320255 + 0.028652320542691963im 0.9684330490544096 + 0.24754262007490024im], [0.9545756768205786 - 0.2959077942999352im -0.0022411486341588046 + 0.03491177090724906im; 0.0022411486341587803 + 0.034911770907249035im 0.9545756768205799 + 0.2959077942999357im], [0.9387134809542094 - 0.3431380556891894im 0.0036526082710561735 + 0.03255662552373212im; -0.003652608271056193 + 0.03255662552373208im 0.9387134809542103 + 0.3431380556891899im], [0.9205157647071577 - 0.3899942142126536im -0.005319283447156803 + 0.022955283266838468im; 0.005319283447156781 + 0.022955283266838433im 0.9205157647071585 + 0.3899942142126542im], [0.8998651411970133 - 0.43524992055471023im 0.005299411419695657 + 0.02778759712899248im; -0.005299411419695668 + 0.027787597128992432im 0.899865141197014 + 0.4352499205547108im]  …  [-0.1565570398394763 + 0.9803405137174955im 0.0859168901893295 + 0.08390863138569517im; -0.08591689018932915 + 0.08390863138569477im -0.15655703983947478 - 0.980340513717495im], [-0.10627981428265139 + 0.9862998268384023im 0.08882399164098882 + 0.08959660241076312im; -0.08882399164098848 + 0.08959660241076271im -0.10627981428264989 - 0.9862998268384016im], [-0.05560307695161047 + 0.989411305209827im 0.09249529550753958 + 0.09704734548394092im; -0.09249529550753928 + 0.09704734548394052im -0.05560307695160901 - 0.9894113052098261im], [-0.005308097848379 + 0.9908356354709656im 0.09387395992606189 + 0.09697549806979967im; -0.09387395992606158 + 0.09697549806979934im -0.005308097848377577 - 0.990835635470965im], [0.0437323700313623 + 0.9910715170919516im 0.0946717279438635 + 0.08307822668200485im; -0.09467172794386322 + 0.08307822668200456im 0.043732370031363724 - 0.9910715170919514im], [0.0940074950298834 + 0.987961884274963im 0.09240819025740452 + 0.08096068472677832im; -0.0924081902574042 + 0.08096068472677803im 0.09400749502988479 - 0.9879618842749626im], [0.1421136661698235 + 0.9795879102004807im 0.11532998572347819 + 0.08312777195291275im; -0.11532998572347793 + 0.08312777195291249im 0.14211366616982493 - 0.9795879102004805im], [0.19017980779190863 + 0.9728869829525824im 0.11418657941947384 + 0.06545215191375613im; -0.11418657941947344 + 0.0654521519137558im 0.19017980779190974 - 0.9728869829525807im], [0.23711689646909526 + 0.9617476966304098im 0.1264142539474302 + 0.05325769272027365im; -0.12641425394742972 + 0.0532576927202733im 0.23711689646909623 - 0.9617476966304076im], [0.28472921676617113 + 0.9512275311815304im 0.11360437213046226 + 0.034489181997622145im; -0.11360437213046172 + 0.03448918199762179im 0.2847292167661721 - 0.951227531181528im]], [0.0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9  …  9.1, 9.2, 9.3, 9.4, 9.5, 9.6, 9.7, 9.8, 9.9, 10.0], Vector{Matrix{ComplexF64}}[[[1.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 1.0 + 0.0im]]], nothing, false, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}(ComplexF64[0.28472921676617113 + 0.9512275311815304im 0.11360437213046226 + 0.034489181997622145im; -0.11360437213046172 + 0.03448918199762179im 0.2847292167661721 - 0.951227531181528im], ComplexF64[0.28463776168318966 + 0.9512519023493696im 0.11361992702753938 + 0.03452064719777919im; -0.11361992702753886 + 0.03452064719777884im 0.28463776168319066 - 0.9512519023493674im], ComplexF64[0.28463776168318966 + 0.9512519023493696im 0.11361992702753938 + 0.03452064719777919im; -0.11361992702753886 + 0.03452064719777884im 0.28463776168319066 - 0.9512519023493674im], ComplexF64[2.0e-8 + 0.0im 1.0e-8 + 0.0im; 1.0e-8 + 0.0im 2.0e-8 + 0.0im], ComplexF64[0.4722477664809377 - 0.11895879909371958im -0.1298954218420899 - 0.18832366855019803im; 0.12989542184209055 - 0.1883236685501978im 0.4722477664809366 + 0.11895879909371995im], 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.4681228419123984 - 0.15906551516630307im 0.16827312652921067 - 0.03181622939526403im; -0.16827312652921086 - 0.03181622939526395im 0.46812284191239717 + 0.15906551516630363im], ComplexF64[0.0 + 0.0im 0.0 + 0.0im; 0.0 + 0.0im 0.0 + 0.0im], ComplexF64[0.011214299682400088 - 0.002117795683583515im -0.043526402558164375 + 0.082500419311832im; 0.04352640379863892 + 0.08250041869159479im 0.011214296896992305 + 0.0021178012543991063im], nothing), nothing, false), false, 0, SciMLBase.DEStats(1869, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1176, 690, 0.0), nothing, SciMLBase.ReturnCode.Success, nothing, nothing, nothing))

Step 4: Set Up the Optimization Problem

SmoothPulseProblem creates an optimization problem with:

  • Fidelity objective (weight Q)
  • Control regularization (weight R)
  • Smoothness via derivative bounds
qcp = SmoothPulseProblem(
    qtraj,
    N;
    Q = 100.0,       # Fidelity weight (higher = prioritize fidelity)
    R = 1e-2,        # Regularization weight (higher = smoother controls)
    ddu_bound = 1.0,  # Limit on control acceleration
)
QuantumControlProblem{UnitaryTrajectory{ZeroOrderPulse{DataInterpolations.ConstantInterpolation{Matrix{Float64}, Vector{Float64}, Vector{Union{}}, Float64}}, SciMLBase.ODESolution{ComplexF64, 3, Vector{Matrix{ComplexF64}}, Nothing, Nothing, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, SciMLBase.ODEProblem{Matrix{ComplexF64}, Tuple{Float64, Float64}, true, SciMLBase.NullParameters, SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Base.Pairs{Symbol, Vector{Float64}, Nothing, @NamedTuple{tstops::Vector{Float64}}}, SciMLBase.StandardODEProblem}, OrdinaryDiffEqLinear.MagnusAdapt4, OrdinaryDiffEqCore.InterpolationData{SciMLBase.ODEFunction{true, SciMLBase.FullSpecialize, SciMLOperators.MatrixOperator{ComplexF64, Matrix{ComplexF64}, SciMLOperators.FilterKwargs{Nothing, Val{()}}, SciMLOperators.FilterKwargs{Piccolo.Quantum.Rollouts.var"#update!#_construct_operator##2"{QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}}, Val{()}}}, LinearAlgebra.UniformScaling{Bool}, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, Nothing, typeof(SciMLBase.DEFAULT_OBSERVED), Nothing, Piccolo.Quantum.Rollouts.PiccoloRolloutSystem{Union{Int64, AbstractVector{Int64}, CartesianIndex, CartesianIndices}}, Nothing, Nothing}, Vector{Matrix{ComplexF64}}, Vector{Float64}, Vector{Vector{Matrix{ComplexF64}}}, Nothing, OrdinaryDiffEqLinear.MagnusAdapt4Cache{Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Matrix{ComplexF64}, Nothing}, Nothing}, SciMLBase.DEStats, Nothing, Nothing, Nothing, Nothing}, Matrix{ComplexF64}}}
  System: QuantumSystem{Piccolo.Quantum.QuantumSystems.var"#32#33"{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}, Vector{SparseArrays.SparseMatrixCSC{ComplexF64, Int64}}, Int64}, Piccolo.Quantum.QuantumSystems.var"#34#35"{Vector{SparseArrays.SparseMatrixCSC{Float64, Int64}}, Int64, SparseArrays.SparseMatrixCSC{Float64, Int64}}, @NamedTuple{}}
  Goal: Matrix{ComplexF64}
  Trajectory: 100 knots
  State: Ũ⃗
  Controls: u

Step 5: Solve!

The solve! function runs the optimizer:

solve!(qcp; max_iter = 20, verbose = false, print_level = 1)

Step 6: Analyze the Results

First, check the fidelity:

fidelity(qcp)
0.9992100214821484

Get the optimized trajectory:

traj = get_trajectory(qcp)

# Check the final unitary
U_final = iso_vec_to_operator(traj[:Ũ⃗][:, end])
round.(U_final, digits = 3)
2×2 Matrix{ComplexF64}:
 0.017+0.015im  -0.017+1.0im
 0.017+1.0im     0.017-0.015im

Step 7: Visualize

Plot the optimized control pulses:

fig = Figure(size = (800, 400))

# Time axis
plot_times = cumsum([0; get_timesteps(traj)])[1:(end-1)]

# Control pulses
ax1 = Axis(
    fig[1, 1],
    xlabel = "Time",
    ylabel = "Control Amplitude",
    title = "Optimized Controls",
)
lines!(ax1, plot_times, traj[:u][1, :], label = "u_x (σ_x drive)", linewidth = 2)
lines!(ax1, plot_times, traj[:u][2, :], label = "u_y (σ_y drive)", linewidth = 2)
axislegend(ax1, position = :rt)

fig
Example block output

Understanding the Solution

The optimizer found control pulses that:

  1. Start and end smoothly (due to derivative regularization)
  2. Stay within bounds (due to drive_bounds)
  3. Achieve high fidelity (due to the Q-weighted objective)

The X gate rotates the qubit state around the X-axis by π radians. You can see the controls create the right rotation!

What's Next?

Now that you've synthesized your first gate, try:

  1. Different gates: Change U_goal to GATES[:H] (Hadamard) or GATES[:T]
  2. Faster gates: Reduce T and see how fidelity changes
  3. Smoother pulses: Increase R or decrease ddu_bound
  4. Time-optimal: Add Δt_bounds and use MinimumTimeProblem

Continue to the State Transfer tutorial to learn about preparing specific quantum states.


This page was generated using Literate.jl.