From acbf5753708c6ea35270afc0f1b554fde597ee7f Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Wed, 21 Aug 2024 17:19:00 -0400 Subject: [PATCH 01/35] refactor: template options into PiccoloOptions (in progress) --- src/QuantumCollocation.jl | 6 +- src/constraints/_constraints.jl | 4 + src/constraints/complex_modulus_constraint.jl | 28 ++--- src/options.jl | 11 +- src/problem_templates/_problem_templates.jl | 53 ++++++++ .../unitary_sampling_problem.jl | 21 +--- .../unitary_smooth_pulse_problem.jl | 118 ++++++++++-------- 7 files changed, 159 insertions(+), 82 deletions(-) diff --git a/src/QuantumCollocation.jl b/src/QuantumCollocation.jl index bf22a5a..7bbe3b3 100644 --- a/src/QuantumCollocation.jl +++ b/src/QuantumCollocation.jl @@ -3,6 +3,9 @@ module QuantumCollocation using Reexport +include("options.jl") +@reexport using .Options + include("isomorphisms.jl") @reexport using .Isomorphisms @@ -42,9 +45,6 @@ include("dynamics.jl") include("evaluators.jl") @reexport using .Evaluators -include("options.jl") -@reexport using .Options - include("problems.jl") @reexport using .Problems diff --git a/src/constraints/_constraints.jl b/src/constraints/_constraints.jl index a059ad8..8b17808 100644 --- a/src/constraints/_constraints.jl +++ b/src/constraints/_constraints.jl @@ -3,6 +3,7 @@ module Constraints export AbstractConstraint export LinearConstraint + export constrain! export NonlinearConstraint @@ -12,6 +13,7 @@ export NonlinearInequalityConstraint using ..Losses using ..Isomorphisms using ..StructureUtils +using ..Options using TrajectoryIndexingUtils using NamedTrajectories @@ -126,4 +128,6 @@ struct NonlinearInequalityConstraint <: NonlinearConstraint params::Dict{Symbol, Any} end + + end diff --git a/src/constraints/complex_modulus_constraint.jl b/src/constraints/complex_modulus_constraint.jl index 9e0de5f..6972edc 100644 --- a/src/constraints/complex_modulus_constraint.jl +++ b/src/constraints/complex_modulus_constraint.jl @@ -20,13 +20,13 @@ function ComplexModulusContraint(; R::Union{Float64, Nothing}=nothing, comps::Union{AbstractVector{Int}, Nothing}=nothing, times::Union{AbstractVector{Int}, Nothing}=nothing, - dim::Union{Int, Nothing}=nothing, + zdim::Union{Int, Nothing}=nothing, T::Union{Int, Nothing}=nothing, ) @assert !isnothing(R) "must provide a value R, s.t. |z| <= R" @assert !isnothing(comps) "must provide components of the complex number" @assert !isnothing(times) "must provide times" - @assert !isnothing(dim) "must provide a trajectory dimension" + @assert !isnothing(zdim) "must provide a trajectory dimension" @assert !isnothing(T) "must provide a T" @assert length(comps) == 2 "component must represent a complex number and have dimension 2" @@ -37,7 +37,7 @@ function ComplexModulusContraint(; params[:R] = R params[:comps] = comps params[:times] = times - params[:dim] = dim + params[:zdim] = zdim params[:T] = T gₜ(xₜ, yₜ) = [R^2 - xₜ^2 - yₜ^2] @@ -47,7 +47,7 @@ function ComplexModulusContraint(; @views function g(Z⃗) r = zeros(length(times)) for (i, t) ∈ enumerate(times) - zₜ = Z⃗[slice(t, comps, dim)] + zₜ = Z⃗[slice(t, comps, zdim)] xₜ = zₜ[1] yₜ = zₜ[2] r[i] = gₜ(xₜ, yₜ)[1] @@ -58,17 +58,17 @@ function ComplexModulusContraint(; ∂g_structure = [] for (i, t) ∈ enumerate(times) - push!(∂g_structure, (i, index(t, comps[1], dim))) - push!(∂g_structure, (i, index(t, comps[2], dim))) + push!(∂g_structure, (i, index(t, comps[1], zdim))) + push!(∂g_structure, (i, index(t, comps[2], zdim))) end @views function ∂g(Z⃗; ipopt=true) ∂ = spzeros(length(times), length(Z⃗)) for (i, t) ∈ enumerate(times) - zₜ = Z⃗[slice(t, comps, dim)] + zₜ = Z⃗[slice(t, comps, zdim)] xₜ = zₜ[1] yₜ = zₜ[2] - ∂[i, slice(t, comps, dim)] = ∂gₜ(xₜ, yₜ) + ∂[i, slice(t, comps, zdim)] = ∂gₜ(xₜ, yₜ) end if ipopt return [∂[i, j] for (i, j) in ∂g_structure] @@ -83,15 +83,15 @@ function ComplexModulusContraint(; push!( μ∂²g_structure, ( - index(t, comps[1], dim), - index(t, comps[1], dim) + index(t, comps[1], zdim), + index(t, comps[1], zdim) ) ) push!( μ∂²g_structure, ( - index(t, comps[2], dim), - index(t, comps[2], dim) + index(t, comps[2], zdim), + index(t, comps[2], zdim) ) ) end @@ -100,7 +100,7 @@ function ComplexModulusContraint(; n = length(Z⃗) μ∂² = spzeros(n, n) for (i, t) ∈ enumerate(times) - t_slice = slice(t, comps, dim) + t_slice = slice(t, comps, zdim) μ∂²[t_slice, t_slice] = μₜ∂²gₜ(μ[i]) end if ipopt @@ -143,4 +143,4 @@ function ComplexModulusContraint( zdim=traj.dim, T=traj.T ) -end \ No newline at end of file +end diff --git a/src/options.jl b/src/options.jl index 8a3869b..f42d7c9 100644 --- a/src/options.jl +++ b/src/options.jl @@ -58,6 +58,10 @@ end Solver settings for Quantum Collocation. """ @kwdef mutable struct PiccoloOptions <: AbstractOptions + state_type::Symbol = :unitary + state_name::Symbol = :Ũ⃗ + control_name::Symbol = :a + timestep_name::Symbol = :Δt verbose::Bool = true verbose_evaluator::Bool = false free_time::Bool = true @@ -65,11 +69,16 @@ end integrator::Symbol = :pade pade_order::Int = 4 eval_hessian::Bool = false - jacobian_structure::Bool = true + jacobian_structure::Bool = integrator == :pade rollout_integrator::Function = expv geodesic = true blas_multithreading::Bool = true build_trajectory_constraints::Bool = true + complex_control_norm_constraint_name::Union{Nothing, Symbol} = nothing + complex_control_norm_constraint_radius::Float64 = 1.0 + bound_state::Bool = false + leakage_suppression::Bool = false + R_leakage::Float64 = 1.0 end diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index e82e9d2..e2ffb36 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -33,4 +33,57 @@ include("unitary_bang_bang_problem.jl") include("quantum_state_smooth_pulse_problem.jl") include("quantum_state_minimum_time_problem.jl") + +function get_piccolo_objective_and_constraints( + piccolo_options::PiccoloOptions, + traj::NamedTrajectory +) + J = NullObjective() + constraints = AbstractConstraint[] + + state_names = [ + Symbol(name) + for name ∈ string.(traj.names) + if startswith(name, string(piccolo_options.state_name)) + ] + + if piccolo_options.leakage_suppression + if operator isa EmbeddedOperator + leakage_indices = get_iso_vec_leakage_indices(operator) + for state_name in state_names + J += L1Regularizer!( + constraints, state_name, traj, + R_value=piccolo_options.R_leakage, + indices=leakage_indices, + eval_hessian=piccolo_options.eval_hessian + ) + end + else + @warn "leakage_suppression is not supported for non-embedded operators, ignoring." + end + end + + if piccolo_options.free_time + if piccolo_options.timesteps_all_equal + push!( + constraints, + TimeStepsAllEqualConstraint(piccolo_options.timestep_name, traj) + ) + end + end + + if !isnothing(piccolo_options.complex_control_norm_constraint_name) + norm_con = ComplexModulusContraint( + piccolo_options.complex_control_norm_constraint_name, + piccolo_options.complex_control_norm_constraint_radius, + traj; + ) + push!(constraints, norm_con) + end + + return J, constraints +end + + + end diff --git a/src/problem_templates/unitary_sampling_problem.jl b/src/problem_templates/unitary_sampling_problem.jl index 539a2b6..5fd8653 100644 --- a/src/problem_templates/unitary_sampling_problem.jl +++ b/src/problem_templates/unitary_sampling_problem.jl @@ -69,12 +69,6 @@ function UnitarySamplingProblem( R_a::Union{Float64, Vector{Float64}}=R, R_da::Union{Float64, Vector{Float64}}=R, R_dda::Union{Float64, Vector{Float64}}=R, - leakage_suppression=false, - R_leakage=1e-1, - bound_unitary=piccolo_options.integrator == :exponential, - control_norm_constraint=false, - control_norm_constraint_components=nothing, - control_norm_R=nothing, kwargs... ) # Create keys for multiple systems @@ -94,7 +88,7 @@ function UnitarySamplingProblem( free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, - bound_unitary=bound_unitary, + bound_unitary=piccolo_options.bound_state, drive_derivative_σ=drive_derivative_σ, a_guess=a_guess, system=systems, @@ -116,13 +110,13 @@ function UnitarySamplingProblem( J += QuadraticRegularizer(:dda, traj, R_dda) # Constraints - if leakage_suppression + if piccolo_options.leakage_suppression if operator isa EmbeddedOperator leakage_indices = get_iso_vec_leakage_indices(operator) for Ũ⃗_key in Ũ⃗_keys J += L1Regularizer!( constraints, Ũ⃗_key, traj, - R_value=R_leakage, + R_value=piccolo_options.R_leakage, indices=leakage_indices, eval_hessian=piccolo_options.eval_hessian ) @@ -138,14 +132,11 @@ function UnitarySamplingProblem( end end - if control_norm_constraint - @assert !isnothing(control_norm_constraint_components) "control_norm_constraint_components must be provided" - @assert !isnothing(control_norm_R) "control_norm_R must be provided" + if !isnothing(piccolo_options.complex_control_norm_constraint_name) norm_con = ComplexModulusContraint( - :a, - control_norm_R, + piccolo_options.complex_control_norm_constraint_name, + piccolo_options.complex_control_norm_constraint_radius, traj; - name_comps=control_norm_constraint_components, ) push!(constraints, norm_con) end diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index 3420f70..6b8ac76 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -77,7 +77,6 @@ function UnitarySmoothPulseProblem( Δt::Union{Float64, Vector{Float64}}; ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), - constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], init_trajectory::Union{NamedTrajectory, Nothing}=nothing, a_bound::Float64=1.0, a_bounds=fill(a_bound, length(system.G_drives)), @@ -94,30 +93,45 @@ function UnitarySmoothPulseProblem( R_a::Union{Float64, Vector{Float64}}=R, R_da::Union{Float64, Vector{Float64}}=R, R_dda::Union{Float64, Vector{Float64}}=R, - leakage_suppression=false, - R_leakage=1e-1, - control_norm_constraint=false, - control_norm_constraint_components=nothing, - control_norm_R=nothing, - bound_unitary=piccolo_options.integrator == :exponential, global_data::Union{NamedTuple, Nothing}=nothing, + constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], kwargs... ) + + state_name = piccolo_options.state_name + control_name = piccolo_options.control_name + control_velocity_name = Symbol(string("d", control_name)) + control_acceleration_name = Symbol(string("dd", control_name)) + timestep_name = piccolo_options.timestep_name + # Trajectory if !isnothing(init_trajectory) traj = init_trajectory else n_drives = length(system.G_drives) + + control_bound_names = ( + control_name, # a + control_velocity_name, # da + control_acceleration_name # dda + ) + + control_bounds = NamedTuple{control_bound_names}(( + a_bounds, + da_bounds, + dda_bounds + )) + traj = initialize_unitary_trajectory( operator, T, Δt, n_drives, - (a = a_bounds, da = da_bounds, dda = dda_bounds); + control_bounds; free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, - bound_unitary=bound_unitary, + bound_unitary=piccolo_options.bound_state, drive_derivative_σ=drive_derivative_σ, a_guess=a_guess, system=system, @@ -128,13 +142,13 @@ function UnitarySmoothPulseProblem( # Objective if isnothing(global_data) - J = UnitaryInfidelityObjective(:Ũ⃗, traj, Q; + J = UnitaryInfidelityObjective(state_name, traj, Q; subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing, ) else # TODO: remove hardcoded args J = UnitaryFreePhaseInfidelityObjective( - name=:Ũ⃗, + name=state_name, phase_name=:ϕ, goal=operator_to_iso_vec(operator isa EmbeddedOperator ? operator.operator : operator), phase_operators=[GATES[:Z] for _ in eachindex(traj.global_components[:ϕ])], @@ -143,58 +157,36 @@ function UnitarySmoothPulseProblem( subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing ) end - J += QuadraticRegularizer(:a, traj, R_a) - J += QuadraticRegularizer(:da, traj, R_da) - J += QuadraticRegularizer(:dda, traj, R_dda) - - # Constraints - if leakage_suppression - if operator isa EmbeddedOperator - leakage_indices = get_iso_vec_leakage_indices(operator) - J += L1Regularizer!( - constraints, :Ũ⃗, traj, - R_value=R_leakage, - indices=leakage_indices, - eval_hessian=piccolo_options.eval_hessian - ) - else - @warn "leakage_suppression is not supported for non-embedded operators, ignoring." - end - end - if piccolo_options.free_time - if piccolo_options.timesteps_all_equal - push!(constraints, TimeStepsAllEqualConstraint(:Δt, traj)) - end - end + J += QuadraticRegularizer(control_bound_names[1], traj, R_a) + J += QuadraticRegularizer(control_bound_names[2], traj, R_da) + J += QuadraticRegularizer(control_bound_names[3], traj, R_dda) - if control_norm_constraint - @assert !isnothing(control_norm_constraint_components) "control_norm_constraint_components must be provided" - @assert !isnothing(control_norm_R) "control_norm_R must be provided" - norm_con = ComplexModulusContraint( - :a, - control_norm_R, - traj; - name_comps=control_norm_constraint_components, - ) - push!(constraints, norm_con) - end + # Piccolo constraints and objective + J_piccolo, constraints_piccolo = + get_piccolo_objective_and_constraints(piccolo_options, traj) + + J += J_piccolo + + append!(constraints, constraints_piccolo) # Integrators if piccolo_options.integrator == :pade unitary_integrator = - UnitaryPadeIntegrator(system, :Ũ⃗, :a, traj; order=piccolo_options.pade_order) + UnitaryPadeIntegrator(system, state_name, control_name, traj; + order=piccolo_options.pade_order + ) elseif piccolo_options.integrator == :exponential unitary_integrator = - UnitaryExponentialIntegrator(system, :Ũ⃗, :a, traj) + UnitaryExponentialIntegrator(system, state_name, control_name, traj) else error("integrator must be one of (:pade, :exponential)") end integrators = [ unitary_integrator, - DerivativeIntegrator(:a, :da, traj), - DerivativeIntegrator(:da, :dda, traj), + DerivativeIntegrator(control_name, control_velocity_name, traj), + DerivativeIntegrator(control_velocity_name, control_acceleration_name, traj), ] return QuantumControlProblem( @@ -271,6 +263,34 @@ end @test final > initial end +@testitem "Hadamard gate with exponential integrator, bounded states, and control norm constraint" begin + sys = QuantumSystem(GATES[:Z], [GATES[:X], GATES[:Y]]) + U_goal = GATES[:H] + T = 51 + Δt = 0.2 + + piccolo_options = PiccoloOptions( + verbose=false, + integrator=:exponential, + # jacobian_structure=false, + bound_state=true, + complex_control_norm_constraint_name=:a + ) + + prob = UnitarySmoothPulseProblem( + sys, U_goal, T, Δt, + ipopt_options=IpoptOptions(print_level=1), + piccolo_options=piccolo_options + ) + + initial = unitary_fidelity(prob) + solve!(prob, max_iter=20) + final = unitary_fidelity(prob) + @test final > initial +end + + + @testitem "EmbeddedOperator Hadamard gate" begin a = annihilate(3) sys = QuantumSystem([(a + a')/2, (a - a')/(2im)]) From 6a90a9501cae9601a8dc6d480d3b9044adddaa2d Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 23 Aug 2024 13:42:53 -0500 Subject: [PATCH 02/35] in-place apply piccolo options --- src/problem_templates/_problem_templates.jl | 27 +++++++++---------- .../unitary_smooth_pulse_problem.jl | 11 +++----- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index e2ffb36..b70a3c8 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -34,20 +34,20 @@ include("quantum_state_smooth_pulse_problem.jl") include("quantum_state_minimum_time_problem.jl") -function get_piccolo_objective_and_constraints( +function apply_piccolo_options!( + J::Objective, + constraints::AbstractVector{<:AbstractConstraint}, piccolo_options::PiccoloOptions, - traj::NamedTrajectory + traj::NamedTrajectory, + operator::OperatorType ) - J = NullObjective() - constraints = AbstractConstraint[] - - state_names = [ - Symbol(name) - for name ∈ string.(traj.names) - if startswith(name, string(piccolo_options.state_name)) - ] - if piccolo_options.leakage_suppression + state_names = [ + Symbol(name) + for name ∈ string.(traj.names) + if startswith(name, string(state_name)) + ] + if operator isa EmbeddedOperator leakage_indices = get_iso_vec_leakage_indices(operator) for state_name in state_names @@ -59,7 +59,7 @@ function get_piccolo_objective_and_constraints( ) end else - @warn "leakage_suppression is not supported for non-embedded operators, ignoring." + @warn "leakage_suppression is only supported for embedded operators, ignoring." end end @@ -81,9 +81,8 @@ function get_piccolo_objective_and_constraints( push!(constraints, norm_con) end - return J, constraints + return end - end diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index 6b8ac76..5867aa5 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -162,14 +162,6 @@ function UnitarySmoothPulseProblem( J += QuadraticRegularizer(control_bound_names[2], traj, R_da) J += QuadraticRegularizer(control_bound_names[3], traj, R_dda) - # Piccolo constraints and objective - J_piccolo, constraints_piccolo = - get_piccolo_objective_and_constraints(piccolo_options, traj) - - J += J_piccolo - - append!(constraints, constraints_piccolo) - # Integrators if piccolo_options.integrator == :pade unitary_integrator = @@ -189,6 +181,9 @@ function UnitarySmoothPulseProblem( DerivativeIntegrator(control_velocity_name, control_acceleration_name, traj), ] + # Optional Piccolo constraints and objectives + apply_piccolo_options!(J, constraints, piccolo_options, traj, operator) + return QuantumControlProblem( system, traj, From cfb843382e35e6b4150f80e36718e7ffa65fa746 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 23 Aug 2024 13:46:10 -0500 Subject: [PATCH 03/35] optional operator kwarg --- src/problem_templates/_problem_templates.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index b70a3c8..456e7a8 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -38,8 +38,8 @@ function apply_piccolo_options!( J::Objective, constraints::AbstractVector{<:AbstractConstraint}, piccolo_options::PiccoloOptions, - traj::NamedTrajectory, - operator::OperatorType + traj::NamedTrajectory; + operator::Union{Nothing, OperatorType}=nothing ) if piccolo_options.leakage_suppression state_names = [ From 080a15c85ae323f9aea0836f67b3b7172c5407e3 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 26 Aug 2024 21:03:20 -0500 Subject: [PATCH 04/35] add method for FinalUnitaryFreePhaseFidelityConstraint --- src/constraints/fidelity_constraint.jl | 24 +++++++++++++++++-- .../unitary_minimum_time_problem.jl | 15 ++++++------ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/src/constraints/fidelity_constraint.jl b/src/constraints/fidelity_constraint.jl index 095b362..2a49514 100644 --- a/src/constraints/fidelity_constraint.jl +++ b/src/constraints/fidelity_constraint.jl @@ -161,7 +161,6 @@ function FinalUnitaryFidelityConstraint( subspace::Union{AbstractVector{<:Integer}, Nothing}=nothing, eval_hessian::Bool=true ) - @assert statesymb ∈ traj.names return FinalFidelityConstraint(; fidelity_function=iso_vec_unitary_fidelity, value=val, @@ -221,7 +220,7 @@ function FinalUnitaryFreePhaseFidelityConstraint(; state_slice::Union{AbstractVector{Int},Nothing}=nothing, phase_slice::Union{AbstractVector{Int},Nothing}=nothing, goal::Union{AbstractVector{Float64},Nothing}=nothing, - phase_operators::Union{AbstractVector{<:AbstractMatrix{<:Complex{Float64}}},Nothing}=nothing, + phase_operators::Union{AbstractVector{<:AbstractMatrix{<:Complex}},Nothing}=nothing, zdim::Union{Int,Nothing}=nothing, subspace::Union{AbstractVector{<:Integer}, Nothing}=nothing, eval_hessian::Bool=false @@ -284,4 +283,25 @@ function FinalUnitaryFreePhaseFidelityConstraint(; 1, params ) +end + +function FinalUnitaryFreePhaseFidelityConstraint( + state_symbol::Symbol, + global_symbol::Symbol, + phase_operators::AbstractVector{<:AbstractMatrix{<:Complex}}, + val::Float64, + traj::NamedTrajectory; + subspace::Union{AbstractVector{<:Integer}, Nothing}=nothing, + eval_hessian::Bool=false +) + return FinalUnitaryFreePhaseFidelityConstraint(; + value=val, + state_slice=slice(traj.T, traj.components[state_symbol], traj.dim), + phase_slice=trajectory.global_components[global_symbol], + goal=traj.goal[state_symbol], + phase_operators=phase_operators, + zdim=length(traj), + subspace=subspace, + eval_hessian=eval_hessian + ) end \ No newline at end of file diff --git a/src/problem_templates/unitary_minimum_time_problem.jl b/src/problem_templates/unitary_minimum_time_problem.jl index 7409c70..e24a915 100644 --- a/src/problem_templates/unitary_minimum_time_problem.jl +++ b/src/problem_templates/unitary_minimum_time_problem.jl @@ -79,14 +79,15 @@ function UnitaryMinimumTimeProblem( eval_hessian=piccolo_options.eval_hessian ) else - # TODO: remove hardcoded args + phase_operators= [ + GATES[:Z] for _ in eachindex(trajectory.global_components[global_symbol]) + ] fidelity_constraint = FinalUnitaryFreePhaseFidelityConstraint( - value=final_fidelity, - state_slice=slice(trajectory.T, trajectory.components[unitary_symbol], trajectory.dim), - phase_slice=trajectory.global_components[global_symbol], - goal=trajectory.goal[unitary_symbol], - phase_operators=[GATES[:Z] for _ in eachindex(trajectory.global_components[global_symbol])], - zdim=trajectory.dim * trajectory.T + trajectory.global_dim, + unitary_symbol, + global_symbol, + phase_operators, + final_fidelity, + trajectory; subspace=subspace, eval_hessian=piccolo_options.eval_hessian ) From 7f69132493da5cd82b335ee5c79812f96a091f94 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 15:32:54 -0400 Subject: [PATCH 05/35] cleaning and formatting --- Manifest.toml | 226 ++++++++++-------- src/problem_templates/_problem_templates.jl | 11 +- .../unitary_smooth_pulse_problem.jl | 6 +- 3 files changed, 135 insertions(+), 108 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 62ef3b3..c02b1a1 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -116,9 +116,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "f54c23a5d304fb87110de62bace7777d59088c34" +git-tree-sha1 = "3640d077b6dafd64ceb8fd5c1ec76f7ca53bcf76" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.15.0" +version = "7.16.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -175,9 +175,9 @@ uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" version = "1.5.0" [[deps.Bijections]] -git-tree-sha1 = "95f5c7e2d177b7ba1a240b0518038b975d72a8c0" +git-tree-sha1 = "d8b0439d2be438a5f2cd68ec158fe08a7b2595b7" uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" -version = "0.1.7" +version = "0.1.9" [[deps.Bzip2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -284,10 +284,10 @@ uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" version = "0.2.4" [[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" +version = "0.3.1" [[deps.CommonWorldInvalidations]] git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" @@ -330,14 +330,14 @@ uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" version = "1.10.2" [[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "a33b7ced222c6165f624a3f2b55945fac5a598d9" +git-tree-sha1 = "76219f1ed5771adbb096743bff43fb5fdd4c1157" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.7" -weakdeps = ["IntervalSets", "StaticArrays"] +version = "1.5.8" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" ConstructionBaseStaticArraysExt = "StaticArrays" [[deps.Contour]] @@ -367,9 +367,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "b5f1c6532d2ea71e99b74231b0a3d53fba846ced" +git-tree-sha1 = "46f12daa85e5acc0ea5d5f9f8c3f1fc679e0f7e5" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.1.3" +version = "1.2.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -389,9 +389,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "0e0a1264b0942f1f3abb2b30891f2a590cc652ac" +git-tree-sha1 = "e6c693a0e4394f8fda0e51a5bdf5aef26f8235e9" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.110" +version = "0.25.111" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -425,10 +425,10 @@ uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" [[deps.DynamicPolynomials]] -deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"] -git-tree-sha1 = "30a1848c4f4fc35d1d4bbbd125650f6a11b5bc6c" +deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Reexport", "Test"] +git-tree-sha1 = "bbf1ace0781d9744cb697fb856bd2c3f6568dadb" uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07" -version = "0.5.7" +version = "0.6.0" [[deps.EarCut_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -477,15 +477,15 @@ uuid = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3636" version = "0.8.5" [[deps.Extents]] -git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" +git-tree-sha1 = "81023caa0021a41712685887db1fc03db26f41f5" uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.3" +version = "0.1.4" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +git-tree-sha1 = "8cc47f299902e13f90405ddb5bf87e5d474c0d38" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "6.1.1+0" +version = "6.1.2+0" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -512,19 +512,24 @@ uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" version = "0.8.3" [[deps.FilePathsBase]] -deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] -git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +deps = ["Compat", "Dates"] +git-tree-sha1 = "7878ff7172a8e6beedd1dea14bd27c3c6340d361" uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.21" +version = "0.9.22" +weakdeps = ["Mmap", "Test"] + + [deps.FilePathsBase.extensions] + FilePathsBaseMmapExt = "Mmap" + FilePathsBaseTestExt = "Test" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra"] -git-tree-sha1 = "fd0002c0b5362d7eb952450ad5eb742443340d6e" +git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.12.0" +version = "1.13.0" weakdeps = ["PDMats", "SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -604,11 +609,16 @@ git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" uuid = "46192b85-c4d5-4398-a991-12ede77f4527" version = "0.1.6" +[[deps.GeoFormatTypes]] +git-tree-sha1 = "59107c179a586f0fe667024c5eb7033e81333271" +uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" +version = "0.4.2" + [[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" +deps = ["Extents", "GeoFormatTypes"] +git-tree-sha1 = "5921fc0704e40c024571eca551800c699f86ceb4" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.5" +version = "1.3.6" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] @@ -652,10 +662,10 @@ uuid = "42e2da0e-8278-4e71-bc24-59509adca0fe" version = "1.0.2" [[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "401e4f3f30f43af2c8478fc008da50096ea5240f" uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" +version = "8.3.1+0" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -726,11 +736,16 @@ git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.5" +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "10bd689145d2c3b2a9844005d01087cc1194e79e" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.2.0+0" +version = "2024.2.1+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -750,15 +765,16 @@ version = "0.15.1" [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "433b0bb201cd76cb087b017e49244f10394ebe9c" +git-tree-sha1 = "01fa84a20be8c7c867edf3b9ef33ac15f4089c1a" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.14" -weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] +version = "0.22.15" +weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "RecipesBase"] [deps.IntervalArithmetic.extensions] IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" IntervalArithmeticRecipesBaseExt = "RecipesBase" + IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -815,16 +831,16 @@ uuid = "82899510-4779-5014-852e-03e436cf321d" version = "1.0.0" [[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "67d4690d32c22e28818a434b293a374cc78473d3" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] +git-tree-sha1 = "a0746c21bdc986d0dc293efa6b1faee112c37c28" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.51" +version = "0.4.53" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +git-tree-sha1 = "f389674c99bfcde17dc57454011aa44d5a260a40" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" +version = "1.6.0" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -873,12 +889,6 @@ git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" version = "1.3.1" -[[deps.LabelledArrays]] -deps = ["ArrayInterface", "ChainRulesCore", "ForwardDiff", "LinearAlgebra", "MacroTools", "PreallocationTools", "RecursiveArrayTools", "StaticArrays"] -git-tree-sha1 = "e459fda6b68ea8684b3fcd513d2fd1e5130c4402" -uuid = "2ee39098-c373-598a-b85f-a56591580800" -version = "1.16.0" - [[deps.LambertW]] git-tree-sha1 = "c5ffc834de5d61d00d2b0e18c96267cffc21f648" uuid = "984bce1d-4616-540c-a9ee-88d1112d94c9" @@ -1047,9 +1057,9 @@ uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] -git-tree-sha1 = "c0fe113e9c72aa0c9a185fd3c5ca1daa51de1486" +git-tree-sha1 = "5b246fca5420ae176d65ed43a2d0ee5897775216" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.31.1" +version = "1.31.2" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] @@ -1107,7 +1117,7 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "94fa6864fcf891e7214a1dd73c773d325556de28" +git-tree-sha1 = "900c2091843bbee472da11a8cc862d01e2482aa5" repo-rev = "main" repo-url = "https://github.com/kestrelquantum/NamedTrajectories.jl.git" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" @@ -1184,10 +1194,10 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" [[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6703a85cb3781bd5909d48730a67205f3f31a575" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" +version = "1.3.3+0" [[deps.OrderedCollections]] git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" @@ -1225,9 +1235,9 @@ version = "0.5.12" [[deps.Pango_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" +git-tree-sha1 = "e127b609fb9ecba6f201ba7ab753d5a605d53801" uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.52.2+0" +version = "1.54.1+0" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] @@ -1263,18 +1273,6 @@ git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" uuid = "647866c9-e3ac-4575-94e7-e3d426903924" version = "0.1.2" -[[deps.PreallocationTools]] -deps = ["Adapt", "ArrayInterface", "ForwardDiff"] -git-tree-sha1 = "6c62ce45f268f3f958821a1e5192cf91c75ae89c" -uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.24" - - [deps.PreallocationTools.extensions] - PreallocationToolsReverseDiffExt = "ReverseDiff" - - [deps.PreallocationTools.weakdeps] - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" @@ -1287,6 +1285,12 @@ git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.3" +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -1302,9 +1306,9 @@ uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.10.2" [[deps.PtrArrays]] -git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" +git-tree-sha1 = "77a42d78b6a92df47ab37e177b2deac405e1c88f" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.2.0" +version = "1.2.1" [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] @@ -1314,9 +1318,15 @@ version = "1.0.0" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "e237232771fdafbae3db5c31275303e056afaa9f" +git-tree-sha1 = "1d587203cf851a51bf1ea31ad7ff89eff8d625ea" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.10.1" +version = "2.11.0" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -1431,9 +1441,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "5123ca064567e81c31fb3acdf15d2c9459bb7cc3" +git-tree-sha1 = "8001043f80051c86f264fd6e936d97e6b9eff401" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.50.0" +version = "2.52.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1455,17 +1465,21 @@ version = "2.50.0" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLOperators]] -deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "23b02c588ac9a17ecb276cc62ab37f3e4fe37b32" +deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools"] +git-tree-sha1 = "e39c5f217f9aca640c8e27ab21acf557a3967db5" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.3.9" -weakdeps = ["SparseArrays"] +version = "0.3.10" +weakdeps = ["SparseArrays", "StaticArraysCore"] + + [deps.SciMLOperators.extensions] + SciMLOperatorsSparseArraysExt = "SparseArrays" + SciMLOperatorsStaticArraysCoreExt = "StaticArraysCore" [[deps.SciMLStructures]] deps = ["ArrayInterface"] -git-tree-sha1 = "20ad3e7c137156c50c93c888d0f2bc5b7883c729" +git-tree-sha1 = "25514a6f200219cd1073e4ff23a6324e4a7efe64" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.4.2" +version = "1.5.0" [[deps.Scratch]] deps = ["Dates"] @@ -1631,21 +1645,28 @@ uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" version = "0.2.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] -git-tree-sha1 = "d00729521f49d96afd3fcddb437141eb71222886" +deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "40b48f4eb06a4bd450c50b4206f7f490556214e1" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.2.0" +version = "3.5.0" + + [deps.SymbolicUtils.extensions] + SymbolicUtilsLabelledArraysExt = "LabelledArrays" + + [deps.SymbolicUtils.weakdeps] + LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" [[deps.Symbolics]] -deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "4224422f6a5452b1accaec15a65a5ce3c2ca4600" +deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] +git-tree-sha1 = "19a3555ce5d82798b5ab67bdf8b4444d54a159de" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.2.0" +version = "6.5.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" SymbolicsLuxCoreExt = "LuxCore" + SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1653,6 +1674,7 @@ version = "6.2.0" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" @@ -1769,9 +1791,9 @@ version = "1.0.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "d9717ce3518dc68a99e6b96300813760d887a01d" +git-tree-sha1 = "1165b0443d0eca63ac1e32b8c0eb69ed2f4f8127" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.1+0" +version = "2.13.3+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] @@ -1857,10 +1879,10 @@ uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" version = "3.9.0+0" [[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "e17c115d55c5fbb7e52ebedb427a0dca79d4484e" uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" +version = "0.15.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] @@ -1868,10 +1890,10 @@ uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" [[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a22cf860a7d27e4f3498a0fe0811a7957badb38" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" +version = "2.0.3+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] @@ -1914,13 +1936,13 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" [[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "35976a1216d6c066ea32cba2150c4fa682b276fc" uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" +version = "10164.0.0+0" [[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dcc541bb19ed5b0ede95581fb2e41ecf179527d2" uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" +version = "3.6.0+0" diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index 456e7a8..9588f5b 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -43,16 +43,17 @@ function apply_piccolo_options!( ) if piccolo_options.leakage_suppression state_names = [ - Symbol(name) - for name ∈ string.(traj.names) - if startswith(name, string(state_name)) + name for name ∈ traj.names + if startswith(string(name), string(piccolo_options.state_name)) ] - + if operator isa EmbeddedOperator leakage_indices = get_iso_vec_leakage_indices(operator) for state_name in state_names J += L1Regularizer!( - constraints, state_name, traj, + constraints, + state_name, + traj; R_value=piccolo_options.R_leakage, indices=leakage_indices, eval_hessian=piccolo_options.eval_hessian diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index 5867aa5..f059ae9 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -150,7 +150,11 @@ function UnitarySmoothPulseProblem( J = UnitaryFreePhaseInfidelityObjective( name=state_name, phase_name=:ϕ, - goal=operator_to_iso_vec(operator isa EmbeddedOperator ? operator.operator : operator), + goal=operator_to_iso_vec( + operator isa EmbeddedOperator ? + operator.operator : + operator + ), phase_operators=[GATES[:Z] for _ in eachindex(traj.global_components[:ϕ])], Q=Q, eval_hessian=piccolo_options.eval_hessian, From cd4061448f438d1e2d3c6111ede604a2461045df Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 16:12:00 -0400 Subject: [PATCH 06/35] patch bump for compat bumps --- Manifest.toml | 57 +++++++++++++++++++++++++++++---------------------- Project.toml | 10 ++++----- 2 files changed, 37 insertions(+), 30 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index c02b1a1..68970c0 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.3" manifest_format = "2.0" -project_hash = "ace2e1df9d9dbcf666fc13e87dfbf3d8881dd7d1" +project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" [[deps.ADTypes]] git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" @@ -206,10 +206,10 @@ uuid = "159f3aea-2a34-519c-b102-8c37f9878175" version = "1.1.0" [[deps.CairoMakie]] -deps = ["CRC32c", "Cairo", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "d69c7593fe9d7d617973adcbe4762028c6899b2c" +deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] +git-tree-sha1 = "361dec06290d76b6d70d0c7dc888038eec9df63a" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.11.11" +version = "0.12.9" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -652,9 +652,9 @@ version = "1.3.14+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "6f93a83ca11346771a93bbde2bdad2f65b61498f" +git-tree-sha1 = "fc713f007cff99ff9e50accba6373624ddd33588" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.10.2" +version = "0.11.0" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -756,13 +756,11 @@ deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArr git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" version = "0.15.1" +weakdeps = ["Unitful"] [deps.Interpolations.extensions] InterpolationsUnitfulExt = "Unitful" - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] git-tree-sha1 = "01fa84a20be8c7c867edf3b9ef33ac15f4089c1a" @@ -1035,16 +1033,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "4d49c9ee830eec99d3e8de2425ff433ece7cc1bc" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "204f06860af9008fa08b3a4842f48116e1209a2c" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.20.10" +version = "0.21.9" [[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "248b7a4be0f92b497f7a331aed02c1e9a878f46b" +deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] +git-tree-sha1 = "b0e2e3473af351011e598f9219afb521121edd2b" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.7.3" +version = "0.8.6" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1063,9 +1061,9 @@ version = "1.31.2" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +git-tree-sha1 = "e1641f32ae592e415e3dbae7f4a188b5316d4b62" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" +version = "0.6.1" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] @@ -1117,11 +1115,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "900c2091843bbee472da11a8cc862d01e2482aa5" -repo-rev = "main" -repo-url = "https://github.com/kestrelquantum/NamedTrajectories.jl.git" +git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.0" +version = "0.2.1" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1717,14 +1713,14 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TestItemRunner]] deps = ["Pkg", "TOML", "Test", "TestItems", "UUIDs"] -git-tree-sha1 = "cb2b53fd36a8fe20c0b9f55da6244eb4818779f5" +git-tree-sha1 = "29647c5398be04a1d697265ba385bdf3f623c993" uuid = "f8b46487-2199-4994-9208-9a1283c18c0a" -version = "0.2.3" +version = "1.0.5" [[deps.TestItems]] -git-tree-sha1 = "8621ba2637b49748e2dc43ba3d84340be2938022" +git-tree-sha1 = "42fd9023fef18b9b78c8343a4e2f3813ffbcefcb" uuid = "1c621080-faea-4a02-84b6-bbd5e436b8fe" -version = "0.1.1" +version = "1.0.0" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] @@ -1772,6 +1768,17 @@ git-tree-sha1 = "2264362f72926965e708ee26f58824b929c72637" uuid = "967fb449-e509-55aa-8007-234b4096b967" version = "1.1.0" +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "d95fe458f26209c66a187b1114df96fd70839efd" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.21.0" +weakdeps = ["ConstructionBase", "InverseFunctions"] + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + [[deps.Unityper]] deps = ["ConstructionBase"] git-tree-sha1 = "25008b734a03736c41e2a7dc314ecb95bd6bbdb0" diff --git a/Project.toml b/Project.toml index 1ea93c3..f80555b 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "QuantumCollocation" uuid = "0dc23a59-5ffb-49af-b6bd-932a8ae77adf" authors = ["Aaron Trowbridge and contributors"] -version = "0.2.0" +version = "0.2.2" [deps] BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" @@ -28,7 +28,7 @@ TrajectoryIndexingUtils = "6dad8b7f-dd9a-4c28-9b70-85b9a079bfc8" [compat] BenchmarkTools = "1.5" -CairoMakie = "0.10, 0.11, 0.12" +CairoMakie = "0.12" Distributions = "0.25" Einsum = "0.4" ExponentialAction = "0.2" @@ -37,12 +37,12 @@ IJulia = "1.25" Ipopt = "1.6" JLD2 = "0.4" MathOptInterface = "1.31" -NamedTrajectories = "0.2.0" +NamedTrajectories = "0.2" ProgressMeter = "1.10" Reexport = "1.2" Symbolics = "6.2" -TestItemRunner = "0.2" -TestItems = "0.1" +TestItemRunner = "1.0" +TestItems = "1.0" TrajectoryIndexingUtils = "0.1" julia = "1.10" From 916491425860cb37cf51caecfe28ea8b3fc07d63 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 23 Aug 2024 13:10:12 -0500 Subject: [PATCH 07/35] feat: data interpolations --- Manifest.toml | 4 +- Project.toml | 1 + src/QuantumCollocation.jl | 3 + src/trajectory_interpolations.jl | 119 +++++++++++++++++++++++++++++++ test/test_utils.jl | 5 +- 5 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/trajectory_interpolations.jl diff --git a/Manifest.toml b/Manifest.toml index 68970c0..a2abdfc 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.3" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" +project_hash = "1d025dab4c6dd8f7ccf572cc68ecdd4a371d25d2" [[deps.ADTypes]] git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" diff --git a/Project.toml b/Project.toml index f80555b..ba5467a 100644 --- a/Project.toml +++ b/Project.toml @@ -11,6 +11,7 @@ Einsum = "b7d42ee7-0b51-5a75-98ca-779d3107e4c0" ExponentialAction = "e24c0720-ea99-47e8-929e-571b494574d3" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" IJulia = "7073ff75-c697-5162-941a-fcdaad2a7d2a" +Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" Ipopt = "b6b21f68-93f8-5de0-b562-5493be1d77c9" JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" diff --git a/src/QuantumCollocation.jl b/src/QuantumCollocation.jl index 7bbe3b3..efaf405 100644 --- a/src/QuantumCollocation.jl +++ b/src/QuantumCollocation.jl @@ -57,6 +57,9 @@ include("rollouts.jl") include("trajectory_initialization.jl") @reexport using .TrajectoryInitialization +include("trajectory_interpolations.jl") +@reexport using .TrajectoryInterpolation + include("problem_templates/_problem_templates.jl") @reexport using .ProblemTemplates diff --git a/src/trajectory_interpolations.jl b/src/trajectory_interpolations.jl new file mode 100644 index 0000000..365a9b4 --- /dev/null +++ b/src/trajectory_interpolations.jl @@ -0,0 +1,119 @@ +module TrajectoryInterpolation + +export DataInterpolation + +using NamedTrajectories + +using Interpolations: Extrapolation, constant_interpolation, linear_interpolation +using TestItemRunner + + +struct DataInterpolation + times::Vector{Float64} + values::Matrix{Float64} + interpolants::Vector{Extrapolation} + timestep_components::Vector{Int} + values_components::Vector{Int} + + function DataInterpolation( + times::AbstractVector{Float64}, values::AbstractMatrix{Float64}; + timestep_components::AbstractVector{Int}=Int[], kind::Symbol=:linear + ) + comps = setdiff(1:size(values, 1), timestep_components) + if kind == :linear + interpolants = [linear_interpolation(times, values[c, :]) for c in comps] + elseif kind == :constant + interpolants = [constant_interpolation(times, values[c, :]) for c in comps] + else + error("Unknown interpolation kind: $kind") + end + return new(times, values, interpolants, timestep_components, comps) + end + + function DataInterpolation( + T::Int, Δt::Real, values::AbstractMatrix{Float64}; kwargs... + ) + times = range(0, Δt * (T - 1), step=Δt) + return DataInterpolation(times, values; kwargs...) + end + + function DataInterpolation( + traj::NamedTrajectory; timestep_symbol::Symbol=:Δt, kwargs... + ) + if timestep_symbol ∈ keys(traj.components) + timestep_components = traj.components[timestep_symbol] + else + timestep_components = Int[] + end + return DataInterpolation( + get_times(traj), traj.data; timestep_components=timestep_components, kwargs... + ) + end +end + +function (traj_int::DataInterpolation)(times::AbstractVector) + values = zeros(eltype(traj_int.values), size(traj_int.values, 1), length(times)) + for (c, interp) in zip(traj_int.values_components, traj_int.interpolants) + values[c, :] = interp(times) + end + if !isempty(traj_int.timestep_components) + timesteps = times[2:end] .- times[1:end-1] + # NOTE: Arbitrary choice of the last timestep + values[traj_int.timestep_components, :] = vcat(timesteps, timesteps[end]) + end + return values +end + +function (traj_int::DataInterpolation)(T::Int) + times = range(traj_int.times[1], traj_int.times[end], length=T) + return traj_int(times) +end + +# ========================================================================= + +@testitem "Trajectory interpolation test" begin + include("../test/test_utils.jl") + + # fixed time + traj = named_trajectory_type_1() + + interp = DataInterpolation(traj) + new_data = interp(get_times(traj)) + @test new_data ≈ traj.data + + new_data = interp(2 * traj.T) + @test size(new_data) == (size(traj.data, 1), 2 * traj.T) + + # free time + free_traj = named_trajectory_type_1(free_time=true) + + interp = DataInterpolation(free_traj) + new_free_data = interp(get_times(traj)) + + # Replace the final timestep with the original value (can't be known a priori) + new_free_data[free_traj.components.Δt, end] = free_traj.data[free_traj.components.Δt, end] + @test new_free_data ≈ free_traj.data + + new_free_data = interp(2 * traj.T) + @test size(new_free_data) == (size(free_traj.data, 1), 2 * traj.T) +end + +@testitem "Component interpolation test" begin + include("../test/test_utils.jl") + + traj = named_trajectory_type_1() + + # interpolate with times + interp_val1 = DataInterpolation(get_times(traj), traj.a) + @test size(interp_val1(2 * traj.T)) == (size(traj.a, 1), 2 * traj.T) + + # interpolate with steps + interp_val2 = DataInterpolation(traj.T, traj.timestep, traj.a) + @test size(interp_val2(3 * traj.T)) == (size(traj.a, 1), 3 * traj.T) + + # check if times match + @test interp_val1.times ≈ interp_val2.times +end + + +end \ No newline at end of file diff --git a/test/test_utils.jl b/test/test_utils.jl index c70c0af..ce5d309 100644 --- a/test/test_utils.jl +++ b/test/test_utils.jl @@ -1,6 +1,5 @@ -""" - utility functions for debugging tests -""" +using NamedTrajectories + """ dense(vals, structure, shape) From 6def0e17f11b4f9035b6b7e93df1574a42d1f5b4 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 26 Aug 2024 15:13:27 -0500 Subject: [PATCH 08/35] update project patch version --- Manifest.toml | 2 +- Project.toml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index a2abdfc..ecadcff 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "1d025dab4c6dd8f7ccf572cc68ecdd4a371d25d2" +project_hash = "a8d39c98fbf089d5b72e82a89504c42d025cd3fe" [[deps.ADTypes]] git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" diff --git a/Project.toml b/Project.toml index ba5467a..623781c 100644 --- a/Project.toml +++ b/Project.toml @@ -35,6 +35,7 @@ Einsum = "0.4" ExponentialAction = "0.2" ForwardDiff = "0.10" IJulia = "1.25" +Interpolations = "0.15" Ipopt = "1.6" JLD2 = "0.4" MathOptInterface = "1.31" From 2817a5501573b57921ca8a02db05d389af66e6f9 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 16:12:00 -0400 Subject: [PATCH 09/35] patch bump for compat bumps --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index ecadcff..b6c1ac3 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "a8d39c98fbf089d5b72e82a89504c42d025cd3fe" +project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" [[deps.ADTypes]] git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" From 24a9e526f06c15b71629f44b8aaffeb5a7486173 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 18:52:38 -0400 Subject: [PATCH 10/35] moved phase infidelity params to options --- src/options.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/options.jl b/src/options.jl index f42d7c9..18a13a9 100644 --- a/src/options.jl +++ b/src/options.jl @@ -58,6 +58,7 @@ end Solver settings for Quantum Collocation. """ @kwdef mutable struct PiccoloOptions <: AbstractOptions + # TODO: return names to problem templates state_type::Symbol = :unitary state_name::Symbol = :Ũ⃗ control_name::Symbol = :a @@ -79,8 +80,12 @@ end bound_state::Bool = false leakage_suppression::Bool = false R_leakage::Float64 = 1.0 + free_phase_infidelity::Bool = false + phase_operators::Union{Nothing, AbstractVector{<:AbstractMatrix{<:Complex}}} = nothing + phase_name::Symbol = :ϕ end +⊗ function set!(optimizer::Ipopt.Optimizer, options::AbstractOptions) for name in fieldnames(typeof(options)) From d502af80ab1e652966611faf8240450668791824 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 9 Sep 2024 14:33:26 -0400 Subject: [PATCH 11/35] docs updates --- README.md | 21 ++ docs/Manifest.toml | 285 ++++++++++--------- docs/literate/man/embedded_operators.jl | 73 +++++ docs/make.jl | 3 +- docs/src/generated/man/embedded_operators.md | 87 ++++++ src/embedded_operators.jl | 51 +++- 6 files changed, 385 insertions(+), 135 deletions(-) create mode 100644 docs/literate/man/embedded_operators.jl create mode 100644 docs/src/generated/man/embedded_operators.md diff --git a/README.md b/README.md index 27fd13e..728b30a 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,27 @@ using Revise using QuantumCollocation ``` +### Documentation + +Documentation is built using [Documenter.jl](https://github.com/JuliaDocs/Documenter.jl) and uses [Literate.jl](https://github.com/fredrikekre/Literate.jl) to generate markdown files from scripts stored in [docs/literate](docs/literate). To build the documentation locally, start julia with the docs environment: + +```bash +julia --project=docs +``` + +Then (for ease of development) load the following packages: + +```julia +using Revise, LiveServer, QuantumCollocation +``` + +To live-serve the docs, run +```julia +servedocs(literate_dir="docs/literate", skip_dir="docs/src/generated") +``` + +Changes made to files in the docs directory should be automatically reflected in the live server. To reflect changes in the source code (e.g. doc strings), since we are using Revise, simply kill the live server running in the REPL (with, e.g., Ctrl-C) and restart it with the above command. + ### Tips for Visual Studio Code __Julia extension__ You can run Julia notebooks and much more with [the Julia extension](https://code.visualstudio.com/docs/languages/julia). Upon opening your project folder in VS code and attempting to run an `.ipynb`, you will see that VS Code finds the interpreters managed by juliaup and defaults to using the environment based on the _Project.toml_ in the project directory. diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 9115317..08ab4c5 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -121,9 +121,9 @@ version = "1.1.1" [[deps.ArrayInterface]] deps = ["Adapt", "LinearAlgebra"] -git-tree-sha1 = "f54c23a5d304fb87110de62bace7777d59088c34" +git-tree-sha1 = "3640d077b6dafd64ceb8fd5c1ec76f7ca53bcf76" uuid = "4fba245c-0d91-5ea0-9b3e-6abc04ee57a9" -version = "7.15.0" +version = "7.16.0" [deps.ArrayInterface.extensions] ArrayInterfaceBandedMatricesExt = "BandedMatrices" @@ -180,9 +180,9 @@ uuid = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" version = "1.5.0" [[deps.Bijections]] -git-tree-sha1 = "95f5c7e2d177b7ba1a240b0518038b975d72a8c0" +git-tree-sha1 = "d8b0439d2be438a5f2cd68ec158fe08a7b2595b7" uuid = "e2ed5e7c-b2de-5872-ae92-c73ca462fb04" -version = "0.1.7" +version = "0.1.9" [[deps.BitFlags]] git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d" @@ -216,10 +216,10 @@ uuid = "159f3aea-2a34-519c-b102-8c37f9878175" version = "1.1.0" [[deps.CairoMakie]] -deps = ["CRC32c", "Cairo", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "d69c7593fe9d7d617973adcbe4762028c6899b2c" +deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] +git-tree-sha1 = "361dec06290d76b6d70d0c7dc888038eec9df63a" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.11.11" +version = "0.12.9" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -300,10 +300,10 @@ uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2" version = "0.2.4" [[deps.CommonSubexpressions]] -deps = ["MacroTools", "Test"] -git-tree-sha1 = "7b8a93dba8af7e3b42fecabf646260105ac373f7" +deps = ["MacroTools"] +git-tree-sha1 = "cda2cfaebb4be89c9084adaca7dd7333369715c5" uuid = "bbf7d656-a473-5ed7-a52c-81e309532950" -version = "0.3.0" +version = "0.3.1" [[deps.CommonWorldInvalidations]] git-tree-sha1 = "ae52d1c52048455e85a387fbee9be553ec2b68d0" @@ -352,14 +352,14 @@ uuid = "8f4d0f93-b110-5947-807f-2305c1781a2d" version = "1.10.2" [[deps.ConstructionBase]] -deps = ["LinearAlgebra"] -git-tree-sha1 = "a33b7ced222c6165f624a3f2b55945fac5a598d9" +git-tree-sha1 = "76219f1ed5771adbb096743bff43fb5fdd4c1157" uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9" -version = "1.5.7" -weakdeps = ["IntervalSets", "StaticArrays"] +version = "1.5.8" +weakdeps = ["IntervalSets", "LinearAlgebra", "StaticArrays"] [deps.ConstructionBase.extensions] ConstructionBaseIntervalSetsExt = "IntervalSets" + ConstructionBaseLinearAlgebraExt = "LinearAlgebra" ConstructionBaseStaticArraysExt = "StaticArrays" [[deps.Contour]] @@ -389,9 +389,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "b5f1c6532d2ea71e99b74231b0a3d53fba846ced" +git-tree-sha1 = "46f12daa85e5acc0ea5d5f9f8c3f1fc679e0f7e5" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.1.3" +version = "1.2.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -411,9 +411,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "0e0a1264b0942f1f3abb2b30891f2a590cc652ac" +git-tree-sha1 = "e6c693a0e4394f8fda0e51a5bdf5aef26f8235e9" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.110" +version = "0.25.111" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -433,9 +433,9 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "76deb8c15f37a3853f13ea2226b8f2577652de05" +git-tree-sha1 = "9d29b99b6b2b6bc2382a4c8dbec6eb694f389853" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.5.0" +version = "1.6.0" [[deps.DomainSets]] deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays"] @@ -453,10 +453,10 @@ uuid = "f43a241f-c20a-4ad4-852c-f6b1247861c6" version = "1.6.0" [[deps.DynamicPolynomials]] -deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Pkg", "Reexport", "Test"] -git-tree-sha1 = "30a1848c4f4fc35d1d4bbbd125650f6a11b5bc6c" +deps = ["Future", "LinearAlgebra", "MultivariatePolynomials", "MutableArithmetics", "Reexport", "Test"] +git-tree-sha1 = "bbf1ace0781d9744cb697fb856bd2c3f6568dadb" uuid = "7c1d4256-1411-5781-91ec-d7bc3513ac07" -version = "0.5.7" +version = "0.6.0" [[deps.EarCut_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -511,15 +511,15 @@ uuid = "6b7a57c9-7cc1-4fdf-b7f5-e857abae3636" version = "0.8.5" [[deps.Extents]] -git-tree-sha1 = "94997910aca72897524d2237c41eb852153b0f65" +git-tree-sha1 = "81023caa0021a41712685887db1fc03db26f41f5" uuid = "411431e0-e8b7-467b-b5e0-f676ba4f2910" -version = "0.1.3" +version = "0.1.4" [[deps.FFMPEG_jll]] deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "JLLWrappers", "LAME_jll", "Libdl", "Ogg_jll", "OpenSSL_jll", "Opus_jll", "PCRE2_jll", "Zlib_jll", "libaom_jll", "libass_jll", "libfdk_aac_jll", "libvorbis_jll", "x264_jll", "x265_jll"] -git-tree-sha1 = "ab3f7e1819dba9434a3a5126510c8fda3a4e7000" +git-tree-sha1 = "8cc47f299902e13f90405ddb5bf87e5d474c0d38" uuid = "b22a6f82-2f65-5046-a5b2-351ab43fb4e5" -version = "6.1.1+0" +version = "6.1.2+0" [[deps.FFTW]] deps = ["AbstractFFTs", "FFTW_jll", "LinearAlgebra", "MKL_jll", "Preferences", "Reexport"] @@ -546,19 +546,24 @@ uuid = "8fc22ac5-c921-52a6-82fd-178b2807b824" version = "0.8.3" [[deps.FilePathsBase]] -deps = ["Compat", "Dates", "Mmap", "Printf", "Test", "UUIDs"] -git-tree-sha1 = "9f00e42f8d99fdde64d40c8ea5d14269a2e2c1aa" +deps = ["Compat", "Dates"] +git-tree-sha1 = "7878ff7172a8e6beedd1dea14bd27c3c6340d361" uuid = "48062228-2e41-5def-b9a4-89aafe57970f" -version = "0.9.21" +version = "0.9.22" +weakdeps = ["Mmap", "Test"] + + [deps.FilePathsBase.extensions] + FilePathsBaseMmapExt = "Mmap" + FilePathsBaseTestExt = "Test" [[deps.FileWatching]] uuid = "7b1f6079-737a-58dc-b8bc-7a2ca5c1b5ee" [[deps.FillArrays]] deps = ["LinearAlgebra"] -git-tree-sha1 = "fd0002c0b5362d7eb952450ad5eb742443340d6e" +git-tree-sha1 = "6a70198746448456524cb442b8af316927ff3e1a" uuid = "1a297f60-69ca-5386-bcde-b61e274b549b" -version = "1.12.0" +version = "1.13.0" weakdeps = ["PDMats", "SparseArrays", "Statistics"] [deps.FillArrays.extensions] @@ -638,11 +643,16 @@ git-tree-sha1 = "ec632f177c0d990e64d955ccc1b8c04c485a0950" uuid = "46192b85-c4d5-4398-a991-12ede77f4527" version = "0.1.6" +[[deps.GeoFormatTypes]] +git-tree-sha1 = "59107c179a586f0fe667024c5eb7033e81333271" +uuid = "68eda718-8dee-11e9-39e7-89f7f65f511f" +version = "0.4.2" + [[deps.GeoInterface]] -deps = ["Extents"] -git-tree-sha1 = "9fff8990361d5127b770e3454488360443019bb3" +deps = ["Extents", "GeoFormatTypes"] +git-tree-sha1 = "5921fc0704e40c024571eca551800c699f86ceb4" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.5" +version = "1.3.6" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] @@ -688,9 +698,9 @@ version = "1.3.14+0" [[deps.GridLayoutBase]] deps = ["GeometryBasics", "InteractiveUtils", "Observables"] -git-tree-sha1 = "6f93a83ca11346771a93bbde2bdad2f65b61498f" +git-tree-sha1 = "fc713f007cff99ff9e50accba6373624ddd33588" uuid = "3955a311-db13-416c-9275-1d80ed98e5e9" -version = "0.10.2" +version = "0.11.0" [[deps.Grisu]] git-tree-sha1 = "53bb909d1151e57e2484c3d1b53e19552b887fb2" @@ -704,10 +714,10 @@ uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3" version = "1.10.8" [[deps.HarfBuzz_jll]] -deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Pkg"] -git-tree-sha1 = "129acf094d168394e80ee1dc4bc06ec835e510a3" +deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "Graphite2_jll", "JLLWrappers", "Libdl", "Libffi_jll"] +git-tree-sha1 = "401e4f3f30f43af2c8478fc008da50096ea5240f" uuid = "2e76f6c2-a576-52d4-95c1-20adfe4de566" -version = "2.8.1+1" +version = "8.3.1+0" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -784,11 +794,16 @@ git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d" uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9" version = "0.1.5" +[[deps.IntegerMathUtils]] +git-tree-sha1 = "b8ffb903da9f7b8cf695a8bead8e01814aa24b30" +uuid = "18e54dd8-cb9d-406c-a71d-865a43cbb235" +version = "0.1.2" + [[deps.IntelOpenMP_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "14eb2b542e748570b56446f4c50fbfb2306ebc45" +deps = ["Artifacts", "JLLWrappers", "LazyArtifacts", "Libdl"] +git-tree-sha1 = "10bd689145d2c3b2a9844005d01087cc1194e79e" uuid = "1d5cc7b8-4909-519e-a0f8-d0f5ad9712d0" -version = "2024.2.0+0" +version = "2024.2.1+0" [[deps.InteractiveUtils]] deps = ["Markdown"] @@ -799,24 +814,23 @@ deps = ["Adapt", "AxisAlgorithms", "ChainRulesCore", "LinearAlgebra", "OffsetArr git-tree-sha1 = "88a101217d7cb38a7b481ccd50d21876e1d1b0e0" uuid = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59" version = "0.15.1" +weakdeps = ["Unitful"] [deps.Interpolations.extensions] InterpolationsUnitfulExt = "Unitful" - [deps.Interpolations.weakdeps] - Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" - [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "433b0bb201cd76cb087b017e49244f10394ebe9c" +git-tree-sha1 = "01fa84a20be8c7c867edf3b9ef33ac15f4089c1a" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.14" -weakdeps = ["DiffRules", "ForwardDiff", "RecipesBase"] +version = "0.22.15" +weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "RecipesBase"] [deps.IntervalArithmetic.extensions] IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" IntervalArithmeticRecipesBaseExt = "RecipesBase" + IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -873,16 +887,16 @@ uuid = "82899510-4779-5014-852e-03e436cf321d" version = "1.0.0" [[deps.JLD2]] -deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Reexport", "Requires", "TranscodingStreams", "UUIDs", "Unicode"] -git-tree-sha1 = "67d4690d32c22e28818a434b293a374cc78473d3" +deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] +git-tree-sha1 = "a0746c21bdc986d0dc293efa6b1faee112c37c28" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.51" +version = "0.4.53" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] -git-tree-sha1 = "7e5d6779a1e09a36db2a7b6cff50942a0a7d0fca" +git-tree-sha1 = "f389674c99bfcde17dc57454011aa44d5a260a40" uuid = "692b3bcd-3c85-4b1f-b108-f13ce0eb3210" -version = "1.5.0" +version = "1.6.0" [[deps.JSON]] deps = ["Dates", "Mmap", "Parsers", "Unicode"] @@ -904,9 +918,9 @@ version = "3.0.3+0" [[deps.JuliaInterpreter]] deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "7ae67d8567853d367e3463719356b8989e236069" +git-tree-sha1 = "4b415b6cccb9ab61fec78a621572c82ac7fa5776" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.34" +version = "0.9.35" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] @@ -937,12 +951,6 @@ git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f" version = "1.3.1" -[[deps.LabelledArrays]] -deps = ["ArrayInterface", "ChainRulesCore", "ForwardDiff", "LinearAlgebra", "MacroTools", "PreallocationTools", "RecursiveArrayTools", "StaticArrays"] -git-tree-sha1 = "e459fda6b68ea8684b3fcd513d2fd1e5130c4402" -uuid = "2ee39098-c373-598a-b85f-a56591580800" -version = "1.16.0" - [[deps.LambertW]] git-tree-sha1 = "c5ffc834de5d61d00d2b0e18c96267cffc21f648" uuid = "984bce1d-4616-540c-a9ee-88d1112d94c9" @@ -1123,16 +1131,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun"] -git-tree-sha1 = "4d49c9ee830eec99d3e8de2425ff433ece7cc1bc" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "204f06860af9008fa08b3a4842f48116e1209a2c" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.20.10" +version = "0.21.9" [[deps.MakieCore]] -deps = ["Observables", "REPL"] -git-tree-sha1 = "248b7a4be0f92b497f7a331aed02c1e9a878f46b" +deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] +git-tree-sha1 = "b0e2e3473af351011e598f9219afb521121edd2b" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.7.3" +version = "0.8.6" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1151,15 +1159,15 @@ version = "0.1.2" [[deps.MathOptInterface]] deps = ["BenchmarkTools", "CodecBzip2", "CodecZlib", "DataStructures", "ForwardDiff", "JSON", "LinearAlgebra", "MutableArithmetics", "NaNMath", "OrderedCollections", "PrecompileTools", "Printf", "SparseArrays", "SpecialFunctions", "Test", "Unicode"] -git-tree-sha1 = "c0fe113e9c72aa0c9a185fd3c5ca1daa51de1486" +git-tree-sha1 = "5b246fca5420ae176d65ed43a2d0ee5897775216" uuid = "b8f27783-ece8-5eb3-8dc8-9495eed66fee" -version = "1.31.1" +version = "1.31.2" [[deps.MathTeXEngine]] deps = ["AbstractTrees", "Automa", "DataStructures", "FreeTypeAbstraction", "GeometryBasics", "LaTeXStrings", "REPL", "RelocatableFolders", "UnicodeFun"] -git-tree-sha1 = "96ca8a313eb6437db5ffe946c457a401bbb8ce1d" +git-tree-sha1 = "e1641f32ae592e415e3dbae7f4a188b5316d4b62" uuid = "0a4f8689-d25c-4efe-a92b-7142dfc1aa53" -version = "0.5.7" +version = "0.6.1" [[deps.MbedTLS]] deps = ["Dates", "MbedTLS_jll", "MozillaCACerts_jll", "NetworkOptions", "Random", "Sockets"] @@ -1211,9 +1219,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "94fa6864fcf891e7214a1dd73c773d325556de28" +git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.0" +version = "0.2.1" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1292,10 +1300,10 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e" version = "0.5.5+0" [[deps.Opus_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "51a08fb14ec28da2ec7a927c4337e4332c2a4720" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "6703a85cb3781bd5909d48730a67205f3f31a575" uuid = "91d4177d-7536-5919-b921-800302f37372" -version = "1.3.2+0" +version = "1.3.3+0" [[deps.OrderedCollections]] git-tree-sha1 = "dfdf5519f235516220579f949664f1bf44e741c5" @@ -1333,9 +1341,9 @@ version = "0.5.12" [[deps.Pango_jll]] deps = ["Artifacts", "Cairo_jll", "Fontconfig_jll", "FreeType2_jll", "FriBidi_jll", "Glib_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl"] -git-tree-sha1 = "cb5a2ab6763464ae0f19c86c56c63d4a2b0f5bda" +git-tree-sha1 = "e127b609fb9ecba6f201ba7ab753d5a605d53801" uuid = "36c8627f-9965-5494-a995-c6b170f724f3" -version = "1.52.2+0" +version = "1.54.1+0" [[deps.Parsers]] deps = ["Dates", "PrecompileTools", "UUIDs"] @@ -1371,18 +1379,6 @@ git-tree-sha1 = "77b3d3605fc1cd0b42d95eba87dfcd2bf67d5ff6" uuid = "647866c9-e3ac-4575-94e7-e3d426903924" version = "0.1.2" -[[deps.PreallocationTools]] -deps = ["Adapt", "ArrayInterface", "ForwardDiff"] -git-tree-sha1 = "6c62ce45f268f3f958821a1e5192cf91c75ae89c" -uuid = "d236fae5-4411-538c-8e31-a6e3d9e00b46" -version = "0.4.24" - - [deps.PreallocationTools.extensions] - PreallocationToolsReverseDiffExt = "ReverseDiff" - - [deps.PreallocationTools.weakdeps] - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" - [[deps.PrecompileTools]] deps = ["Preferences"] git-tree-sha1 = "5aa36f7049a63a1528fe8f7c3f2113413ffd4e1f" @@ -1395,6 +1391,12 @@ git-tree-sha1 = "9306f6085165d270f7e3db02af26a400d580f5c6" uuid = "21216c6a-2e73-6563-6e65-726566657250" version = "1.4.3" +[[deps.Primes]] +deps = ["IntegerMathUtils"] +git-tree-sha1 = "cb420f77dc474d23ee47ca8d14c90810cafe69e7" +uuid = "27ebfcd6-29c5-5fa9-bf4b-fb8fc14df3ae" +version = "0.5.6" + [[deps.Printf]] deps = ["Unicode"] uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" @@ -1410,9 +1412,9 @@ uuid = "92933f4c-e287-5a05-a399-4b506db050ca" version = "1.10.2" [[deps.PtrArrays]] -git-tree-sha1 = "f011fbb92c4d401059b2212c05c0601b70f8b759" +git-tree-sha1 = "77a42d78b6a92df47ab37e177b2deac405e1c88f" uuid = "43287f4e-b6f4-7ad1-bb20-aadabca52c3d" -version = "1.2.0" +version = "1.2.1" [[deps.QOI]] deps = ["ColorTypes", "FileIO", "FixedPointNumbers"] @@ -1422,9 +1424,15 @@ version = "1.0.0" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "e237232771fdafbae3db5c31275303e056afaa9f" +git-tree-sha1 = "1d587203cf851a51bf1ea31ad7ff89eff8d625ea" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.10.1" +version = "2.11.0" + + [deps.QuadGK.extensions] + QuadGKEnzymeExt = "Enzyme" + + [deps.QuadGK.weakdeps] + Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.QuantumCollocation]] deps = ["BenchmarkTools", "CairoMakie", "Distributions", "Einsum", "ExponentialAction", "ForwardDiff", "IJulia", "Ipopt", "JLD2", "Libdl", "LinearAlgebra", "MathOptInterface", "NamedTrajectories", "ProgressMeter", "Random", "Reexport", "SparseArrays", "Symbolics", "TestItemRunner", "TestItems", "TrajectoryIndexingUtils"] @@ -1557,9 +1565,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "5123ca064567e81c31fb3acdf15d2c9459bb7cc3" +git-tree-sha1 = "8001043f80051c86f264fd6e936d97e6b9eff401" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.50.0" +version = "2.52.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1581,17 +1589,21 @@ version = "2.50.0" Zygote = "e88e6eb3-aa80-5325-afca-941959d7151f" [[deps.SciMLOperators]] -deps = ["ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools", "Setfield", "StaticArraysCore"] -git-tree-sha1 = "23b02c588ac9a17ecb276cc62ab37f3e4fe37b32" +deps = ["Accessors", "ArrayInterface", "DocStringExtensions", "LinearAlgebra", "MacroTools"] +git-tree-sha1 = "e39c5f217f9aca640c8e27ab21acf557a3967db5" uuid = "c0aeaf25-5076-4817-a8d5-81caf7dfa961" -version = "0.3.9" -weakdeps = ["SparseArrays"] +version = "0.3.10" +weakdeps = ["SparseArrays", "StaticArraysCore"] + + [deps.SciMLOperators.extensions] + SciMLOperatorsSparseArraysExt = "SparseArrays" + SciMLOperatorsStaticArraysCoreExt = "StaticArraysCore" [[deps.SciMLStructures]] deps = ["ArrayInterface"] -git-tree-sha1 = "20ad3e7c137156c50c93c888d0f2bc5b7883c729" +git-tree-sha1 = "25514a6f200219cd1073e4ff23a6324e4a7efe64" uuid = "53ae85a6-f571-4167-b2af-e1d143709226" -version = "1.4.2" +version = "1.5.0" [[deps.Scratch]] deps = ["Dates"] @@ -1762,21 +1774,28 @@ uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" version = "0.2.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LabelledArrays", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] -git-tree-sha1 = "d00729521f49d96afd3fcddb437141eb71222886" +deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "40b48f4eb06a4bd450c50b4206f7f490556214e1" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.2.0" +version = "3.5.0" + + [deps.SymbolicUtils.extensions] + SymbolicUtilsLabelledArraysExt = "LabelledArrays" + + [deps.SymbolicUtils.weakdeps] + LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" [[deps.Symbolics]] -deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "4224422f6a5452b1accaec15a65a5ce3c2ca4600" +deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] +git-tree-sha1 = "19a3555ce5d82798b5ab67bdf8b4444d54a159de" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.2.0" +version = "6.5.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" SymbolicsLuxCoreExt = "LuxCore" + SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1784,6 +1803,7 @@ version = "6.2.0" ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" @@ -1826,14 +1846,14 @@ uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [[deps.TestItemRunner]] deps = ["Pkg", "TOML", "Test", "TestItems", "UUIDs"] -git-tree-sha1 = "cb2b53fd36a8fe20c0b9f55da6244eb4818779f5" +git-tree-sha1 = "29647c5398be04a1d697265ba385bdf3f623c993" uuid = "f8b46487-2199-4994-9208-9a1283c18c0a" -version = "0.2.3" +version = "1.0.5" [[deps.TestItems]] -git-tree-sha1 = "8621ba2637b49748e2dc43ba3d84340be2938022" +git-tree-sha1 = "42fd9023fef18b9b78c8343a4e2f3813ffbcefcb" uuid = "1c621080-faea-4a02-84b6-bbd5e436b8fe" -version = "0.1.1" +version = "1.0.0" [[deps.TiffImages]] deps = ["ColorTypes", "DataStructures", "DocStringExtensions", "FileIO", "FixedPointNumbers", "IndirectArrays", "Inflate", "Mmap", "OffsetArrays", "PkgVersion", "ProgressMeter", "SIMD", "UUIDs"] @@ -1886,6 +1906,17 @@ git-tree-sha1 = "2264362f72926965e708ee26f58824b929c72637" uuid = "967fb449-e509-55aa-8007-234b4096b967" version = "1.1.0" +[[deps.Unitful]] +deps = ["Dates", "LinearAlgebra", "Random"] +git-tree-sha1 = "d95fe458f26209c66a187b1114df96fd70839efd" +uuid = "1986cc42-f94f-5a68-af5c-568840ba703d" +version = "1.21.0" +weakdeps = ["ConstructionBase", "InverseFunctions"] + + [deps.Unitful.extensions] + ConstructionBaseUnitfulExt = "ConstructionBase" + InverseFunctionsUnitfulExt = "InverseFunctions" + [[deps.Unityper]] deps = ["ConstructionBase"] git-tree-sha1 = "25008b734a03736c41e2a7dc314ecb95bd6bbdb0" @@ -1905,9 +1936,9 @@ version = "1.0.0" [[deps.XML2_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"] -git-tree-sha1 = "d9717ce3518dc68a99e6b96300813760d887a01d" +git-tree-sha1 = "1165b0443d0eca63ac1e32b8c0eb69ed2f4f8127" uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a" -version = "2.13.1+0" +version = "2.13.3+0" [[deps.XSLT_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Libgcrypt_jll", "Libgpg_error_jll", "Libiconv_jll", "XML2_jll", "Zlib_jll"] @@ -1993,10 +2024,10 @@ uuid = "a4ae2306-e953-59d6-aa16-d00cac43593b" version = "3.9.0+0" [[deps.libass_jll]] -deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Pkg", "Zlib_jll"] -git-tree-sha1 = "5982a94fcba20f02f42ace44b9894ee2b140fe47" +deps = ["Artifacts", "Bzip2_jll", "FreeType2_jll", "FriBidi_jll", "HarfBuzz_jll", "JLLWrappers", "Libdl", "Zlib_jll"] +git-tree-sha1 = "e17c115d55c5fbb7e52ebedb427a0dca79d4484e" uuid = "0ac62f75-1d6f-5e53-bd7c-93b484bb37c0" -version = "0.15.1+0" +version = "0.15.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] @@ -2004,10 +2035,10 @@ uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" version = "5.8.0+1" [[deps.libfdk_aac_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "daacc84a041563f965be61859a36e17c4e4fcd55" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "8a22cf860a7d27e4f3498a0fe0811a7957badb38" uuid = "f638f0a6-7fb0-5443-88ba-1cc74229b280" -version = "2.0.2+0" +version = "2.0.3+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] @@ -2050,13 +2081,13 @@ uuid = "3f19e933-33d8-53b3-aaab-bd5110c3b7a0" version = "17.4.0+2" [[deps.x264_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "4fea590b89e6ec504593146bf8b988b2c00922b2" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "35976a1216d6c066ea32cba2150c4fa682b276fc" uuid = "1270edf5-f2f9-52d2-97e9-ab00b5d0237a" -version = "2021.5.5+0" +version = "10164.0.0+0" [[deps.x265_jll]] -deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "ee567a171cce03570d77ad3a43e90218e38937a9" +deps = ["Artifacts", "JLLWrappers", "Libdl"] +git-tree-sha1 = "dcc541bb19ed5b0ede95581fb2e41ecf179527d2" uuid = "dfaa095f-4041-5dcd-9319-2fabd8486b76" -version = "3.5.0+0" +version = "3.6.0+0" diff --git a/docs/literate/man/embedded_operators.jl b/docs/literate/man/embedded_operators.jl new file mode 100644 index 0000000..8ac8326 --- /dev/null +++ b/docs/literate/man/embedded_operators.jl @@ -0,0 +1,73 @@ +# ```@meta +# CollapsedDocStrings = true +# ``` +# # Embedded Operators + +# In this manual, we will discuss embedding operators in subspaces of larger quantum systems. + +# ## The `embed` and `unembed` functions + +# A frequent situation in quantum optimal control is the need to embed a quantum operator in a larger Hilbert space. This is often necessary when the control Hamiltonian acts on a subspace of the full Hilbert space. + +# The [`embed`](@ref) function allows to embed a quantum operator in a larger Hilbert space. +# ```@docs +# embed +# ``` + +# The [`unembed`](@ref) function allows to unembed a quantum operator from a larger Hilbert space. +# ```@docs +# unembed +# ``` + +# For example, for a single qubit X gate embedded in a multilevel system: + +using QuantumCollocation + +## define levels of full system +levels = 3 + +## get a 2-level X gate +X = GATES[:X] + +## define subspace indices as lowest two levels +subspace_indices = 1:2 + +## embed the X gate in the full system +X_embedded = embed(X, subspace_indices, levels) + +# We can retrieve the original operator: + +X_unembedded = unembed(X_embedded, subspace_indices) + + +# ## The `EmbeddedOperator` type + +# The `EmbeddedOperator` type is a convenient way to define an operator embedded in a subspace of a larger quantum system. + +# The `EmbeddedOperator` type is defined as follows: + +# ```@docs +# EmbeddedOperator +# ``` + +# And can be constructed using the following method: + +# ```@docs +# EmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int}) +# ``` + +# For example, for a single qubit X gate embedded in a multilevel system: + +## define the target operator + +gate = GATES[:X] ⊗ GATES[:I] + +subsystem_levels = [3, 3] + +subspace_indices = get_subspace_indices([1:2, 1:2], subsystem_levels) + +op = EmbeddedOperator(gate, subspace_indices, subsystem_levels) + +op.operator + +## show the full operator diff --git a/docs/make.jl b/docs/make.jl index 9049232..3f86715 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -15,7 +15,8 @@ pages = [ "Manual" => [ "Problem Templates" => "generated/man/problem_templates.md", "Utilities" => "generated/man/utils.md", - "Losses" => "generated/man/losses.md" + "Losses" => "generated/man/losses.md", + "Embedded Operators" => "generated/man/embedded_operators.md", ], "Examples" => [ "Multilevel Transmon" => "generated/examples/multilevel_transmon.md", diff --git a/docs/src/generated/man/embedded_operators.md b/docs/src/generated/man/embedded_operators.md new file mode 100644 index 0000000..e4e7104 --- /dev/null +++ b/docs/src/generated/man/embedded_operators.md @@ -0,0 +1,87 @@ +```@meta +EditURL = "../../../literate/man/embedded_operators.jl" +``` + +```@meta +CollapsedDocStrings = true +``` +# Embedded Operators + +In this manual, we will discuss embedding operators in subspaces of larger quantum systems. + +## The `embed` and `unembed` functions + +A frequent situation in quantum optimal control is the need to embed a quantum operator in a larger Hilbert space. This is often necessary when the control Hamiltonian acts on a subspace of the full Hilbert space. + +The [`embed`](@ref) function allows to embed a quantum operator in a larger Hilbert space. +```@docs +embed +``` + +The [`unembed`](@ref) function allows to unembed a quantum operator from a larger Hilbert space. +```@docs +unembed +``` + +For example, for a single qubit X gate embedded in a multilevel system: + +````@example embedded_operators +using QuantumCollocation + +# define levels of full system +levels = 3 + +# get a 2-level X gate +X = GATES[:X] + +# define subspace indices as lowest two levels +subspace_indices = 1:2 + +# embed the X gate in the full system +X_embedded = embed(X, subspace_indices, levels) +```` + +We can retrieve the original operator: + +````@example embedded_operators +X_unembedded = unembed(X_embedded, subspace_indices) +```` + +## The `EmbeddedOperator` type + +The `EmbeddedOperator` type is a convenient way to define an operator embedded in a subspace of a larger quantum system. + +The `EmbeddedOperator` type is defined as follows: + +```@docs +EmbeddedOperator +``` + +And can be constructed using the following method: + +```@docs +EmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int}) +``` + +For example, for a single qubit X gate embedded in a multilevel system: + +````@example embedded_operators +# define the target operator + +gate = GATES[:X] ⊗ GATES[:I] + +subsystem_levels = [3, 3] + +subspace_indices = get_subspace_indices([1:2, 1:2], subsystem_levels) + +op = EmbeddedOperator(gate, subspace_indices, subsystem_levels) + +op.operator + +# show the full operator +```` + +--- + +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* + diff --git a/src/embedded_operators.jl b/src/embedded_operators.jl index 16b4636..d0424c7 100644 --- a/src/embedded_operators.jl +++ b/src/embedded_operators.jl @@ -22,36 +22,73 @@ using ..QuantumObjectUtils using ..QuantumSystems # using ..QuantumSystemUtils +@doc raw""" + embed(matrix::Matrix{ComplexF64}, subspace_indices::AbstractVector{Int}, levels::Int) +Embed an operator $U$ in the subspace of a larger system $\mathcal{X} = \mathcal{X}_{\text{subspace}} \oplus \mathcal{X}_{\text{leakage}}$ which is composed of matrices of size $\text{levels} \times \text{levels}$. + +# Arguments +- `matrix::Matrix{ComplexF64}`: Operator to embed. +- `subspace_indices::AbstractVector{Int}`: Indices of the subspace to embed the operator in. +- `levels::Int`: Total number of levels in the system. +""" function embed(op::Matrix{ComplexF64}, subspace_indices::AbstractVector{Int}, levels::Int) - """ - Embed an operator in a subspace defined at `subspace_indices` within `levels`. - """ @assert size(op, 1) == size(op, 2) "Operator must be square." op_embedded = zeros(ComplexF64, levels, levels) op_embedded[subspace_indices, subspace_indices] = op return op_embedded end +@doc raw""" + unembed(matrix::AbstractMatrix, subspace_indices::AbstractVector{Int}) + +Unembed an operator $U$ from a subspace of a larger system $\mathcal{X} = \mathcal{X}_{\text{subspace}} \oplus \mathcal{X}_{\text{leakage}}$ which is composed of matrices of size $\text{levels} \times \text{levels}$. + +This is equivalent to calling `matrix[subspace_indices, subspace_indices]`. + +# Arguments +- `matrix::AbstractMatrix`: Operator to unembed. +- `subspace_indices::AbstractVector{Int}`: Indices of the subspace to unembed the operator from. +""" +function unembed(matrix::AbstractMatrix, subspace_indices::AbstractVector{Int}) + return matrix[subspace_indices, subspace_indices] +end + # ----------------------------------------------------------------------------- # # Embedded Operator # # ----------------------------------------------------------------------------- # +""" + EmbeddedOperator + +Embedded operator type to represent an operator embedded in a subspace of a larger quantum system. + +# Fields +- `operator::Matrix{ComplexF64}`: Embedded operator of size `prod(subsystem_levels) x prod(subsystem_levels)`. +- `subspace_indices::Vector{Int}`: Indices of the subspace the operator is embedded in. +- `subsystem_levels::Vector{Int}`: Levels of the subsystems in the composite system. +""" struct EmbeddedOperator operator::Matrix{ComplexF64} subspace_indices::Vector{Int} subsystem_levels::Vector{Int} + @doc raw""" + EmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int}) + + Create an embedded operator. The operator `op` is embedded in the subspace defined by `subspace_indices` in `subsystem_levels`. + + # Arguments + - `op::Matrix{<:Number}`: Operator to embed. + - `subspace_indices::AbstractVector{Int}`: Indices of the subspace to embed the operator in. e.g. `get_subspace_indices([1:2, 1:2], [3, 3])`. + - `subsystem_levels::AbstractVector{Int}`: Levels of the subsystems in the composite system. e.g. `[3, 3]` for two 3-level systems. + """ function EmbeddedOperator( op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int} ) - """ - Create an embedded operator. - The operator `op` is embedded in the subspace defined by `subspace_indices` in `subsystem_levels`. - """ op_embedded = embed(Matrix{ComplexF64}(op), subspace_indices, prod(subsystem_levels)) return new(op_embedded, subspace_indices, subsystem_levels) end From 4dbf74c6be7e5124cc1602f79e4af976c5a2f555 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 9 Sep 2024 16:03:57 -0400 Subject: [PATCH 12/35] docs final touches --- docs/literate/man/embedded_operators.jl | 52 +++++++++++++++-- docs/src/generated/man/embedded_operators.md | 59 ++++++++++++++++++-- src/embedded_operators.jl | 44 ++++++++++++++- 3 files changed, 143 insertions(+), 12 deletions(-) diff --git a/docs/literate/man/embedded_operators.jl b/docs/literate/man/embedded_operators.jl index 8ac8326..9f1c4b5 100644 --- a/docs/literate/man/embedded_operators.jl +++ b/docs/literate/man/embedded_operators.jl @@ -22,6 +22,7 @@ # For example, for a single qubit X gate embedded in a multilevel system: using QuantumCollocation +using SparseArrays # for visualization ## define levels of full system levels = 3 @@ -56,18 +57,59 @@ X_unembedded = unembed(X_embedded, subspace_indices) # EmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int}) # ``` -# For example, for a single qubit X gate embedded in a multilevel system: - -## define the target operator +# For example, for an X gate on the first qubit of two qubit, 3-level system: +## define the target operator X ⊗ I gate = GATES[:X] ⊗ GATES[:I] +## define the subsystem levels subsystem_levels = [3, 3] +## define the subspace indices subspace_indices = get_subspace_indices([1:2, 1:2], subsystem_levels) +## create the embedded operator op = EmbeddedOperator(gate, subspace_indices, subsystem_levels) -op.operator - ## show the full operator +op.operator .|> abs |> sparse + +# We can get the original operator back: + +gate_unembeded = unembed(op) + +gate_unembeded .|> abs |> sparse + +# ## The `get_subspace_indices` function + +# The `get_subspace_indices` function is a convenient way to get the indices of a subspace in a larger quantum system. + +# ### Simple quantum systems +# For simple (non-composite) quantum systems, such as a single multilevel qubit, we provode the following method: + +# ```@docs +# get_subspace_indices(subspace::AbstractVector{Int}, levels::Int) +# ``` + +## get the indices of the lowest two levels of a 3-level system +subspace_indices = get_subspace_indices(1:2, 3) + +# ### Comosite quantum systems +# For composite quantum systems, such as a two qubit system, we provide the following methods. + +# Targeting subspaces in a composite quantum system, with general subsystem levels: +# ```@docs +# get_subspace_indices(subspaces::Vector{<:AbstractVector{Int}}, subsystem_levels::AbstractVector{Int}) +# ``` + +## get the subspace indices for a three level qubit coupled to a 9-level cavity +get_subspace_indices([1:2, 1:2], [3, 9]) + + +# Targeting subspaces in a composite quantum system, with all subsystems having the same number of levels: +# ```@docs +# get_subspace_indices(levels::AbstractVector{Int}; subspace=1:2, kwargs...) +# ``` + +## get the subspace indices for a two qubit system with 3 levels each +get_subspace_indices([3, 3]) diff --git a/docs/src/generated/man/embedded_operators.md b/docs/src/generated/man/embedded_operators.md index e4e7104..3621bfd 100644 --- a/docs/src/generated/man/embedded_operators.md +++ b/docs/src/generated/man/embedded_operators.md @@ -27,6 +27,7 @@ For example, for a single qubit X gate embedded in a multilevel system: ````@example embedded_operators using QuantumCollocation +using SparseArrays # for visualization # define levels of full system levels = 3 @@ -63,22 +64,70 @@ And can be constructed using the following method: EmbeddedOperator(op::Matrix{<:Number}, subspace_indices::AbstractVector{Int}, subsystem_levels::AbstractVector{Int}) ``` -For example, for a single qubit X gate embedded in a multilevel system: +For example, for an X gate on the first qubit of two qubit, 3-level system: ````@example embedded_operators -# define the target operator - +# define the target operator X ⊗ I gate = GATES[:X] ⊗ GATES[:I] +# define the subsystem levels subsystem_levels = [3, 3] +# define the subspace indices subspace_indices = get_subspace_indices([1:2, 1:2], subsystem_levels) +# create the embedded operator op = EmbeddedOperator(gate, subspace_indices, subsystem_levels) -op.operator - # show the full operator +op.operator .|> abs |> sparse +```` + +We can get the original operator back: + +````@example embedded_operators +gate_unembeded = unembed(op) + +gate_unembeded .|> abs |> sparse +```` + +## The `get_subspace_indices` function + +The `get_subspace_indices` function is a convenient way to get the indices of a subspace in a larger quantum system. + +### Simple quantum systems +For simple (non-composite) quantum systems, such as a single multilevel qubit, we provode the following method: + +```@docs +get_subspace_indices(subspace::AbstractVector{Int}, levels::Int) +``` + +````@example embedded_operators +# get the indices of the lowest two levels of a 3-level system +subspace_indices = get_subspace_indices(1:2, 3) +```` + +### Comosite quantum systems +For composite quantum systems, such as a two qubit system, we provide the following methods. + +Targeting subspaces in a composite quantum system, with general subsystem levels: +```@docs +get_subspace_indices(subspaces::Vector{<:AbstractVector{Int}}, subsystem_levels::AbstractVector{Int}) +``` + +````@example embedded_operators +# get the subspace indices for a three level qubit coupled to a 9-level cavity +get_subspace_indices([1:2, 1:2], [3, 9]) +```` + +Targeting subspaces in a composite quantum system, with all subsystems having the same number of levels: +```@docs +get_subspace_indices(levels::AbstractVector{Int}; subspace=1:2, kwargs...) +``` + +````@example embedded_operators +# get the subspace indices for a two qubit system with 3 levels each +get_subspace_indices([3, 3]) ```` --- diff --git a/src/embedded_operators.jl b/src/embedded_operators.jl index d0424c7..80d7a2b 100644 --- a/src/embedded_operators.jl +++ b/src/embedded_operators.jl @@ -221,6 +221,23 @@ basis_labels(subsystem_levels::AbstractVector{Int}; baseline=1) = basis_labels(subsystem_level::Int; kwargs...) = basis_labels([subsystem_level]; kwargs...) +""" + get_subspace_indices(subspaces::Vector{<:AbstractVector{Int}}, subsystem_levels::AbstractVector{Int}) + +Get the indices for the subspace of composite quantum system. + +Example: for the two-qubit subspace of two 3-level systems: +```julia +subspaces = [1:2, 1:2] +subsystem_levels = [3, 3] +get_subspace_indices(subspaces, subsystem_levels) == [1, 2, 4, 5] +``` + +# Arguments + +- `subspaces::Vector{<:AbstractVector{Int}}`: Subspaces to get indices for. e.g. `[1:2, 1:2]`. +- `subsystem_levels::AbstractVector{Int}`: Levels of the subsystems in the composite system. e.g. `[3, 3]`. Each element corresponds to a subsystem. +""" function get_subspace_indices( subspaces::Vector{<:AbstractVector{Int}}, subsystem_levels::AbstractVector{Int} @@ -232,11 +249,34 @@ function get_subspace_indices( ) end +""" + get_subspace_indices(subspace::AbstractVector{Int}, levels::Int) + +Get the indices for the subspace of simple, non-composite, quantum system. For example: +```julia +get_subspace_indices([1, 2], 3) == [1, 2] +``` + +# Arguments +- `subspace::AbstractVector{Int}`: Subspace to get indices for. e.g. `[1, 2]`. +- `levels::Int`: Levels of the subsystem. e.g. `3`. +""" get_subspace_indices(subspace::AbstractVector{Int}, levels::Int) = get_subspace_indices([subspace], [levels]) -get_subspace_indices(levels::AbstractVector{Int}; subspace=1:2, kwargs...) = - get_subspace_indices(fill(subspace, length(levels)), levels; kwargs...) +""" + get_subspace_indices(levels::AbstractVector{Int}; subspace=1:2, kwargs...) + +Get the indices for the subspace of composite quantum system. This is a convenience function that allows to specify the subspace as a range that is constant for every subsystem, which defaults to `1:2`, that is qubit systems. + +# Arguments +- `levels::AbstractVector{Int}`: Levels of the subsystems in the composite system. e.g. `[3, 3]`. + +# Keyword Arguments +- `subspace::AbstractVector{Int}`: Subspace to get indices for. e.g. `1:2`. +""" +get_subspace_indices(levels::AbstractVector{Int}; subspace=1:2) = + get_subspace_indices(fill(subspace, length(levels)), levels) function get_subspace_enr_indices(excitation_restriction::Int, subsystem_levels::AbstractVector{Int}) # excitation_number uses baseline of zero From 91afdb3a242beea96865bce36adff8669bba61ff Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 9 Sep 2024 16:41:29 -0400 Subject: [PATCH 13/35] compat bump --- Manifest.toml | 53 +++++++++++++++++++++++++++------------------------ Project.toml | 4 ++-- 2 files changed, 30 insertions(+), 27 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index b6c1ac3..dd2de93 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.4" +julia_version = "1.10.5" manifest_format = "2.0" project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" @@ -367,9 +367,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "46f12daa85e5acc0ea5d5f9f8c3f1fc679e0f7e5" +git-tree-sha1 = "9903123ab7fc5e55053292aff04ff5d7aff92633" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.2.0" +version = "1.3.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -763,16 +763,17 @@ weakdeps = ["Unitful"] [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "01fa84a20be8c7c867edf3b9ef33ac15f4089c1a" +git-tree-sha1 = "fe30dec78e68f27fc416901629c6e24e9d5f057b" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.15" -weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "RecipesBase"] +version = "0.22.16" +weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "RecipesBase"] [deps.IntervalArithmetic.extensions] IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" + IntervalArithmeticIntervalSetsExt = "IntervalSets" + IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" - IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -830,9 +831,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] -git-tree-sha1 = "a0746c21bdc986d0dc293efa6b1faee112c37c28" +git-tree-sha1 = "1dbe274ad1c199490b19a153b60a9e46c5386f8d" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.53" +version = "0.5.1" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -1115,9 +1116,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" +git-tree-sha1 = "8b72d6806501fd61684dcc6e9c336855acd5abe1" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.1" +version = "0.2.2" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1179,9 +1180,9 @@ version = "0.8.1+2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" +git-tree-sha1 = "1b35263570443fdd9e76c76b7062116e2f374ab8" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.14+0" +version = "3.0.15+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1437,9 +1438,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "8001043f80051c86f264fd6e936d97e6b9eff401" +git-tree-sha1 = "303a73db99326a8be43e695fbab9e076b02118ca" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.52.0" +version = "2.52.2" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1630,9 +1631,9 @@ version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "c9fce29fb41a10677e24f74421ebe31220b81ad0" +git-tree-sha1 = "988e04b34a4c3b824fb656f542473df99a4f610d" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.28" +version = "0.3.30" [[deps.SymbolicLimits]] deps = ["SymbolicUtils"] @@ -1641,27 +1642,29 @@ uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" version = "0.2.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] -git-tree-sha1 = "40b48f4eb06a4bd450c50b4206f7f490556214e1" +deps = ["AbstractTrees", "ArrayInterface", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "9d983078d9e99421fcca44c373e4304b8421fdde" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.5.0" +version = "3.6.0" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" + SymbolicUtilsReverseDiffExt = "ReverseDiff" [deps.SymbolicUtils.weakdeps] LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "19a3555ce5d82798b5ab67bdf8b4444d54a159de" +git-tree-sha1 = "2226d810512c678d2ec9c2a9b2e227c2ebc43573" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.5.0" +version = "6.11.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" - SymbolicsLuxCoreExt = "LuxCore" + SymbolicsLuxExt = "Lux" SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1669,7 +1672,7 @@ version = "6.5.0" [deps.Symbolics.weakdeps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" - LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + Lux = "b2108857-7c20-44ae-9111-449ecde12c47" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" @@ -1894,7 +1897,7 @@ version = "0.15.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" +version = "5.11.0+0" [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] diff --git a/Project.toml b/Project.toml index 623781c..10bdbed 100644 --- a/Project.toml +++ b/Project.toml @@ -37,12 +37,12 @@ ForwardDiff = "0.10" IJulia = "1.25" Interpolations = "0.15" Ipopt = "1.6" -JLD2 = "0.4" +JLD2 = "0.5" MathOptInterface = "1.31" NamedTrajectories = "0.2" ProgressMeter = "1.10" Reexport = "1.2" -Symbolics = "6.2" +Symbolics = "6.11" TestItemRunner = "1.0" TestItems = "1.0" TrajectoryIndexingUtils = "0.1" From 23ce875eca03577ac77d0045d85bf307dd687abb Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 10 Sep 2024 08:22:58 -0400 Subject: [PATCH 14/35] patch: repo name --- docs/make.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/make.jl b/docs/make.jl index 3f86715..c2fb7d8 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -67,6 +67,6 @@ makedocs(; ) deploydocs(; - repo="github.com/aarontrowbridge/QuantumCollocation.jl.git", + repo="github.com/kestrelquantum/QuantumCollocation.jl.git", devbranch="main", ) From 6e6cd3830ce9c2eb3ce9377533b4a8603e499122 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 16 Sep 2024 16:52:46 +0200 Subject: [PATCH 15/35] doc string addition --- src/plotting.jl | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/plotting.jl b/src/plotting.jl index 90ab1c5..fcadb40 100644 --- a/src/plotting.jl +++ b/src/plotting.jl @@ -16,23 +16,23 @@ function get_layout(index::Int, n::Int) return ((index - 1) ÷ √n + 1, (index - 1) % √n + 1) end -# """ -# plot_unitary_populations( -# traj::NamedTrajectory; -# unitary_columns::AbstractVector{Int}=1:2, -# unitary_name::Symbol=:Ũ⃗, -# control_name::Symbol=:a, -# kwargs... -# ) +""" + plot_unitary_populations( + traj::NamedTrajectory; + unitary_columns::AbstractVector{Int}=1:2, + unitary_name::Symbol=:Ũ⃗, + control_name::Symbol=:a, + kwargs... + ) -# plot_unitary_populations( -# prob::QuantumControlProblem; -# kwargs... -# ) + plot_unitary_populations( + prob::QuantumControlProblem; + kwargs... + ) -# Plot the populations of the unitary columns of the unitary matrix in the trajectory. `kwargs` are passed to [`NamedTrajectories.plot`](https://aarontrowbridge.github.io/NamedTrajectories.jl/dev/generated/plotting/). -# """ -# function plot_unitary_populations end +Plot the populations of the unitary columns of the unitary matrix in the trajectory. `kwargs` are passed to [`NamedTrajectories.plot`](https://aarontrowbridge.github.io/NamedTrajectories.jl/dev/generated/plotting/). +""" +function plot_unitary_populations end function plot_unitary_populations( traj::NamedTrajectory; From 2e768db1a3bf4f493229f2dc595388f9649b9868 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 17 Sep 2024 21:36:27 +0200 Subject: [PATCH 16/35] docs: two qubit gates --- docs/Manifest.toml | 117 ++++----- docs/literate/examples/two_qubit_gates.jl | 201 +++++++++++++++ docs/make.jl | 1 + .../src/generated/examples/two_qubit_gates.md | 233 ++++++++++++++++++ 4 files changed, 497 insertions(+), 55 deletions(-) create mode 100644 docs/literate/examples/two_qubit_gates.jl create mode 100644 docs/src/generated/examples/two_qubit_gates.md diff --git a/docs/Manifest.toml b/docs/Manifest.toml index 08ab4c5..b5a57e3d 100644 --- a/docs/Manifest.toml +++ b/docs/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.3" +julia_version = "1.10.5" manifest_format = "2.0" project_hash = "46fa82f4324d65b2cf462382aecded8067fca5f1" @@ -68,24 +68,28 @@ uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" version = "0.4.5" [[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] -git-tree-sha1 = "f61b15be1d76846c0ce31d3fcfac5380ae53db6a" +deps = ["CompositionsBase", "ConstructionBase", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown"] +git-tree-sha1 = "b392ede862e506d451fc1616e79aa6f4c673dab8" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.37" +version = "0.1.38" [deps.Accessors.extensions] AccessorsAxisKeysExt = "AxisKeys" + AccessorsDatesExt = "Dates" AccessorsIntervalSetsExt = "IntervalSets" AccessorsStaticArraysExt = "StaticArrays" AccessorsStructArraysExt = "StructArrays" + AccessorsTestExt = "Test" AccessorsUnitfulExt = "Unitful" [deps.Accessors.weakdeps] AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" Requires = "ae029012-a4dd-5104-9daa-d747884805df" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.Adapt]] @@ -99,9 +103,9 @@ weakdeps = ["StaticArrays"] AdaptStaticArraysExt = "StaticArrays" [[deps.AdaptivePredicates]] -git-tree-sha1 = "7d5da5dd472490d048b081ca1bda4a7821b06456" +git-tree-sha1 = "7e651ea8d262d2d74ce75fdf47c4d63c07dba7a6" uuid = "35492f91-a3bd-45ad-95db-fcad7dcfedb7" -version = "1.1.1" +version = "1.2.0" [[deps.AliasTables]] deps = ["PtrArrays", "Random"] @@ -217,9 +221,9 @@ version = "1.1.0" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "361dec06290d76b6d70d0c7dc888038eec9df63a" +git-tree-sha1 = "4f827b38d3d9ffe6e3b01fbcf866c625fa259ca5" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.12.9" +version = "0.12.11" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -389,9 +393,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "46f12daa85e5acc0ea5d5f9f8c3f1fc679e0f7e5" +git-tree-sha1 = "94eb20e6621600f4315813b1d1fc9b8a5a6a34db" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.2.0" +version = "1.4.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -433,9 +437,9 @@ version = "0.9.3" [[deps.Documenter]] deps = ["ANSIColoredPrinters", "AbstractTrees", "Base64", "CodecZlib", "Dates", "DocStringExtensions", "Downloads", "Git", "IOCapture", "InteractiveUtils", "JSON", "LibGit2", "Logging", "Markdown", "MarkdownAST", "Pkg", "PrecompileTools", "REPL", "RegistryInstances", "SHA", "TOML", "Test", "Unicode"] -git-tree-sha1 = "9d29b99b6b2b6bc2382a4c8dbec6eb694f389853" +git-tree-sha1 = "5a1ee886566f2fa9318df1273d8b778b9d42712d" uuid = "e30172f5-a6a5-5a46-863b-614d45cd2de4" -version = "1.6.0" +version = "1.7.0" [[deps.DomainSets]] deps = ["CompositeTypes", "IntervalSets", "LinearAlgebra", "Random", "StaticArrays"] @@ -821,16 +825,17 @@ weakdeps = ["Unitful"] [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "01fa84a20be8c7c867edf3b9ef33ac15f4089c1a" +git-tree-sha1 = "fe30dec78e68f27fc416901629c6e24e9d5f057b" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.15" -weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "RecipesBase"] +version = "0.22.16" +weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "RecipesBase"] [deps.IntervalArithmetic.extensions] IntervalArithmeticDiffRulesExt = "DiffRules" IntervalArithmeticForwardDiffExt = "ForwardDiff" + IntervalArithmeticIntervalSetsExt = "IntervalSets" + IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" - IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -888,9 +893,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] -git-tree-sha1 = "a0746c21bdc986d0dc293efa6b1faee112c37c28" +git-tree-sha1 = "1dbe274ad1c199490b19a153b60a9e46c5386f8d" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.4.53" +version = "0.5.1" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -918,9 +923,9 @@ version = "3.0.3+0" [[deps.JuliaInterpreter]] deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"] -git-tree-sha1 = "4b415b6cccb9ab61fec78a621572c82ac7fa5776" +git-tree-sha1 = "2984284a8abcfcc4784d95a9e2ea4e352dd8ede7" uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a" -version = "0.9.35" +version = "0.9.36" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] @@ -936,9 +941,9 @@ version = "3.100.2+0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e16271d212accd09d52ee0ae98956b8a05c4b626" +git-tree-sha1 = "78211fb6cbc872f77cad3fc0b6cf647d923f4929" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "17.0.6+0" +version = "18.1.7+0" [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1055,9 +1060,9 @@ uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" [[deps.Literate]] deps = ["Base64", "IOCapture", "JSON", "REPL"] -git-tree-sha1 = "eef2e1fc1dc38af90a18eb16e519e06d1fd10c2a" +git-tree-sha1 = "b9b38448af801760a608b7a7f895f7dcf166f4a5" uuid = "98b081ad-f1c9-55d3-8b20-4c87d4299306" -version = "2.19.0" +version = "2.19.1" [[deps.LiveServer]] deps = ["HTTP", "LoggingExtras", "MIMEs", "Pkg", "Sockets", "Test"] @@ -1092,9 +1097,9 @@ version = "1.0.3" [[deps.LoweredCodeUtils]] deps = ["JuliaInterpreter"] -git-tree-sha1 = "1ce1834f9644a8f7c011eb0592b7fd6c42c90653" +git-tree-sha1 = "c2b5e92eaf5101404a58ce9c6083d595472361d6" uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b" -version = "3.0.1" +version = "3.0.2" [[deps.METIS_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] @@ -1131,16 +1136,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "204f06860af9008fa08b3a4842f48116e1209a2c" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "2281aaf0685e5e8a559982d32f17d617a949b9cd" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.21.9" +version = "0.21.11" [[deps.MakieCore]] deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] -git-tree-sha1 = "b0e2e3473af351011e598f9219afb521121edd2b" +git-tree-sha1 = "22fed09860ca73537a36d4e5a9bce0d9e80ee8a8" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.8.6" +version = "0.8.8" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1219,9 +1224,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" +git-tree-sha1 = "8b72d6806501fd61684dcc6e9c336855acd5abe1" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.1" +version = "0.2.2" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1289,9 +1294,9 @@ version = "1.4.3" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "a028ee3cb5641cccc4c24e90c36b0a4f7707bdf5" +git-tree-sha1 = "1b35263570443fdd9e76c76b7062116e2f374ab8" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.14+0" +version = "3.0.15+0" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1435,10 +1440,10 @@ version = "2.11.0" Enzyme = "7da242da-08ed-463a-9acd-ee780be4f1d9" [[deps.QuantumCollocation]] -deps = ["BenchmarkTools", "CairoMakie", "Distributions", "Einsum", "ExponentialAction", "ForwardDiff", "IJulia", "Ipopt", "JLD2", "Libdl", "LinearAlgebra", "MathOptInterface", "NamedTrajectories", "ProgressMeter", "Random", "Reexport", "SparseArrays", "Symbolics", "TestItemRunner", "TestItems", "TrajectoryIndexingUtils"] +deps = ["BenchmarkTools", "CairoMakie", "Distributions", "Einsum", "ExponentialAction", "ForwardDiff", "IJulia", "Interpolations", "Ipopt", "JLD2", "Libdl", "LinearAlgebra", "MathOptInterface", "NamedTrajectories", "ProgressMeter", "Random", "Reexport", "SparseArrays", "Symbolics", "TestItemRunner", "TestItems", "TrajectoryIndexingUtils"] path = ".." uuid = "0dc23a59-5ffb-49af-b6bd-932a8ae77adf" -version = "0.2.0" +version = "0.2.2" [[deps.REPL]] deps = ["InteractiveUtils", "Markdown", "Sockets", "Unicode"] @@ -1526,15 +1531,15 @@ version = "3.5.18" [[deps.Rmath]] deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4" uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" +version = "0.8.0" [[deps.Rmath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e60724fd3beea548353984dc61c943ecddb0e29a" +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.3+0" +version = "0.5.1+0" [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" @@ -1565,9 +1570,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "8001043f80051c86f264fd6e936d97e6b9eff401" +git-tree-sha1 = "c96f81c3e98d5e2f0848fb42aba4383d772c3bb7" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.52.0" +version = "2.53.1" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1730,9 +1735,9 @@ version = "0.34.3" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +git-tree-sha1 = "b423576adc27097764a90e163157bcfc9acf0f46" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.1" +version = "1.3.2" weakdeps = ["ChainRulesCore", "InverseFunctions"] [deps.StatsFuns.extensions] @@ -1763,9 +1768,9 @@ version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "c9fce29fb41a10677e24f74421ebe31220b81ad0" +git-tree-sha1 = "988e04b34a4c3b824fb656f542473df99a4f610d" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.28" +version = "0.3.30" [[deps.SymbolicLimits]] deps = ["SymbolicUtils"] @@ -1774,27 +1779,29 @@ uuid = "19f23fe9-fdab-4a78-91af-e7b7767979c3" version = "0.2.2" [[deps.SymbolicUtils]] -deps = ["AbstractTrees", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] -git-tree-sha1 = "40b48f4eb06a4bd450c50b4206f7f490556214e1" +deps = ["AbstractTrees", "ArrayInterface", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] +git-tree-sha1 = "635cc663e7913678362a6e34bfab5f9b8feb97c4" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.5.0" +version = "3.7.0" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" + SymbolicUtilsReverseDiffExt = "ReverseDiff" [deps.SymbolicUtils.weakdeps] LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "19a3555ce5d82798b5ab67bdf8b4444d54a159de" +git-tree-sha1 = "2226d810512c678d2ec9c2a9b2e227c2ebc43573" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.5.0" +version = "6.11.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" - SymbolicsLuxCoreExt = "LuxCore" + SymbolicsLuxExt = "Lux" SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1802,7 +1809,7 @@ version = "6.5.0" [deps.Symbolics.weakdeps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" - LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + Lux = "b2108857-7c20-44ae-9111-449ecde12c47" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" @@ -2032,7 +2039,7 @@ version = "0.15.2+0" [[deps.libblastrampoline_jll]] deps = ["Artifacts", "Libdl"] uuid = "8e850b90-86db-534c-a0d3-1478176c7d93" -version = "5.8.0+1" +version = "5.11.0+0" [[deps.libfdk_aac_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] diff --git a/docs/literate/examples/two_qubit_gates.jl b/docs/literate/examples/two_qubit_gates.jl new file mode 100644 index 0000000..c0cb6e0 --- /dev/null +++ b/docs/literate/examples/two_qubit_gates.jl @@ -0,0 +1,201 @@ +# # Two Qubit Gates + +# In this example we will solve for a selection of two-qubit gates using a simple two-qubit system. We will use the [`UnitarySmoothPulseProblem`](@ref) template to solve for the optimal control fields. + +# ## Defining our Hamiltonian + +# In quantum optimal control we work with Hamiltonians of the form + +# ```math +# H(t) = H_{\text{drift}} + \sum_{j} u^j(t) H_{\text{drive}}^j, +# ``` + +# Specifically, for a simple two-qubit system in a rotating frame, we have + +# ```math +# H = J_{12} \sigma_1^x \sigma_2^x + \sum_{i \in {1,2}} a_i^R(t) {\sigma^x_i \over 2} + a_i^I(t) {\sigma^y_i \over 2}. +# ``` + +# where + +# ```math +# \begin{align*} +# J_{12} &= 0.001 \text{ GHz}, \\ +# |a_i^R(t)| &\leq 0.1 \text{ GHz} \\ +# \end{align*} +# ``` + +# And the duration of the gate will be capped at $400 \ \mu s$. + +# Let's now set this up using some of the convenience functions available in QuantumCollocation.jl. + +using QuantumCollocation +using NamedTrajectories +using LinearAlgebra + +## Define our operators +σx = GATES[:X] +σy = GATES[:Y] +Id = GATES[:I] + +## Lift the operators to the two-qubit Hilbert space +σx_1 = σx ⊗ Id +σx_2 = Id ⊗ σx + +σy_1 = σy ⊗ Id +σy_2 = Id ⊗ σy + +## Define the parameters of the Hamiltonian +J_12 = 0.001 # GHz +a_bound = 0.100 # GHz + +## Define the drift (coupling) Hamiltonian +H_drift = J_12 * (σx ⊗ σx) + +## Define the control Hamiltonians +H_drives = [σx_1 / 2, σy_1 / 2, σx_2 / 2, σy_2 / 2] + +## Define control (and higher derivative) bounds +a_bound = 0.1 +da_bound = 0.0005 +dda_bound = 0.0025 + +## Scale the Hamiltonians by 2π +H_drift *= 2π +H_drives .*= 2π + +## Define the time parameters +T = 100 # timesteps +duration = 100 # μs +Δt = duration / T +Δt_max = 400 / T + +## Define the system +sys = QuantumSystem(H_drift, H_drives) + +## Look at max eigenvalue of the generator (for deciding if Pade integrators are viable) +maximum(abs.(eigvals(Δt_max * (H_drift + sum(a_bound .* H_drives))))) + +# That this value above is greater than one means that we must use an exponential integrator for these problems. We can set the kwarg `integrator=:exponential` in `the PiccoloOptions` struct as follows. + +piccolo_options = PiccoloOptions( + integrator=:exponential, +) + +# ## SWAP gate + +## Define the goal operation +U_goal = [ + 1 0 0 0; + 0 0 1 0; + 0 1 0 0; + 0 0 0 1 +] |> Matrix{ComplexF64} + +## Set up and solve the problem + +prob = UnitarySmoothPulseProblem( + sys, + U_goal, + T, + Δt; + a_bound=a_bound, + da_bound=da_bound, + dda_bound=dda_bound, + R_da=0.01, + R_dda=0.01, + Δt_max=Δt_max, + piccolo_options=piccolo_options +) + +solve!(prob; max_iter=100) + +## Let's take a look at the final fidelity +unitary_fidelity(prob) + +# Looks good! + +# Now let's plot the pulse and the population trajectories for the first two columns of the unitary, i.e. initial state of $\ket{00}$ and $\ket{01}$. For this we provide the function [`plot_unitary_populations`](@ref). +plot_unitary_populations(prob) + +# For fun, let's look at a minimum time pulse for this problem + +min_time_prob = UnitaryMinimumTimeProblem(prob; final_fidelity=.99) + +solve!(min_time_prob; max_iter=300) + +unitary_fidelity(min_time_prob) + +# And let's plot this solution +plot_unitary_populations(min_time_prob) + +# It looks like our pulse derivative bounds are holding back the solution, but regardless, the duration has decreased: + +get_duration(prob.trajectory) - get_duration(min_time_prob.trajectory) + + + + +# ## Mølmer–Sørensen gate + +# Here we will solve for a [Mølmer–Sørensen gate](https://en.wikipedia.org/wiki/M%C3%B8lmer%E2%80%93S%C3%B8rensen_gate) between two. The gate is generally described, for N qubits, by the unitary matrix + +# ```math +# U_{\text{MS}}(\vec\theta) = \exp\left(i\sum_{j=1}^{N-1}\sum_{k=j+1}^{N}\theta_{jk}\sigma_j^x\sigma_k^x\right), +# ``` + +# where $\sigma_j^x$ is the Pauli-X operator acting on the $j$-th qubit, and $\vec\theta$ is a vector of real parameters. The Mølmer–Sørensen gate is a two-qubit gate that is particularly well-suited for trapped-ion qubits, where the interaction between qubits is mediated. + +# Here we will focus on the simplest case of a Mølmer–Sørensen gate between two qubits. The gate is described by the unitary matrix + +# ```math +# U_{\text{MS}}\left({\pi \over 4}\right) = \exp\left(i\frac{\pi}{4}\sigma_1^x\sigma_2^x\right). +# ``` + +# Let's set up the problem. + +## Define the goal operation +U_goal = exp(im * π/4 * σx_1 * σx_2) + +## Set up and solve the problem + +prob = UnitarySmoothPulseProblem( + sys, + U_goal, + T, + Δt; + a_bound=a_bound, + da_bound=da_bound, + dda_bound=dda_bound, + R_da=0.01, + R_dda=0.01, + Δt_max=Δt_max, + piccolo_options=piccolo_options +) + +solve!(prob; max_iter=1_000) + +## Let's take a look at the final fidelity +unitary_fidelity(prob) + +# Again, looks good! + +# Now let's plot the pulse and the population trajectories for the first two columns of the unitary, i.e. initial state of $\ket{00}$ and $\ket{01}$. + +plot_unitary_populations(prob) + +# For fun, let's look at a minimum time pulse for this problem + +min_time_prob = UnitaryMinimumTimeProblem(prob; final_fidelity=.999) + +solve!(min_time_prob; max_iter=300) + +unitary_fidelity(min_time_prob) + +# And let's plot this solution + +plot_unitary_populations(min_time_prob) + +# It looks like our pulse derivative bounds are holding back the solution, but regardless, the duration has decreased: + +get_duration(prob.trajectory) - get_duration(min_time_prob.trajectory) diff --git a/docs/make.jl b/docs/make.jl index c2fb7d8..5c7e5b9 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -19,6 +19,7 @@ pages = [ "Embedded Operators" => "generated/man/embedded_operators.md", ], "Examples" => [ + "Two Qubit Gates" => "generated/examples/two_qubit_gates.md", "Multilevel Transmon" => "generated/examples/multilevel_transmon.md", ], "Library" => "lib.md", diff --git a/docs/src/generated/examples/two_qubit_gates.md b/docs/src/generated/examples/two_qubit_gates.md new file mode 100644 index 0000000..da2cdd3 --- /dev/null +++ b/docs/src/generated/examples/two_qubit_gates.md @@ -0,0 +1,233 @@ +```@meta +EditURL = "../../../literate/examples/two_qubit_gates.jl" +``` + +# Two Qubit Gates + +In this example we will solve for a selection of two-qubit gates using a simple two-qubit system. We will use the [`UnitarySmoothPulseProblem`](@ref) template to solve for the optimal control fields. + +## Defining our Hamiltonian + +In quantum optimal control we work with Hamiltonians of the form + +```math +H(t) = H_{\text{drift}} + \sum_{j} u^j(t) H_{\text{drive}}^j, +``` + +Specifically, for a simple two-qubit system in a rotating frame, we have + +```math +H = J_{12} \sigma_1^x \sigma_2^x + \sum_{i \in {1,2}} a_i^R(t) {\sigma^x_i \over 2} + a_i^I(t) {\sigma^y_i \over 2}. +``` + +where + +```math +\begin{align*} +J_{12} &= 0.001 \text{ GHz}, \\ +|a_i^R(t)| &\leq 0.1 \text{ GHz} \\ +\end{align*} +``` + +And the duration of the gate will be capped at $400 \ \mu s$. + +Let's now set this up using some of the convenience functions available in QuantumCollocation.jl. + +````@example two_qubit_gates +using QuantumCollocation +using NamedTrajectories +using LinearAlgebra + +# Define our operators +σx = GATES[:X] +σy = GATES[:Y] +Id = GATES[:I] + +# Lift the operators to the two-qubit Hilbert space +σx_1 = σx ⊗ Id +σx_2 = Id ⊗ σx + +σy_1 = σy ⊗ Id +σy_2 = Id ⊗ σy + +# Define the parameters of the Hamiltonian +J_12 = 0.001 # GHz +a_bound = 0.100 # GHz + +# Define the drift (coupling) Hamiltonian +H_drift = J_12 * (σx ⊗ σx) + +# Define the control Hamiltonians +H_drives = [σx_1 / 2, σy_1 / 2, σx_2 / 2, σy_2 / 2] + +# Define control (and higher derivative) bounds +a_bound = 0.1 +da_bound = 0.0005 +dda_bound = 0.0025 + +# Scale the Hamiltonians by 2π +H_drift *= 2π +H_drives .*= 2π + +# Define the time parameters +T = 100 # timesteps +duration = 100 # μs +Δt = duration / T +Δt_max = 400 / T + +# Define the system +sys = QuantumSystem(H_drift, H_drives) + +# Look at max eigenvalue of the generator (for deciding if Pade integrators are viable) +maximum(abs.(eigvals(Δt_max * (H_drift + sum(a_bound .* H_drives))))) +```` + +That this value above is greater than one means that we must use an exponential integrator for these problems. We can set the kwarg `integrator=:exponential` in `the PiccoloOptions` struct as follows. + +````@example two_qubit_gates +piccolo_options = PiccoloOptions( + integrator=:exponential, +) +```` + +## SWAP gate + +````@example two_qubit_gates +# Define the goal operation +U_goal = [ + 1 0 0 0; + 0 0 1 0; + 0 1 0 0; + 0 0 0 1 +] |> Matrix{ComplexF64} + +# Set up and solve the problem + +prob = UnitarySmoothPulseProblem( + sys, + U_goal, + T, + Δt; + a_bound=a_bound, + da_bound=da_bound, + dda_bound=dda_bound, + R_da=0.01, + R_dda=0.01, + Δt_max=Δt_max, + piccolo_options=piccolo_options +) + +solve!(prob; max_iter=100) + +# Let's take a look at the final fidelity +unitary_fidelity(prob) +```` + +Looks good! + +Now let's plot the pulse and the population trajectories for the first two columns of the unitary, i.e. initial state of $\ket{00}$ and $\ket{01}$. For this we provide the function [`plot_unitary_populations`](@ref). + +````@example two_qubit_gates +plot_unitary_populations(prob) +```` + +For fun, let's look at a minimum time pulse for this problem + +````@example two_qubit_gates +min_time_prob = UnitaryMinimumTimeProblem(prob; final_fidelity=.99) + +solve!(min_time_prob; max_iter=300) + +unitary_fidelity(min_time_prob) +```` + +And let's plot this solution + +````@example two_qubit_gates +plot_unitary_populations(min_time_prob) +```` + +It looks like our pulse derivative bounds are holding back the solution, but regardless, the duration has decreased: + +````@example two_qubit_gates +get_duration(prob.trajectory) - get_duration(min_time_prob.trajectory) +```` + +## Mølmer–Sørensen gate + +Here we will solve for a [Mølmer–Sørensen gate](https://en.wikipedia.org/wiki/M%C3%B8lmer%E2%80%93S%C3%B8rensen_gate) between two. The gate is generally described, for N qubits, by the unitary matrix + +```math +U_{\text{MS}}(\vec\theta) = \exp\left(i\sum_{j=1}^{N-1}\sum_{k=j+1}^{N}\theta_{jk}\sigma_j^x\sigma_k^x\right), +``` + +where $\sigma_j^x$ is the Pauli-X operator acting on the $j$-th qubit, and $\vec\theta$ is a vector of real parameters. The Mølmer–Sørensen gate is a two-qubit gate that is particularly well-suited for trapped-ion qubits, where the interaction between qubits is mediated. + +Here we will focus on the simplest case of a Mølmer–Sørensen gate between two qubits. The gate is described by the unitary matrix + +```math +U_{\text{MS}}\left({\pi \over 4}\right) = \exp\left(i\frac{\pi}{4}\sigma_1^x\sigma_2^x\right). +``` + +Let's set up the problem. + +````@example two_qubit_gates +# Define the goal operation +U_goal = exp(im * π/4 * σx_1 * σx_2) + +# Set up and solve the problem + +prob = UnitarySmoothPulseProblem( + sys, + U_goal, + T, + Δt; + a_bound=a_bound, + da_bound=da_bound, + dda_bound=dda_bound, + R_da=0.01, + R_dda=0.01, + Δt_max=Δt_max, + piccolo_options=piccolo_options +) + +solve!(prob; max_iter=1_000) + +# Let's take a look at the final fidelity +unitary_fidelity(prob) +```` + +Again, looks good! + +Now let's plot the pulse and the population trajectories for the first two columns of the unitary, i.e. initial state of $\ket{00}$ and $\ket{01}$. + +````@example two_qubit_gates +plot_unitary_populations(prob) +```` + +For fun, let's look at a minimum time pulse for this problem + +````@example two_qubit_gates +min_time_prob = UnitaryMinimumTimeProblem(prob; final_fidelity=.999) + +solve!(min_time_prob; max_iter=300) + +unitary_fidelity(min_time_prob) +```` + +And let's plot this solution + +````@example two_qubit_gates +plot_unitary_populations(min_time_prob) +```` + +It looks like our pulse derivative bounds are holding back the solution, but regardless, the duration has decreased: + +````@example two_qubit_gates +get_duration(prob.trajectory) - get_duration(min_time_prob.trajectory) +```` + +--- + +*This page was generated using [Literate.jl](https://github.com/fredrikekre/Literate.jl).* + From 0f5f7e29f9df0fe41317411859840bd381eb23b0 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 15:32:54 -0400 Subject: [PATCH 17/35] cleaning and formatting --- Manifest.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Manifest.toml b/Manifest.toml index dd2de93..ca7fda1 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -774,6 +774,7 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" + IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" From 537f3c0f3cfe6d52c1c697190a9172aaad8e10df Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 30 Sep 2024 16:43:24 -0400 Subject: [PATCH 18/35] mid-refactor save --- Manifest.toml | 91 ++++++++++--------- src/options.jl | 7 -- src/problem_templates/_problem_templates.jl | 10 +- .../unitary_sampling_problem.jl | 42 ++++++--- .../unitary_smooth_pulse_problem.jl | 45 ++++----- src/trajectory_initialization.jl | 53 ++++++----- 6 files changed, 131 insertions(+), 117 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index ca7fda1..de5b92d 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,12 +2,12 @@ julia_version = "1.10.5" manifest_format = "2.0" -project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" +project_hash = "0e1b56171c4e825157ede62be9481fa3374601e7" [[deps.ADTypes]] -git-tree-sha1 = "99a6f5d0ce1c7c6afdb759daa30226f71c54f6b0" +git-tree-sha1 = "5a5eafb8344b81b8c2237f8a6f6b3602b3f6180e" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.7.1" +version = "1.8.1" [deps.ADTypes.extensions] ADTypesChainRulesCoreExt = "ChainRulesCore" @@ -63,24 +63,28 @@ uuid = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" version = "0.4.5" [[deps.Accessors]] -deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown", "Test"] -git-tree-sha1 = "f61b15be1d76846c0ce31d3fcfac5380ae53db6a" +deps = ["CompositionsBase", "ConstructionBase", "InverseFunctions", "LinearAlgebra", "MacroTools", "Markdown"] +git-tree-sha1 = "b392ede862e506d451fc1616e79aa6f4c673dab8" uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" -version = "0.1.37" +version = "0.1.38" [deps.Accessors.extensions] AccessorsAxisKeysExt = "AxisKeys" + AccessorsDatesExt = "Dates" AccessorsIntervalSetsExt = "IntervalSets" AccessorsStaticArraysExt = "StaticArrays" AccessorsStructArraysExt = "StructArrays" + AccessorsTestExt = "Test" AccessorsUnitfulExt = "Unitful" [deps.Accessors.weakdeps] AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5" + Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953" Requires = "ae029012-a4dd-5104-9daa-d747884805df" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" + Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d" [[deps.Adapt]] @@ -94,9 +98,9 @@ weakdeps = ["StaticArrays"] AdaptStaticArraysExt = "StaticArrays" [[deps.AdaptivePredicates]] -git-tree-sha1 = "7d5da5dd472490d048b081ca1bda4a7821b06456" +git-tree-sha1 = "7e651ea8d262d2d74ce75fdf47c4d63c07dba7a6" uuid = "35492f91-a3bd-45ad-95db-fcad7dcfedb7" -version = "1.1.1" +version = "1.2.0" [[deps.AliasTables]] deps = ["PtrArrays", "Random"] @@ -207,9 +211,9 @@ version = "1.1.0" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "361dec06290d76b6d70d0c7dc888038eec9df63a" +git-tree-sha1 = "4f827b38d3d9ffe6e3b01fbcf866c625fa259ca5" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.12.9" +version = "0.12.11" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] @@ -219,9 +223,9 @@ version = "1.18.0+2" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] -git-tree-sha1 = "71acdbf594aab5bbb2cec89b208c41b4c411e49f" +git-tree-sha1 = "3e4b134270b372f2ed4d4d0e936aabaefc1802bc" uuid = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" -version = "1.24.0" +version = "1.25.0" weakdeps = ["SparseArrays"] [deps.ChainRulesCore.extensions] @@ -367,9 +371,9 @@ uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "9903123ab7fc5e55053292aff04ff5d7aff92633" +git-tree-sha1 = "94eb20e6621600f4315813b1d1fc9b8a5a6a34db" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.3.0" +version = "1.4.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -774,7 +778,6 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" - IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -788,9 +791,9 @@ weakdeps = ["Random", "RecipesBase", "Statistics"] IntervalSetsStatisticsExt = "Statistics" [[deps.InverseFunctions]] -git-tree-sha1 = "2787db24f4e03daf859c6509ff87764e4182f7d1" +git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb" uuid = "3587e190-3f89-42d0-90ee-14403ec27112" -version = "0.1.16" +version = "0.1.17" weakdeps = ["Dates", "Test"] [deps.InverseFunctions.extensions] @@ -832,9 +835,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] -git-tree-sha1 = "1dbe274ad1c199490b19a153b60a9e46c5386f8d" +git-tree-sha1 = "07f9dec43deef049c2f0daa96f67bfc0baa20a17" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.1" +version = "0.5.3" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -874,9 +877,9 @@ version = "3.100.2+0" [[deps.LLVMOpenMP_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e16271d212accd09d52ee0ae98956b8a05c4b626" +git-tree-sha1 = "78211fb6cbc872f77cad3fc0b6cf647d923f4929" uuid = "1d63c593-3942-5779-bab2-d838dc0a180e" -version = "17.0.6+0" +version = "18.1.7+0" [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] @@ -1035,16 +1038,16 @@ uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09" version = "0.5.13" [[deps.Makie]] -deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageIO", "InteractiveUtils", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "204f06860af9008fa08b3a4842f48116e1209a2c" +deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] +git-tree-sha1 = "2281aaf0685e5e8a559982d32f17d617a949b9cd" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.21.9" +version = "0.21.11" [[deps.MakieCore]] deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] -git-tree-sha1 = "b0e2e3473af351011e598f9219afb521121edd2b" +git-tree-sha1 = "22fed09860ca73537a36d4e5a9bce0d9e80ee8a8" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.8.6" +version = "0.8.8" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1181,9 +1184,9 @@ version = "0.8.1+2" [[deps.OpenSSL_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "1b35263570443fdd9e76c76b7062116e2f374ab8" +git-tree-sha1 = "7493f61f55a6cce7325f197443aa80d32554ba10" uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95" -version = "3.0.15+0" +version = "3.0.15+1" [[deps.OpenSpecFun_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl", "Pkg"] @@ -1316,9 +1319,9 @@ version = "1.0.0" [[deps.QuadGK]] deps = ["DataStructures", "LinearAlgebra"] -git-tree-sha1 = "1d587203cf851a51bf1ea31ad7ff89eff8d625ea" +git-tree-sha1 = "cda3b045cf9ef07a08ad46731f5a3165e56cf3da" uuid = "1fd47b50-473d-5c70-9696-f719f8f3bcdc" -version = "2.11.0" +version = "2.11.1" [deps.QuadGK.extensions] QuadGKEnzymeExt = "Enzyme" @@ -1400,15 +1403,15 @@ version = "1.3.0" [[deps.Rmath]] deps = ["Random", "Rmath_jll"] -git-tree-sha1 = "f65dcb5fa46aee0cf9ed6274ccbd597adc49aa7b" +git-tree-sha1 = "852bd0f55565a9e973fcfee83a84413270224dc4" uuid = "79098fc4-a85e-5d69-aa6a-4863f24498fa" -version = "0.7.1" +version = "0.8.0" [[deps.Rmath_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "e60724fd3beea548353984dc61c943ecddb0e29a" +git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8" uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f" -version = "0.4.3+0" +version = "0.5.1+0" [[deps.RoundingEmulator]] git-tree-sha1 = "40b9edad2e5287e05bd413a38f61a8ff55b9557b" @@ -1427,9 +1430,9 @@ version = "0.7.0" [[deps.SIMD]] deps = ["PrecompileTools"] -git-tree-sha1 = "2803cab51702db743f3fda07dd1745aadfbf43bd" +git-tree-sha1 = "98ca7c29edd6fc79cd74c61accb7010a4e7aee33" uuid = "fdea26ae-647d-5447-a871-4b548cad5224" -version = "3.5.0" +version = "3.6.0" [[deps.SPRAL_jll]] deps = ["Artifacts", "CompilerSupportLibraries_jll", "Hwloc_jll", "JLLWrappers", "Libdl", "METIS_jll", "libblastrampoline_jll"] @@ -1439,9 +1442,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "303a73db99326a8be43e695fbab9e076b02118ca" +git-tree-sha1 = "71857d6bab17e7ac6802d86ffcc75423b8c1d812" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.52.2" +version = "2.54.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1599,9 +1602,9 @@ version = "0.34.3" [[deps.StatsFuns]] deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"] -git-tree-sha1 = "cef0472124fab0695b58ca35a77c6fb942fdab8a" +git-tree-sha1 = "b423576adc27097764a90e163157bcfc9acf0f46" uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c" -version = "1.3.1" +version = "1.3.2" weakdeps = ["ChainRulesCore", "InverseFunctions"] [deps.StatsFuns.extensions] @@ -1644,9 +1647,9 @@ version = "0.2.2" [[deps.SymbolicUtils]] deps = ["AbstractTrees", "ArrayInterface", "Bijections", "ChainRulesCore", "Combinatorics", "ConstructionBase", "DataStructures", "DocStringExtensions", "DynamicPolynomials", "IfElse", "LinearAlgebra", "MultivariatePolynomials", "NaNMath", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArrays", "SymbolicIndexingInterface", "TermInterface", "TimerOutputs", "Unityper"] -git-tree-sha1 = "9d983078d9e99421fcca44c373e4304b8421fdde" +git-tree-sha1 = "3927e02dc7648a45ec6aa592bcd8374094a44740" uuid = "d1185830-fcd6-423d-90d6-eec64667417b" -version = "3.6.0" +version = "3.7.1" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" @@ -1658,9 +1661,9 @@ version = "3.6.0" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "2226d810512c678d2ec9c2a9b2e227c2ebc43573" +git-tree-sha1 = "8b48697e7fec6d4b7c4a9fe892857a5ed2bae7e8" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.11.0" +version = "6.12.0" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" diff --git a/src/options.jl b/src/options.jl index 18a13a9..39fe0f5 100644 --- a/src/options.jl +++ b/src/options.jl @@ -58,11 +58,6 @@ end Solver settings for Quantum Collocation. """ @kwdef mutable struct PiccoloOptions <: AbstractOptions - # TODO: return names to problem templates - state_type::Symbol = :unitary - state_name::Symbol = :Ũ⃗ - control_name::Symbol = :a - timestep_name::Symbol = :Δt verbose::Bool = true verbose_evaluator::Bool = false free_time::Bool = true @@ -85,8 +80,6 @@ end phase_name::Symbol = :ϕ end -⊗ - function set!(optimizer::Ipopt.Optimizer, options::AbstractOptions) for name in fieldnames(typeof(options)) value = getfield(options, name) diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index 9588f5b..d509394 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -38,13 +38,15 @@ function apply_piccolo_options!( J::Objective, constraints::AbstractVector{<:AbstractConstraint}, piccolo_options::PiccoloOptions, - traj::NamedTrajectory; - operator::Union{Nothing, OperatorType}=nothing + traj::NamedTrajectory, + operator::OperatorType, + state_name::Symbol, + timestep_name::Symbol ) if piccolo_options.leakage_suppression state_names = [ name for name ∈ traj.names - if startswith(string(name), string(piccolo_options.state_name)) + if startswith(string(name), string(state_name)) ] if operator isa EmbeddedOperator @@ -68,7 +70,7 @@ function apply_piccolo_options!( if piccolo_options.timesteps_all_equal push!( constraints, - TimeStepsAllEqualConstraint(piccolo_options.timestep_name, traj) + TimeStepsAllEqualConstraint(timestep_name, traj) ) end end diff --git a/src/problem_templates/unitary_sampling_problem.jl b/src/problem_templates/unitary_sampling_problem.jl index 5fd8653..014a17d 100644 --- a/src/problem_templates/unitary_sampling_problem.jl +++ b/src/problem_templates/unitary_sampling_problem.jl @@ -53,6 +53,9 @@ function UnitarySamplingProblem( init_trajectory::Union{NamedTrajectory, Nothing}=nothing, ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), + state_name::Symbol = :Ũ⃗, + control_name::Symbol = :a, + timestep_name::Symbol = :Δt, constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], a_bound::Float64=1.0, a_bounds=fill(a_bound, length(systems[1].G_drives)), @@ -72,19 +75,23 @@ function UnitarySamplingProblem( kwargs... ) # Create keys for multiple systems - Ũ⃗_keys = [add_suffix(:Ũ⃗, ℓ) for ℓ ∈ system_labels] + Ũ⃗_names = [add_suffix(state_name, ℓ) for ℓ ∈ system_labels] # Trajectory if !isnothing(init_trajectory) traj = init_trajectory else n_drives = length(systems[1].G_drives) + traj = initialize_unitary_trajectory( operator, T, Δt, n_drives, - (a = a_bounds, da = da_bounds, dda = dda_bounds); + (a_bounds, da_bounds, dda_bounds); + state_name=state_name, + control_name=control_name, + timestep_name=timestep_name, free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, @@ -93,29 +100,34 @@ function UnitarySamplingProblem( a_guess=a_guess, system=systems, rollout_integrator=piccolo_options.rollout_integrator, - Ũ⃗_keys=Ũ⃗_keys + Ũ⃗_names=Ũ⃗_names ) end + control_names = [ + name for name ∈ traj.names + if endswith(string(name), string(control_name)) + ] + # Objective J = NullObjective() - for (wᵢ, Ũ⃗_key) in zip(system_weights, Ũ⃗_keys) + for (wᵢ, Ũ⃗_name) in zip(system_weights, Ũ⃗_names) J += wᵢ * UnitaryInfidelityObjective( - Ũ⃗_key, traj, Q; + Ũ⃗_name, traj, Q; subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing ) end - J += QuadraticRegularizer(:a, traj, R_a) - J += QuadraticRegularizer(:da, traj, R_da) - J += QuadraticRegularizer(:dda, traj, R_dda) + J += QuadraticRegularizer(control_names[1], traj, R_a) + J += QuadraticRegularizer(control_names[2], traj, R_da) + J += QuadraticRegularizer(control_names[3], traj, R_dda) # Constraints if piccolo_options.leakage_suppression if operator isa EmbeddedOperator leakage_indices = get_iso_vec_leakage_indices(operator) - for Ũ⃗_key in Ũ⃗_keys + for Ũ⃗_name in Ũ⃗_names J += L1Regularizer!( - constraints, Ũ⃗_key, traj, + constraints, Ũ⃗_name, traj, R_value=piccolo_options.R_leakage, indices=leakage_indices, eval_hessian=piccolo_options.eval_hessian @@ -143,16 +155,16 @@ function UnitarySamplingProblem( # Integrators unitary_integrators = AbstractIntegrator[] - for (sys, Ũ⃗_key) in zip(systems, Ũ⃗_keys) + for (sys, Ũ⃗_name) in zip(systems, Ũ⃗_names) if piccolo_options.integrator == :pade push!( unitary_integrators, - UnitaryPadeIntegrator(sys, Ũ⃗_key, :a, traj; order=piccolo_options.pade_order) + UnitaryPadeIntegrator(sys, Ũ⃗_name, control_name, traj; order=piccolo_options.pade_order) ) elseif piccolo_options.integrator == :exponential push!( unitary_integrators, - UnitaryExponentialIntegrator(sys, Ũ⃗_key, :a, traj) + UnitaryExponentialIntegrator(sys, Ũ⃗_name, control_name, traj) ) else error("integrator must be one of (:pade, :exponential)") @@ -161,8 +173,8 @@ function UnitarySamplingProblem( integrators = [ unitary_integrators..., - DerivativeIntegrator(:a, :da, traj), - DerivativeIntegrator(:da, :dda, traj), + DerivativeIntegrator(control_name, control_names[2], traj), + DerivativeIntegrator(control_names[w], control_names[3], traj), ] return QuantumControlProblem( diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index f059ae9..52beffb 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -77,6 +77,10 @@ function UnitarySmoothPulseProblem( Δt::Union{Float64, Vector{Float64}}; ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), + state_type::Symbol = :unitary, + state_name::Symbol = :Ũ⃗, + control_name::Symbol = :a, + timestep_name::Symbol = :Δt, init_trajectory::Union{NamedTrajectory, Nothing}=nothing, a_bound::Float64=1.0, a_bounds=fill(a_bound, length(system.G_drives)), @@ -98,36 +102,22 @@ function UnitarySmoothPulseProblem( kwargs... ) - state_name = piccolo_options.state_name - control_name = piccolo_options.control_name - control_velocity_name = Symbol(string("d", control_name)) - control_acceleration_name = Symbol(string("dd", control_name)) - timestep_name = piccolo_options.timestep_name - # Trajectory if !isnothing(init_trajectory) traj = init_trajectory else n_drives = length(system.G_drives) - control_bound_names = ( - control_name, # a - control_velocity_name, # da - control_acceleration_name # dda - ) - - control_bounds = NamedTuple{control_bound_names}(( - a_bounds, - da_bounds, - dda_bounds - )) - traj = initialize_unitary_trajectory( operator, T, Δt, n_drives, - control_bounds; + (a_bounds, da_bounds, dda_bounds); + n_derivatives=2, + state_name=state_name, + control_name=control_name, + timestep_name=timestep_name, free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, @@ -162,9 +152,14 @@ function UnitarySmoothPulseProblem( ) end - J += QuadraticRegularizer(control_bound_names[1], traj, R_a) - J += QuadraticRegularizer(control_bound_names[2], traj, R_da) - J += QuadraticRegularizer(control_bound_names[3], traj, R_dda) + control_names = [ + name for name ∈ traj.names + if endswith(string(name), string(control_name)) + ] + + J += QuadraticRegularizer(control_names[1], traj, R_a) + J += QuadraticRegularizer(control_names[2], traj, R_da) + J += QuadraticRegularizer(control_names[3], traj, R_dda) # Integrators if piccolo_options.integrator == :pade @@ -181,12 +176,12 @@ function UnitarySmoothPulseProblem( integrators = [ unitary_integrator, - DerivativeIntegrator(control_name, control_velocity_name, traj), - DerivativeIntegrator(control_velocity_name, control_acceleration_name, traj), + DerivativeIntegrator(control_name, control_names[2], traj), + DerivativeIntegrator(control_names[2], control_names[3], traj), ] # Optional Piccolo constraints and objectives - apply_piccolo_options!(J, constraints, piccolo_options, traj, operator) + apply_piccolo_options!(J, constraints, piccolo_options, traj, operator, state_name, timestep_name) return QuantumControlProblem( system, diff --git a/src/trajectory_initialization.jl b/src/trajectory_initialization.jl index 32f3c56..94cb8ac 100644 --- a/src/trajectory_initialization.jl +++ b/src/trajectory_initialization.jl @@ -250,9 +250,12 @@ function initialize_unitary_trajectory( T::Int, Δt::Union{Float64, AbstractVecOrMat{<:Float64}}, n_drives::Int, - all_a_bounds::NamedTuple{anames, <:Tuple{Vararg{VectorBound}}} where anames; + control_bounds::Tuple{Vararg{VectorBound}}; + state_name=:Ũ⃗, + control_name=:a, + timestep_name=:Δt, U_init::AbstractMatrix{<:Number}=Matrix{ComplexF64}(I(size(U_goal, 1))), - n_derivatives::Int=2, + n_derivatives::Int=0, geodesic=true, bound_unitary=false, free_time=false, @@ -262,10 +265,16 @@ function initialize_unitary_trajectory( system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, global_data::Union{NamedTuple, Nothing}=nothing, rollout_integrator::Function=expv, - Ũ⃗_keys::AbstractVector{<:Symbol}=[:Ũ⃗], - a_keys::AbstractVector{<:Symbol}=[Symbol("d"^i * "a") for i in 0:n_derivatives] + state_names::AbstractVector{<:Symbol}=[state_name], ) - @assert length(a_keys) == n_derivatives + 1 "a_keys must have the same length as n_derivatives + 1" + control_derivative_names = [ + Symbol("d"^i * string(control_name)) + for i = 1:n_derivatives + ] + + control_names = (control_name, control_derivative_names...) + + control_bounds = NamedTuple{control_names}(control_bounds) if free_time if Δt isa Real @@ -275,7 +284,7 @@ function initialize_unitary_trajectory( else @assert size(Δt) == (1, T) "Δt must be a Real, AbstractVector, or 1x$(T) AbstractMatrix" end - timestep = :Δt + timestep = timestep_name else @assert Δt isa Real "Δt must be a Real if free_time is false" timestep = Δt @@ -289,9 +298,9 @@ function initialize_unitary_trajectory( end # Constraints - Ũ⃗_inits = repeat([Ũ⃗_init], length(Ũ⃗_keys)) + Ũ⃗_inits = repeat([Ũ⃗_init], length(state_names)) initial = (; - (Ũ⃗_keys .=> Ũ⃗_inits)..., + (state_names .=> Ũ⃗_inits)..., a = zeros(n_drives), ) @@ -299,27 +308,27 @@ function initialize_unitary_trajectory( a = zeros(n_drives), ) - Ũ⃗_goals = repeat([Ũ⃗_goal], length(Ũ⃗_keys)) - goal = (; (Ũ⃗_keys .=> Ũ⃗_goals)...) + Ũ⃗_goals = repeat([Ũ⃗_goal], length(state_names)) + goal = (; (state_names .=> Ũ⃗_goals)...) # Bounds - bounds = all_a_bounds + bounds = control_bounds if bound_unitary Ũ⃗_dim = length(Ũ⃗_init) - Ũ⃗_bounds = repeat([(-ones(Ũ⃗_dim), ones(Ũ⃗_dim))], length(Ũ⃗_keys)) - bounds = merge(bounds, (; (Ũ⃗_keys .=> Ũ⃗_bounds)...)) + Ũ⃗_bounds = repeat([(-ones(Ũ⃗_dim), ones(Ũ⃗_dim))], length(state_names)) + bounds = merge(bounds, (; (state_names .=> Ũ⃗_bounds)...)) end # Initial state and control values if isnothing(a_guess) Ũ⃗ = initialize_unitaries(U_init, U_goal, T, geodesic=geodesic) - Ũ⃗_values = repeat([Ũ⃗], length(Ũ⃗_keys)) + Ũ⃗_values = repeat([Ũ⃗], length(state_names)) a_values = initialize_controls( n_drives, n_derivatives, T, - bounds[a_keys[1]], + bounds[control_name], drive_derivative_σ ) else @@ -336,33 +345,33 @@ function initialize_unitary_trajectory( end if system isa AbstractVector - @assert length(system) == length(Ũ⃗_keys) "systems must have the same length as Ũ⃗_keys" + @assert length(system) == length(state_names) "systems must have the same length as state_names" Ũ⃗_values = map(system) do sys unitary_rollout(Ũ⃗_init, a_guess, ts, sys; integrator=rollout_integrator) end else Ũ⃗ = unitary_rollout(Ũ⃗_init, a_guess, ts, system; integrator=rollout_integrator) - Ũ⃗_values = repeat([Ũ⃗], length(Ũ⃗_keys)) + Ũ⃗_values = repeat([Ũ⃗], length(state_names)) end Ũ⃗_values = Matrix{Float64}.(Ũ⃗_values) a_values = initialize_controls(a_guess, ts, n_derivatives) end # Trajectory - keys = [Ũ⃗_keys..., a_keys...] + names = [state_names..., control_names...] values = [Ũ⃗_values..., a_values...] if free_time - push!(keys, :Δt) + push!(names, timestep_name) push!(values, Δt) - controls = (a_keys[end], :Δt) + controls = (control_names[end], :Δt) bounds = merge(bounds, (Δt = Δt_bounds,)) else - controls = (a_keys[end],) + controls = (control_names[end],) end return NamedTrajectory( - (; (keys .=> values)...); + (; (names .=> values)...); controls=controls, timestep=timestep, bounds=bounds, From be7d0f4f6d040aefbc0dce88bc276562dc1adc45 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Fri, 4 Oct 2024 16:30:53 -0400 Subject: [PATCH 19/35] rafactor to initialization code --- .../quantum_state_minimum_time_problem.jl | 4 +- .../quantum_state_smooth_pulse_problem.jl | 50 ++- .../unitary_bang_bang_problem.jl | 108 +++--- .../unitary_direct_sum_problem.jl | 34 +- .../unitary_minimum_time_problem.jl | 28 +- .../unitary_robustness_problem.jl | 25 +- .../unitary_sampling_problem.jl | 89 +++-- .../unitary_smooth_pulse_problem.jl | 31 +- src/rollouts.jl | 20 +- src/trajectory_initialization.jl | 367 +++++++++++++----- 10 files changed, 457 insertions(+), 299 deletions(-) diff --git a/src/problem_templates/quantum_state_minimum_time_problem.jl b/src/problem_templates/quantum_state_minimum_time_problem.jl index d3b0fcf..ad28461 100644 --- a/src/problem_templates/quantum_state_minimum_time_problem.jl +++ b/src/problem_templates/quantum_state_minimum_time_problem.jl @@ -87,8 +87,8 @@ end T = 50 Δt = 0.2 sys = QuantumSystem(0.1 * GATES[:Z], [GATES[:X], GATES[:Y]]) - ψ_init = [1.0, 0.0] - ψ_target = [0.0, 1.0] + ψ_init = Vector{ComplexF64}([1.0, 0.0]) + ψ_target = Vector{ComplexF64}([0.0, 1.0]) prob = QuantumStateSmoothPulseProblem( sys, ψ_init, ψ_target, T, Δt; diff --git a/src/problem_templates/quantum_state_smooth_pulse_problem.jl b/src/problem_templates/quantum_state_smooth_pulse_problem.jl index b3fa761..6e94845 100644 --- a/src/problem_templates/quantum_state_smooth_pulse_problem.jl +++ b/src/problem_templates/quantum_state_smooth_pulse_problem.jl @@ -26,8 +26,8 @@ function QuantumStateSmoothPulseProblem end function QuantumStateSmoothPulseProblem( system::AbstractQuantumSystem, - ψ_init::Union{AbstractVector{<:Number}, Vector{<:AbstractVector{<:Number}}}, - ψ_goal::Union{AbstractVector{<:Number}, Vector{<:AbstractVector{<:Number}}}, + ψ_init::Union{AbstractVector{<:ComplexF64}, Vector{<:AbstractVector{<:ComplexF64}}}, + ψ_goal::Union{AbstractVector{<:ComplexF64}, Vector{<:AbstractVector{<:ComplexF64}}}, T::Int, Δt::Float64; ipopt_options::IpoptOptions=IpoptOptions(), @@ -74,13 +74,13 @@ function QuantumStateSmoothPulseProblem( if !isnothing(init_trajectory) traj = init_trajectory else - traj = initialize_quantum_state_trajectory( - ψ̃_goals, - ψ̃_inits, + traj = initialize_trajectory( + ψ_goals, + ψ_inits, T, Δt, n_drives, - (a = a_bounds, da = da_bounds, dda = dda_bounds); + (a_bounds, da_bounds, dda_bounds); free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), drive_derivative_σ=drive_derivative_σ, @@ -95,8 +95,12 @@ function QuantumStateSmoothPulseProblem( J += QuadraticRegularizer(:da, traj, R_da) J += QuadraticRegularizer(:dda, traj, R_dda) - for i = 1:length(ψ_inits) - J += QuantumStateObjective(Symbol("ψ̃$i"), traj, Q) + if length(ψ_inits) == 1 + J += QuantumStateObjective(:ψ̃, traj, Q) + else + for i = 1:length(ψ_inits) + J += QuantumStateObjective(Symbol("ψ̃$i"), traj, Q) + end end # Constraints @@ -124,10 +128,16 @@ function QuantumStateSmoothPulseProblem( end # Integrators - ψ̃_integrators = [ - QuantumStatePadeIntegrator(system, Symbol("ψ̃$i"), :a, traj) - for i = 1:length(ψ_inits) - ] + if length(ψ_inits) == 1 + ψ̃_integrators = [ + QuantumStatePadeIntegrator(system, :ψ̃, :a, traj) + ] + else + ψ̃_integrators = [ + QuantumStatePadeIntegrator(system, Symbol("ψ̃$i"), :a, traj) + for i = 1:length(ψ_inits) + ] + end integrators = [ ψ̃_integrators..., @@ -164,8 +174,8 @@ end T = 50 Δt = 0.2 sys = QuantumSystem(0.1 * GATES[:Z], [GATES[:X], GATES[:Y]]) - ψ_init = [1.0, 0.0] - ψ_target = [0.0, 1.0] + ψ_init = Vector{ComplexF64}([1.0, 0.0]) + ψ_target = Vector{ComplexF64}([0.0, 1.0]) # Single initial and target states # -------------------------------- @@ -181,8 +191,8 @@ end # Multiple initial and target states # ---------------------------------- - ψ_inits = [[1.0, 0.0], [0.0, 1.0]] - ψ_targets = [[0.0, 1.0], [1.0, 0.0]] + ψ_inits = Vector{ComplexF64}.([[1.0, 0.0], [0.0, 1.0]]) + ψ_targets = Vector{ComplexF64}.([[0.0, 1.0], [1.0, 0.0]]) prob = QuantumStateSmoothPulseProblem( sys, ψ_inits, ψ_targets, T, Δt; ipopt_options=IpoptOptions(print_level=1), @@ -199,8 +209,8 @@ end T = 50 Δt = 0.2 sys = QuantumSystem(0.1 * GATES[:Z], [GATES[:X], GATES[:Y]]) - ψ_init = [1.0, 0.0] - ψ_target = [0.0, 1.0] + ψ_init = Vector{ComplexF64}([1.0, 0.0]) + ψ_target = Vector{ComplexF64}([0.0, 1.0]) integrator=:exponential # Single initial and target states @@ -217,8 +227,8 @@ end # Multiple initial and target states # ---------------------------------- - ψ_inits = [[1.0, 0.0], [0.0, 1.0]] - ψ_targets = [[0.0, 1.0], [1.0, 0.0]] + ψ_inits = Vector{ComplexF64}.([[1.0, 0.0], [0.0, 1.0]]) + ψ_targets = Vector{ComplexF64}.([[0.0, 1.0], [1.0, 0.0]]) prob = QuantumStateSmoothPulseProblem( sys, ψ_inits, ψ_targets, T, Δt; ipopt_options=IpoptOptions(print_level=1), diff --git a/src/problem_templates/unitary_bang_bang_problem.jl b/src/problem_templates/unitary_bang_bang_problem.jl index f3de265..d0e2d8d 100644 --- a/src/problem_templates/unitary_bang_bang_problem.jl +++ b/src/problem_templates/unitary_bang_bang_problem.jl @@ -60,7 +60,7 @@ with - `R_bang_bang::Union{Float64, Vector{Float64}}=1.0`: the weight on the bang-bang regularization term - `leakage_suppression::Bool=false`: whether or not to suppress leakage to higher energy states - `R_leakage=1e-1`: the weight on the leakage suppression term -- `bound_unitary=integrator == :exponential`: whether or not to bound the unitary +- `bound_state=integrator == :exponential`: whether or not to bound the unitary - `control_norm_constraint=false`: whether or not to enforce a constraint on the control pulse norm - `control_norm_constraint_components=nothing`: the components of the control pulse to use for the norm constraint - `control_norm_R=nothing`: the weight on the control pulse norm constraint @@ -76,7 +76,9 @@ function UnitaryBangBangProblem( Δt::Union{Float64, Vector{Float64}}; ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), - constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], + state_name::Symbol = :Ũ⃗, + control_name::Symbol = :a, + timestep_name::Symbol = :Δt, init_trajectory::Union{NamedTrajectory, Nothing}=nothing, a_bound::Float64=1.0, a_bounds=fill(a_bound, length(system.G_drives)), @@ -91,13 +93,8 @@ function UnitaryBangBangProblem( R_a::Union{Float64, Vector{Float64}}=R, R_da::Union{Float64, Vector{Float64}}=R, R_bang_bang::Union{Float64, Vector{Float64}}=1e-1, - leakage_suppression=false, - R_leakage=1e-1, - control_norm_constraint=false, - control_norm_constraint_components=nothing, - control_norm_R=nothing, - bound_unitary=piccolo_options.integrator == :exponential, global_data::Union{NamedTuple, Nothing}=nothing, + constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], kwargs... ) # Trajectory @@ -105,17 +102,19 @@ function UnitaryBangBangProblem( traj = init_trajectory else n_drives = length(system.G_drives) - traj = initialize_unitary_trajectory( + traj = initialize_trajectory( operator, T, Δt, n_drives, - (a = a_bounds, da = da_bounds); - n_derivatives=1, + (a_bounds, da_bounds); + state_name=state_name, + control_name=control_name, + timestep_name=timestep_name, free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, - bound_unitary=bound_unitary, + bound_state=piccolo_options.bound_state, drive_derivative_σ=drive_derivative_σ, a_guess=a_guess, system=system, @@ -126,81 +125,60 @@ function UnitaryBangBangProblem( # Objective if isnothing(global_data) - J = UnitaryInfidelityObjective(:Ũ⃗, traj, Q; + J = UnitaryInfidelityObjective(state_name, traj, Q; subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing, ) else # TODO: remove hardcoded args J = UnitaryFreePhaseInfidelityObjective( - name=:Ũ⃗, - phase_name=:ϕ, - goal=operator_to_iso_vec(operator isa EmbeddedOperator ? operator.operator : operator), - phase_operators=[GATES[:Z] for _ in eachindex(traj.global_components[:ϕ])], + name=state_name, + phase_name=piccolo_options.phase_name, + goal=operator_to_iso_vec( + operator isa EmbeddedOperator ? operator.operator : operator + ), + phase_operators=[GATES[:Z] for _ in eachindex(traj.global_components[:piccolo_options.phase_name])], Q=Q, eval_hessian=piccolo_options.eval_hessian, subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing ) end - J += QuadraticRegularizer(:a, traj, R_a) - J += QuadraticRegularizer(:da, traj, R_da) + + control_names = [ + name for name ∈ traj.names + if endswith(string(name), string(control_name)) + ] + + J += QuadraticRegularizer(control_names[1], traj, R_a) + J += QuadraticRegularizer(control_names[2], traj, R_da) # Constraints if R_bang_bang isa Float64 R_bang_bang = fill(R_bang_bang, length(system.G_drives)) end J += L1Regularizer!( - constraints, :da, traj, + constraints, control_names[2], traj, R=R_bang_bang, eval_hessian=piccolo_options.eval_hessian ) - if leakage_suppression - if operator isa EmbeddedOperator - leakage_indices = get_iso_vec_leakage_indices(operator) - J += L1Regularizer!( - constraints, :Ũ⃗, traj, - R_value=R_leakage, - indices=leakage_indices, - eval_hessian=piccolo_options.eval_hessian - ) - else - @warn "leakage_suppression is not supported for non-embedded operators, ignoring." - end - end - - if piccolo_options.free_time - if piccolo_options.timesteps_all_equal - push!(constraints, TimeStepsAllEqualConstraint(:Δt, traj)) - end - end - - if control_norm_constraint - @assert !isnothing(control_norm_constraint_components) "control_norm_constraint_components must be provided" - @assert !isnothing(control_norm_R) "control_norm_R must be provided" - norm_con = ComplexModulusContraint( - :a, - control_norm_R, - traj; - name_comps=control_norm_constraint_components, - ) - push!(constraints, norm_con) - end - # Integrators if piccolo_options.integrator == :pade unitary_integrator = - UnitaryPadeIntegrator(system, :Ũ⃗, :a, traj; order=piccolo_options.pade_order) + UnitaryPadeIntegrator(system, state_name, control_names[1], traj; order=piccolo_options.pade_order) elseif piccolo_options.integrator == :exponential unitary_integrator = - UnitaryExponentialIntegrator(system, :Ũ⃗, :a, traj) + UnitaryExponentialIntegrator(system, state_name, control_names[1], traj) else error("integrator must be one of (:pade, :exponential)") end integrators = [ unitary_integrator, - DerivativeIntegrator(:a, :da, traj), + DerivativeIntegrator(control_names[1], control_names[2], traj), ] + # Optional Piccolo constraints and objectives + apply_piccolo_options!(J, constraints, piccolo_options, traj, operator, state_name, timestep_name) + return QuantumControlProblem( system, traj, @@ -245,25 +223,29 @@ end Δt = 0.2 ipopt_options = IpoptOptions(print_level=1, max_iter=25) - piccolo_options = PiccoloOptions(verbose=false) + piccolo_options = PiccoloOptions(verbose=false, pade_order=12) prob = UnitaryBangBangProblem( sys, U_goal, T, Δt, R_bang_bang=10., - ipopt_options=ipopt_options, piccolo_options=piccolo_options + ipopt_options=ipopt_options, + piccolo_options=piccolo_options, + control_name=:u ) smooth_prob = UnitarySmoothPulseProblem( - sys, U_goal, T, Δt, - ipopt_options=ipopt_options, piccolo_options=piccolo_options + sys, U_goal, T, Δt; + ipopt_options=ipopt_options, + piccolo_options=piccolo_options, + control_name=:u ) - initial = unitary_fidelity(prob) + initial = unitary_fidelity(prob; drive_name=:u) solve!(prob) - final = unitary_fidelity(prob) + final = unitary_fidelity(prob; drive_name=:u) @test final > initial solve!(smooth_prob) threshold = 1e-3 - a_sparse = sum(prob.trajectory.da .> 5e-2) - a_dense = sum(smooth_prob.trajectory.da .> 5e-2) + a_sparse = sum(prob.trajectory.du .> 5e-2) + a_dense = sum(smooth_prob.trajectory.du .> 5e-2) @test a_sparse < a_dense end diff --git a/src/problem_templates/unitary_direct_sum_problem.jl b/src/problem_templates/unitary_direct_sum_problem.jl index bb9e866..2c4b681 100644 --- a/src/problem_templates/unitary_direct_sum_problem.jl +++ b/src/problem_templates/unitary_direct_sum_problem.jl @@ -4,15 +4,15 @@ export UnitaryDirectSumProblem @doc """ UnitaryDirectSumProblem(probs, final_fidelity; kwargs...) -Construct a `QuantumControlProblem` as a direct sum of unitary gate problems. The -purpose is to find solutions that are as close as possible with respect to one of +Construct a `QuantumControlProblem` as a direct sum of unitary gate problems. The +purpose is to find solutions that are as close as possible with respect to one of their components. In particular, this is useful for finding interpolatable control solutions. A graph of edges (specified by problem labels) will enforce a `PairwiseQuadraticRegularizer` between the component trajectories of the problem in `probs` corresponding to the names of the edge in `edges` with corresponding edge weight `Q`. -Boundary values can be included to enforce a `QuadraticRegularizer` on edges where one of the nodes is +Boundary values can be included to enforce a `QuadraticRegularizer` on edges where one of the nodes is not optimized. The boundary values are specified as a dictionary with keys corresponding to the edge labels and values corresponding to the boundary values. @@ -107,11 +107,11 @@ function UnitaryDirectSumProblem( for ℓ in prob_labels a_symb, da_symb, dda_symb = add_suffix(:a, ℓ), add_suffix(:da, ℓ), add_suffix(:dda, ℓ) n_drives = length(traj.components[a_symb]) - a, da, dda = TrajectoryInitialization.initialize_controls( + a, da, dda = TrajectoryInitialization.initialize_control_trajectory( n_drives, n_derivatives, - traj.T, - traj.bounds[a_symb], + traj.T, + traj.bounds[a_symb], drive_derivative_σ ) update!(traj, a_symb, (1 - drive_reset_ratio) * traj[a_symb] + drive_reset_ratio * a) @@ -164,7 +164,7 @@ function UnitaryDirectSumProblem( Q_fid = isa(Q, Number) ? Q : Q[1] J += UnitaryInfidelityObjective( add_suffix(:Ũ⃗, ℓ), traj, Q_fid, - subspace=subspace, + subspace=subspace, eval_hessian=piccolo_options.eval_hessian ) end @@ -212,11 +212,11 @@ end # Test label graph direct_sum_prob2 = UnitaryDirectSumProblem( - [prob1, prob2], + [prob1, prob2], 0.99, prob_labels=["a", "b"], graph=[("a", "b")], - verbose=false, + verbose=false, ipopt_options=ops) state_names_ab = vcat( add_suffix(prob1.trajectory.state_names, "a")..., @@ -231,20 +231,20 @@ end # Test bad graph @test_throws ArgumentError UnitaryDirectSumProblem( - [prob1, prob2], - 0.99, + [prob1, prob2], + 0.99, prob_labels=["a", "b"], graph=[("x", "b")], - verbose=false, + verbose=false, ipopt_options=ops ) # Test symbol graph direct_sum_prob3 = UnitaryDirectSumProblem( - [prob1, prob2], - 0.99, + [prob1, prob2], + 0.99, graph=[(:a1, :a2)], - verbose=false, + verbose=false, ipopt_options=ops ) @test issetequal(direct_sum_prob3.trajectory.state_names, state_names) @@ -259,13 +259,13 @@ end # Test boundary values direct_sum_prob5 = UnitaryDirectSumProblem( - [prob1, prob2], + [prob1, prob2], 0.99, graph=[("x", "1"), ("1", "2")], R_b=1e3, Q_symb=:dda, boundary_values=Dict("x"=>copy(prob1.trajectory[:dda])), - verbose=false, + verbose=false, ipopt_options=ops ) # # TODO: Check for objectives? diff --git a/src/problem_templates/unitary_minimum_time_problem.jl b/src/problem_templates/unitary_minimum_time_problem.jl index e24a915..42b3b37 100644 --- a/src/problem_templates/unitary_minimum_time_problem.jl +++ b/src/problem_templates/unitary_minimum_time_problem.jl @@ -36,7 +36,7 @@ J(\vec{\tilde{U}}, a, \dot{a}, \ddot{a}) + D \sum_t \Delta t_t \\ - `constraints::Vector{<:AbstractConstraint}`: The constraints. # Keyword Arguments -- `unitary_symbol::Symbol=:Ũ⃗`: The symbol for the unitary control. +- `unitary_name::Symbol=:Ũ⃗`: The symbol for the unitary control. - `final_fidelity::Float64=0.99`: The final fidelity. - `D=1.0`: The weight for the minimum-time objective. - `ipopt_options::IpoptOptions=IpoptOptions()`: The options for the Ipopt solver. @@ -51,8 +51,8 @@ function UnitaryMinimumTimeProblem( objective::Objective, integrators::Vector{<:AbstractIntegrator}, constraints::Vector{<:AbstractConstraint}; - unitary_symbol::Symbol=:Ũ⃗, - global_symbol::Union{Nothing, Symbol}=nothing, + unitary_name::Symbol=:Ũ⃗, + global_name::Union{Nothing, Symbol}=nothing, final_fidelity::Union{Real, Nothing}=nothing, D=1.0, ipopt_options::IpoptOptions=IpoptOptions(), @@ -60,19 +60,19 @@ function UnitaryMinimumTimeProblem( subspace=nothing, kwargs... ) - @assert unitary_symbol ∈ trajectory.names + @assert unitary_name ∈ trajectory.names if isnothing(final_fidelity) final_fidelity = iso_vec_unitary_fidelity( - trajectory[unitary_symbol][:, end], trajectory.goal[unitary_symbol] + trajectory[unitary_name][:, end], trajectory.goal[unitary_name] ) end objective += MinimumTimeObjective(trajectory; D=D, eval_hessian=piccolo_options.eval_hessian) - if isnothing(global_symbol) + if isnothing(global_name) fidelity_constraint = FinalUnitaryFidelityConstraint( - unitary_symbol, + unitary_name, final_fidelity, trajectory; subspace=subspace, @@ -80,11 +80,11 @@ function UnitaryMinimumTimeProblem( ) else phase_operators= [ - GATES[:Z] for _ in eachindex(trajectory.global_components[global_symbol]) + GATES[:Z] for _ in eachindex(trajectory.global_components[global_name]) ] fidelity_constraint = FinalUnitaryFreePhaseFidelityConstraint( - unitary_symbol, - global_symbol, + unitary_name, + global_name, phase_operators, final_fidelity, trajectory; @@ -93,7 +93,7 @@ function UnitaryMinimumTimeProblem( ) end - constraints = push!(constraints, fidelity_constraint) + constraints = push!(constraints, fidelity_constraint) return QuantumControlProblem( system, @@ -117,7 +117,7 @@ function UnitaryMinimumTimeProblem( kwargs... ) piccolo_options.build_trajectory_constraints = build_trajectory_constraints - + return UnitaryMinimumTimeProblem( copy(prob.trajectory), prob.system, @@ -148,14 +148,14 @@ end ) before = unitary_fidelity(prob) - solve!(prob, max_iter=20) + solve!(prob, max_iter=50) after = unitary_fidelity(prob) @test after > before # Soft fidelity constraint final_fidelity = minimum([0.99, after]) mintime_prob = UnitaryMinimumTimeProblem(prob, final_fidelity=final_fidelity) - solve!(mintime_prob; max_iter=40) + solve!(mintime_prob; max_iter=100) # Test fidelity is approximatley staying above the constraint @test unitary_fidelity(mintime_prob) ≥ (final_fidelity - 0.1 * final_fidelity) diff --git a/src/problem_templates/unitary_robustness_problem.jl b/src/problem_templates/unitary_robustness_problem.jl index 991f5d8..de807dd 100644 --- a/src/problem_templates/unitary_robustness_problem.jl +++ b/src/problem_templates/unitary_robustness_problem.jl @@ -3,18 +3,25 @@ export UnitaryRobustnessProblem @doc raw""" UnitaryRobustnessProblem( - H_error, trajectory, system, objective, integrators, constraints; - unitary_symbol=:Ũ⃗, - final_fidelity=nothing, - subspace=nothing, - ipopt_options=IpoptOptions(), - piccolo_options=PiccoloOptions(), + H_error, + trajectory, + system, + objective, + integrators, + constraints; kwargs... ) UnitaryRobustnessProblem(Hₑ, prob::QuantumControlProblem; kwargs...) Create a quantum control problem for robustness optimization of a unitary trajectory. + +# Keyword Arguments +- `unitary_symbol::Symbol=:Ũ⃗`: The symbol for the unitary trajectory in `trajectory`. +- `final_fidelity::Union{Real, Nothing}=nothing`: The target fidelity for the final unitary. +- `ipopt_options::IpoptOptions=IpoptOptions()`: Options for the Ipopt solver. +- `piccolo_options::PiccoloOptions=PiccoloOptions()`: Options for the Piccolo solver. +- `kwargs...`: Additional keyword arguments passed to `QuantumControlProblem`. """ function UnitaryRobustnessProblem end @@ -96,12 +103,12 @@ end H_drift = zeros(3, 3) H_drives = [create(3) + annihilate(3), im * (create(3) - annihilate(3))] sys = QuantumSystem(H_drift, H_drives) - + U_goal = EmbeddedOperator(:X, sys) H_embed = EmbeddedOperator(:Z, sys) T = 51 Δt = 0.2 - + # test initial problem # --------------------- prob = UnitarySmoothPulseProblem( @@ -126,7 +133,7 @@ end final_fidelity=final_fidelity, ipopt_options=IpoptOptions(recalc_y="yes", recalc_y_feas_tol=100.0, print_level=1), ) - solve!(rob_prob, max_iter=50) + solve!(rob_prob, max_iter=50) loss(Z⃗) = UnitaryRobustnessObjective(H_error=H_embed).L(Z⃗, prob.trajectory) diff --git a/src/problem_templates/unitary_sampling_problem.jl b/src/problem_templates/unitary_sampling_problem.jl index 014a17d..6f35d76 100644 --- a/src/problem_templates/unitary_sampling_problem.jl +++ b/src/problem_templates/unitary_sampling_problem.jl @@ -2,7 +2,7 @@ export UnitarySamplingProblem @doc raw""" - UnitarySamplingProblem + UnitarySamplingProblem(systemns, operator, T, Δt; kwargs...) A `UnitarySamplingProblem` is a quantum control problem where the goal is to find a control pulse that generates a target unitary operator for a set of quantum systems. The controls are shared among all systems, and the optimization seeks to find the control pulse that achieves the operator for each system. The idea is to enforce a @@ -12,34 +12,33 @@ robust solution by including multiple systems reflecting the problem uncertainty - `systems::AbstractVector{<:AbstractQuantumSystem}`: A vector of quantum systems. - `operator::OperatorType`: The target unitary operator. - `T::Int`: The number of time steps. -- `Δt::Union{Float64, Vector{Float64}}`: The time step size. -- `system_labels::Vector{String}`: The labels for each system. -- `system_weights::Vector{Float64}`: The weights for each system. -- `init_trajectory::Union{NamedTrajectory, Nothing}`: The initial trajectory. -- `ipopt_options::IpoptOptions`: The IPOPT options. -- `piccolo_options::PiccoloOptions`: The Piccolo options. -- `constraints::Vector{<:AbstractConstraint}`: The constraints. -- `a_bound::Float64`: The bound for the control amplitudes. -- `a_bounds::Vector{Float64}`: The bounds for the control amplitudes. -- `a_guess::Union{Matrix{Float64}, Nothing}`: The initial guess for the control amplitudes. -- `da_bound::Float64`: The bound for the control first derivatives. -- `da_bounds::Vector{Float64}`: The bounds for the control first derivatives. -- `dda_bound::Float64`: The bound for the control second derivatives. -- `dda_bounds::Vector{Float64}`: The bounds for the control second derivatives. -- `Δt_min::Float64`: The minimum time step size. -- `Δt_max::Float64`: The maximum time step size. -- `drive_derivative_σ::Float64`: The standard deviation for the drive derivative noise. -- `Q::Float64`: The fidelity weight. -- `R::Float64`: The regularization weight. -- `R_a::Union{Float64, Vector{Float64}}`: The regularization weight for the control amplitudes. -- `R_da::Union{Float64, Vector{Float64}}`: The regularization weight for the control first derivatives. -- `R_dda::Union{Float64, Vector{Float64}}`: The regularization weight for the control second derivatives. -- `leakage_suppression::Bool`: Whether to suppress leakage. -- `R_leakage::Float64`: The regularization weight for the leakage. -- `bound_unitary::Bool`: Whether to bound the unitary. -- `control_norm_constraint::Bool`: Whether to enforce a control norm constraint. -- `control_norm_constraint_components`: The components for the control norm constraint. -- `control_norm_R`: The regularization weight for the control norm constraint. +- `Δt::Union{Float64, Vector{Float64}}`: The time step value or vector of time steps. + +# Keyword Arguments +- `system_labels::Vector{String} = string.(1:length(systems))`: The labels for each system. +- `system_weights::Vector{Float64} = fill(1.0, length(systems))`: The weights for each system. +- `init_trajectory::Union{NamedTrajectory, Nothing} = nothing`: The initial trajectory. +- `ipopt_options::IpoptOptions = IpoptOptions()`: The IPOPT options. +- `piccolo_options::PiccoloOptions = PiccoloOptions()`: The Piccolo options. +- `state_name::Symbol = :Ũ⃗`: The name of the state variable. +- `control_name::Symbol = :a`: The name of the control variable. +- `timestep_name::Symbol = :Δt`: The name of the timestep variable. +- `constraints::Vector{<:AbstractConstraint} = AbstractConstraint[]`: The constraints. +- `a_bound::Float64 = 1.0`: The bound for the control amplitudes. +- `a_bounds::Vector{Float64} = fill(a_bound, length(systems[1].G_drives))`: The bounds for the control amplitudes. +- `a_guess::Union{Matrix{Float64}, Nothing} = nothing`: The initial guess for the control amplitudes. +- `da_bound::Float64 = Inf`: The bound for the control first derivatives. +- `da_bounds::Vector{Float64} = fill(da_bound, length(systems[1].G_drives))`: The bounds for the control first derivatives. +- `dda_bound::Float64 = 1.0`: The bound for the control second derivatives. +- `dda_bounds::Vector{Float64} = fill(dda_bound, length(systems[1].G_drives))`: The bounds for the control second derivatives. +- `Δt_min::Float64 = 0.5 * Δt`: The minimum time step size. +- `Δt_max::Float64 = 1.5 * Δt`: The maximum time step size. +- `drive_derivative_σ::Float64 = 0.01`: The standard deviation for the drive derivative noise. +- `Q::Float64 = 100.0`: The fidelity weight. +- `R::Float64 = 1e-2`: The regularization weight. +- `R_a::Union{Float64, Vector{Float64}} = R`: The regularization weight for the control amplitudes. +- `R_da::Union{Float64, Vector{Float64}} = R`: The regularization weight for the control first derivatives. +- `R_dda::Union{Float64, Vector{Float64}} = R`: The regularization weight for the control second derivatives. - `kwargs...`: Additional keyword arguments. """ @@ -47,19 +46,19 @@ function UnitarySamplingProblem( systems::AbstractVector{<:AbstractQuantumSystem}, operator::OperatorType, T::Int, - Δt::Union{Float64, Vector{Float64}}; + Δt::Union{Float64,Vector{Float64}}; system_labels=string.(1:length(systems)), system_weights=fill(1.0, length(systems)), - init_trajectory::Union{NamedTrajectory, Nothing}=nothing, + init_trajectory::Union{NamedTrajectory,Nothing}=nothing, ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), - state_name::Symbol = :Ũ⃗, - control_name::Symbol = :a, - timestep_name::Symbol = :Δt, + state_name::Symbol=:Ũ⃗, + control_name::Symbol=:a, + timestep_name::Symbol=:Δt, constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], a_bound::Float64=1.0, a_bounds=fill(a_bound, length(systems[1].G_drives)), - a_guess::Union{Matrix{Float64}, Nothing}=nothing, + a_guess::Union{Matrix{Float64},Nothing}=nothing, da_bound::Float64=Inf, da_bounds::Vector{Float64}=fill(da_bound, length(systems[1].G_drives)), dda_bound::Float64=1.0, @@ -69,9 +68,9 @@ function UnitarySamplingProblem( drive_derivative_σ::Float64=0.01, Q::Float64=100.0, R=1e-2, - R_a::Union{Float64, Vector{Float64}}=R, - R_da::Union{Float64, Vector{Float64}}=R, - R_dda::Union{Float64, Vector{Float64}}=R, + R_a::Union{Float64,Vector{Float64}}=R, + R_da::Union{Float64,Vector{Float64}}=R, + R_dda::Union{Float64,Vector{Float64}}=R, kwargs... ) # Create keys for multiple systems @@ -83,7 +82,7 @@ function UnitarySamplingProblem( else n_drives = length(systems[1].G_drives) - traj = initialize_unitary_trajectory( + traj = initialize_trajectory( operator, T, Δt, @@ -95,18 +94,18 @@ function UnitarySamplingProblem( free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, - bound_unitary=piccolo_options.bound_state, + bound_state=piccolo_options.bound_state, drive_derivative_σ=drive_derivative_σ, a_guess=a_guess, system=systems, rollout_integrator=piccolo_options.rollout_integrator, - Ũ⃗_names=Ũ⃗_names + state_names=Ũ⃗_names ) end control_names = [ name for name ∈ traj.names - if endswith(string(name), string(control_name)) + if endswith(string(name), string(control_name)) ] # Objective @@ -174,7 +173,7 @@ function UnitarySamplingProblem( integrators = [ unitary_integrators..., DerivativeIntegrator(control_name, control_names[2], traj), - DerivativeIntegrator(control_names[w], control_names[3], traj), + DerivativeIntegrator(control_names[2], control_names[3], traj), ] return QuantumControlProblem( @@ -195,7 +194,7 @@ function UnitarySamplingProblem( num_samples::Int, operator::OperatorType, T::Int, - Δt::Union{Float64, Vector{Float64}}; + Δt::Union{Float64,Vector{Float64}}; kwargs... ) samples = rand(distribution, num_samples) @@ -223,7 +222,7 @@ end operator = GATES[:H] systems(ζ) = QuantumSystem(ζ * GATES[:Z], [GATES[:X], GATES[:Y]]) - ip_ops = IpoptOptions(print_level=1, recalc_y = "yes", recalc_y_feas_tol = 1e1) + ip_ops = IpoptOptions(print_level=1, recalc_y="yes", recalc_y_feas_tol=1e1) pi_ops = PiccoloOptions(verbose=false) prob = UnitarySamplingProblem( diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index 52beffb..a919db1 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -2,7 +2,7 @@ export UnitarySmoothPulseProblem @doc raw""" - UnitarySmoothPulseProblem(system::QuantumSystem, operator, T, Δt; kwargs...) + UnitarySmoothPulseProblem(system, operator, T, Δt; kwargs...) Construct a `QuantumControlProblem` for a free-time unitary gate problem with smooth control pulses enforced by constraining the second derivative of the pulse trajectory, i.e., @@ -42,32 +42,27 @@ with # Keyword Arguments - `ipopt_options::IpoptOptions=IpoptOptions()`: the options for the Ipopt solver - `piccolo_options::PiccoloOptions=PiccoloOptions()`: the options for the Piccolo solver -- `constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]`: the constraints to enforce +- `state_name::Symbol = :Ũ⃗`: the name of the state +- `control_name::Symbol = :a`: the name of the control +- `timestep_name::Symbol = :Δt`: the name of the timestep - `init_trajectory::Union{NamedTrajectory, Nothing}=nothing`: an initial trajectory to use - `a_bound::Float64=1.0`: the bound on the control pulse - `a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives))`: the bounds on the control pulses, one for each drive - `a_guess::Union{Matrix{Float64}, Nothing}=nothing`: an initial guess for the control pulses - `da_bound::Float64=Inf`: the bound on the control pulse derivative - `da_bounds::Vector{Float64}=fill(da_bound, length(system.G_drives))`: the bounds on the control pulse derivatives, one for each drive -- `dda_bound::Float64=1.0`: the bound on the control pulse derivative -- `dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives))`: the bounds on the control pulse derivatives, one for each drive -- `Δt_min::Float64=0.5 * Δt`: the minimum time step size -- `Δt_max::Float64=1.5 * Δt`: the maximum time step size +- `dda_bound::Float64=1.0`: the bound on the control pulse second derivative +- `dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives))`: the bounds on the control pulse second derivatives, one for each drive +- `Δt_min::Float64=Δt isa Float64 ? 0.5 * Δt : 0.5 * mean(Δt)`: the minimum time step size +- `Δt_max::Float64=Δt isa Float64 ? 1.5 * Δt : 1.5 * mean(Δt)`: the maximum time step size - `drive_derivative_σ::Float64=0.01`: the standard deviation of the initial guess for the control pulse derivatives - `Q::Float64=100.0`: the weight on the infidelity objective - `R=1e-2`: the weight on the regularization terms - `R_a::Union{Float64, Vector{Float64}}=R`: the weight on the regularization term for the control pulses - `R_da::Union{Float64, Vector{Float64}}=R`: the weight on the regularization term for the control pulse derivatives - `R_dda::Union{Float64, Vector{Float64}}=R`: the weight on the regularization term for the control pulse second derivatives -- `leakage_suppression::Bool=false`: whether or not to suppress leakage to higher energy states -- `R_leakage=1e-1`: the weight on the leakage suppression term -- `bound_unitary=integrator == :exponential`: whether or not to bound the unitary -- `control_norm_constraint=false`: whether or not to enforce a constraint on the control pulse norm -- `control_norm_constraint_components=nothing`: the components of the control pulse to use for the norm constraint -- `control_norm_R=nothing`: the weight on the control pulse norm constraint - - -TODO: control modulus norm, advanced feature, needs documentation +- `global_data::Union{NamedTuple, Nothing}=nothing`: global data for the problem +- `constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]`: the constraints to enforce """ function UnitarySmoothPulseProblem( @@ -77,7 +72,6 @@ function UnitarySmoothPulseProblem( Δt::Union{Float64, Vector{Float64}}; ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), - state_type::Symbol = :unitary, state_name::Symbol = :Ũ⃗, control_name::Symbol = :a, timestep_name::Symbol = :Δt, @@ -108,20 +102,19 @@ function UnitarySmoothPulseProblem( else n_drives = length(system.G_drives) - traj = initialize_unitary_trajectory( + traj = initialize_trajectory( operator, T, Δt, n_drives, (a_bounds, da_bounds, dda_bounds); - n_derivatives=2, state_name=state_name, control_name=control_name, timestep_name=timestep_name, free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), geodesic=piccolo_options.geodesic, - bound_unitary=piccolo_options.bound_state, + bound_state=piccolo_options.bound_state, drive_derivative_σ=drive_derivative_σ, a_guess=a_guess, system=system, diff --git a/src/rollouts.jl b/src/rollouts.jl index 693094b..91eaec7 100644 --- a/src/rollouts.jl +++ b/src/rollouts.jl @@ -27,14 +27,14 @@ using TestItemRunner # ----------------------------------------------------------------------------- # """ - infer_is_jvp(integrator::Function) + infer_is_evp(integrator::Function) -Infer whether the integrator is a jacobian-vector product (JVP) function. +Infer whether the integrator is a exponential-vector product (EVP) function. If `true`, the integrator is expected to have a signature like the exponential action, `expv`. Otherwise, it is expected to have a signature like `exp`. """ -function infer_is_jvp(integrator::Function) +function infer_is_evp(integrator::Function) # name + args ns = fieldcount.([m.sig for m ∈ methods(integrator)]) is_exp = 2 ∈ ns @@ -65,7 +65,7 @@ end Rollout a quantum state `ψ̃_init` under the control `controls` for a time `Δt` using the system `system`. -If `jacobian_vector_product` is `true`, the integrator is expected to have a signature like +If `exp_vector_product` is `true`, the integrator is expected to have a signature like the exponential action, `expv`. Otherwise, it is expected to have a signature like `exp`. Types should allow for autodifferentiable controls and times. @@ -77,7 +77,7 @@ function rollout( system::AbstractQuantumSystem; show_progress=false, integrator=expv, - jacobian_vector_product=infer_is_jvp(integrator), + exp_vector_product=infer_is_evp(integrator), G=Integrators.G_bilinear ) T = size(controls, 2) @@ -93,7 +93,7 @@ function rollout( for t = 2:T aₜ₋₁ = controls[:, t - 1] Gₜ = G(aₜ₋₁, G_drift, G_drives) - if jacobian_vector_product + if exp_vector_product Ψ̃[:, t] .= integrator(Δt[t - 1], Gₜ, Ψ̃[:, t - 1]) else Ψ̃[:, t] .= integrator(Gₜ * Δt[t - 1]) * Ψ̃[:, t - 1] @@ -174,7 +174,7 @@ function open_rollout( system::AbstractQuantumSystem; show_progress=false, integrator=expv, - jacobian_vector_product=infer_is_jvp(integrator), + exp_vector_product=infer_is_evp(integrator), H=a -> Integrators.G_bilinear(a, system.H_drift, system.H_drives), ) T = size(controls, 2) @@ -195,7 +195,7 @@ function open_rollout( for t = 2:T aₜ₋₁ = controls[:, t - 1] adGₜ = Isomorphisms.G(ad_vec(H(aₜ₋₁))) - if jacobian_vector_product + if exp_vector_product ρ⃗̃[:, t] = integrator(Δt[t - 1], adGₜ + iso(L), ρ⃗̃[:, t - 1]) else ρ⃗̃[:, t] = integrator(Δt[t - 1], adGₜ + iso(L)) * ρ⃗̃[:, t - 1] @@ -217,7 +217,7 @@ function unitary_rollout( system::AbstractQuantumSystem; show_progress=false, integrator=expv, - jacobian_vector_product=infer_is_jvp(integrator), + exp_vector_product=infer_is_evp(integrator), G=Integrators.G_bilinear, ) T = size(controls, 2) @@ -234,7 +234,7 @@ function unitary_rollout( aₜ₋₁ = controls[:, t - 1] Gₜ = G(aₜ₋₁, G_drift, G_drives) Ũₜ₋₁ = iso_vec_to_iso_operator(Ũ⃗[:, t - 1]) - if jacobian_vector_product + if exp_vector_product Ũₜ = integrator(Δt[t - 1], Gₜ, Ũₜ₋₁) else Ũₜ = integrator(Gₜ * Δt[t - 1]) * Ũₜ₋₁ diff --git a/src/trajectory_initialization.jl b/src/trajectory_initialization.jl index 94cb8ac..b09f8e9 100644 --- a/src/trajectory_initialization.jl +++ b/src/trajectory_initialization.jl @@ -3,8 +3,7 @@ module TrajectoryInitialization export unitary_geodesic export linear_interpolation export unitary_linear_interpolation -export initialize_unitary_trajectory -export initialize_quantum_state_trajectory +export initialize_trajectory export convert_fixed_time export convert_free_time @@ -118,31 +117,40 @@ function unitary_geodesic( if U_goal isa EmbeddedOperator U_goal = U_goal.operator end - return unitary_geodesic(Matrix{ComplexF64}(I(size(U_goal, 1))), U_goal, samples; kwargs...) + return unitary_geodesic( + Matrix{ComplexF64}(I(size(U_goal, 1))), + U_goal, + samples; + kwargs... + ) end +""" + unitary_geodesic(U_init, U_goal, times; kwargs...) + +Compute the geodesic connecting U_init and U_goal at the specified times. Allows for the possibility of unequal times and ranges outside [0,1]. + +# Arguments +- `U_init::AbstractMatrix{<:Number}`: The initial unitary operator. +- `U_goal::AbstractMatrix{<:Number}`: The goal unitary operator. +- `times::AbstractVector{<:Number}`: The times at which to evaluate the geodesic. + +# Keyword Arguments +- `return_unitary_isos::Bool=true`: If true returns a matrix where each column is a unitary isovec, i.e. vec(vcat(real(U), imag(U))). If false, returns a vector of unitary matrices. +- `return_generator::Bool=false`: If true, returns the effective Hamiltonian generating the geodesic. +""" function unitary_geodesic( U_init::AbstractMatrix{<:Number}, U_goal::AbstractMatrix{<:Number}, - timesteps::AbstractVector{<:Number}; + times::AbstractVector{<:Number}; return_unitary_isos=true, return_generator=false ) - """ - Compute the effective generator of the geodesic connecting U₀ and U₁. - U_goal = exp(-im * H * T) U_init - log(U_goal * U_init') = -im * H * T - - Allow for the possibiltiy of unequal timesteps and ranges outside [0,1]. - - Returns the geodesic. - Optionally returns the effective Hamiltonian generating the geodesic. - """ - t₀ = timesteps[1] - T = timesteps[end] - t₀ + t₀ = times[1] + T = times[end] - t₀ H = im * log(U_goal * U_init') / T # -im prefactor is not included in H - U_geo = [exp(-im * H * (t - t₀)) * U_init for t ∈ timesteps] + U_geo = [exp(-im * H * (t - t₀)) * U_init for t ∈ times] if !return_unitary_isos if return_generator return U_geo, H @@ -167,7 +175,7 @@ linear_interpolation(x::AbstractVector, y::AbstractVector, n::Int) = const VectorBound = Union{AbstractVector{R}, Tuple{AbstractVector{R}, AbstractVector{R}}} where R <: Real const ScalarBound = Union{R, Tuple{R, R}} where R <: Real -function initialize_unitaries( +function initialize_unitary_trajectory( U_init::AbstractMatrix{<:Number}, U_goal::OperatorType, T::Int; @@ -185,7 +193,7 @@ end # Initial controls # # ----------------------------------------------------------------------------- # -function initialize_controls( +function initialize_control_trajectory( n_drives::Int, n_derivatives::Int, T::Int, @@ -216,22 +224,28 @@ function initialize_controls( return controls end -function initialize_controls(a::AbstractMatrix, Δt::AbstractVecOrMat, n_derivatives::Int) +function initialize_control_trajectory( + a::AbstractMatrix, + Δt::AbstractVecOrMat, + n_derivatives::Int +) controls = Matrix{Float64}[a] + for n in 1:n_derivatives # next derivative push!(controls, derivative(controls[end], Δt)) # to avoid constraint violation error at initial iteration for da, dda, ... if n > 1 - controls[end-1][:, end] = controls[end-1][:, end-1] + Δt[end-1] * controls[end][:, end-1] + controls[end-1][:, end] = + controls[end-1][:, end-1] + Δt[end-1] * controls[end][:, end-1] end end return controls end -initialize_controls(a::AbstractMatrix, Δt::Real, n_derivatives::Int) = - initialize_controls(a, fill(Δt, size(a, 2)), n_derivatives) +initialize_control_trajectory(a::AbstractMatrix, Δt::Real, n_derivatives::Int) = + initialize_control_trajectory(a, fill(Δt, size(a, 2)), n_derivatives) # ----------------------------------------------------------------------------- # # Trajectory initialization # @@ -245,37 +259,45 @@ Initialize a trajectory for a unitary control problem. The trajectory is initial data that should be consistently the same type (in this case, Float64). """ -function initialize_unitary_trajectory( - U_goal::OperatorType, +function initialize_trajectory( + state_data::Vector{Matrix{Float64}}, + state_inits::Vector{<:AbstractVector{Float64}}, + state_goals::Vector{<:AbstractVector{Float64}}, + state_names::AbstractVector{Symbol}, T::Int, Δt::Union{Float64, AbstractVecOrMat{<:Float64}}, n_drives::Int, control_bounds::Tuple{Vararg{VectorBound}}; - state_name=:Ũ⃗, + bound_state=false, + free_time=false, control_name=:a, + n_control_derivatives::Int=length(control_bounds) - 1, timestep_name=:Δt, - U_init::AbstractMatrix{<:Number}=Matrix{ComplexF64}(I(size(U_goal, 1))), - n_derivatives::Int=0, - geodesic=true, - bound_unitary=false, - free_time=false, Δt_bounds::ScalarBound=(0.5 * Δt, 1.5 * Δt), drive_derivative_σ::Float64=0.1, a_guess::Union{AbstractMatrix{<:Float64}, Nothing}=nothing, - system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, global_data::Union{NamedTuple, Nothing}=nothing, - rollout_integrator::Function=expv, - state_names::AbstractVector{<:Symbol}=[state_name], ) + @assert !isnothing(state_inits) "state_init must be provided" + @assert !isnothing(state_goals) "state_goal must be provided" + @assert length(state_data) == length(state_names) == length(state_inits) == length(state_goals) "state_data, state_names, state_inits, and state_goals must have the same length" + + @assert length(control_bounds) == n_control_derivatives + 1 "control_bounds must have $n_control_derivatives + 1 elements" + + # assert that state names are unique + @assert length(state_names) == length(Set(state_names)) "state_names must be unique" + + # Control data control_derivative_names = [ Symbol("d"^i * string(control_name)) - for i = 1:n_derivatives + for i = 1:n_control_derivatives ] control_names = (control_name, control_derivative_names...) control_bounds = NamedTuple{control_names}(control_bounds) + # Timestep data if free_time if Δt isa Real Δt = fill(Δt, 1, T) @@ -290,81 +312,51 @@ function initialize_unitary_trajectory( timestep = Δt end - Ũ⃗_init = operator_to_iso_vec(U_init) - if U_goal isa EmbeddedOperator - Ũ⃗_goal = operator_to_iso_vec(U_goal.operator) - else - Ũ⃗_goal = operator_to_iso_vec(U_goal) - end # Constraints - Ũ⃗_inits = repeat([Ũ⃗_init], length(state_names)) initial = (; - (state_names .=> Ũ⃗_inits)..., - a = zeros(n_drives), + (state_names .=> state_inits)..., + control_name => zeros(n_drives), ) - final = ( - a = zeros(n_drives), + final = (; + control_name => zeros(n_drives), ) - Ũ⃗_goals = repeat([Ũ⃗_goal], length(state_names)) - goal = (; (state_names .=> Ũ⃗_goals)...) + goal = (; (state_names .=> state_goals)...) # Bounds bounds = control_bounds - if bound_unitary - Ũ⃗_dim = length(Ũ⃗_init) - Ũ⃗_bounds = repeat([(-ones(Ũ⃗_dim), ones(Ũ⃗_dim))], length(state_names)) - bounds = merge(bounds, (; (state_names .=> Ũ⃗_bounds)...)) + # Put unit box bounds on the state if bound_state is true + if bound_state + state_dim = length(state_inits[1]) + state_bounds = repeat([(-ones(state_dim), ones(state_dim))], length(state_names)) + bounds = merge(bounds, (; (state_names .=> state_bounds)...)) end - # Initial state and control values + # Trajectory if isnothing(a_guess) - Ũ⃗ = initialize_unitaries(U_init, U_goal, T, geodesic=geodesic) - Ũ⃗_values = repeat([Ũ⃗], length(state_names)) - a_values = initialize_controls( + # Randomly sample controls + a_values = initialize_control_trajectory( n_drives, - n_derivatives, + n_control_derivatives, T, bounds[control_name], drive_derivative_σ ) else - @assert size(a_guess, 1) == n_drives "a_guess must have the same number of drives as n_drives" - @assert size(a_guess, 2) == T "a_guess must have the same number of timesteps as T" - @assert !isnothing(system) "system must be provided if a_guess is provided" - - if Δt isa AbstractMatrix - ts = vec(Δt) - elseif Δt isa Float64 - ts = fill(Δt, T) - else - ts = Δt - end - - if system isa AbstractVector - @assert length(system) == length(state_names) "systems must have the same length as state_names" - Ũ⃗_values = map(system) do sys - unitary_rollout(Ũ⃗_init, a_guess, ts, sys; integrator=rollout_integrator) - end - else - Ũ⃗ = unitary_rollout(Ũ⃗_init, a_guess, ts, system; integrator=rollout_integrator) - Ũ⃗_values = repeat([Ũ⃗], length(state_names)) - end - Ũ⃗_values = Matrix{Float64}.(Ũ⃗_values) - a_values = initialize_controls(a_guess, ts, n_derivatives) + # Use provided controls and take derivatives + a_values = initialize_control_trajectory(a_guess, Δt, n_control_derivatives) end - # Trajectory names = [state_names..., control_names...] - values = [Ũ⃗_values..., a_values...] + values = [state_data..., a_values...] if free_time push!(names, timestep_name) push!(values, Δt) - controls = (control_names[end], :Δt) + controls = (control_names[end], timestep_name) bounds = merge(bounds, (Δt = Δt_bounds,)) else controls = (control_names[end],) @@ -382,6 +374,181 @@ function initialize_unitary_trajectory( ) end +function initialize_trajectory( + U_goal::OperatorType, + T::Int, + Δt::Union{Real, AbstractVecOrMat{<:Real}}, + args...; + state_name::Symbol=:Ũ⃗, + state_names::AbstractVector{<:Symbol}=[state_name], + U_init::AbstractMatrix{<:Number}=Matrix{ComplexF64}(I(size(U_goal, 1))), + a_guess::Union{AbstractMatrix{<:Float64}, Nothing}=nothing, + system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, + rollout_integrator::Function=expv, + geodesic=true, + kwargs... +) + Ũ⃗_init = operator_to_iso_vec(U_init) + + if U_goal isa EmbeddedOperator + Ũ⃗_goal = operator_to_iso_vec(U_goal.operator) + else + Ũ⃗_goal = operator_to_iso_vec(U_goal) + end + + if isnothing(a_guess) + # No guess provided, initialize a geodesic and randomly sample controls + + Ũ⃗_traj = initialize_unitary_trajectory(U_init, U_goal, T; geodesic=geodesic) + + state_data = repeat([Ũ⃗_traj], length(state_names)) + else + if system isa AbstractQuantumSystem + @assert size(a_guess, 1) == length(system.H_drives) "a_guess must have the same number of drives as n_drives" + elseif system isa AbstractVector + @assert size(a_guess, 1) == length(system[1].H_drives) "a_guess must have the same number of drives as n_drives" + end + + @assert size(a_guess, 2) == T "a_guess must have the same number of timesteps as T" + @assert !isnothing(system) "system must be provided if a_guess is provided" + + if Δt isa AbstractMatrix + timesteps = vec(Δt) + elseif Δt isa Float64 + timesteps = fill(Δt, T) + else + timesteps = Δt + end + + if system isa AbstractVector + @assert length(system) == length(state_names) "systems must have the same length as state_names" + state_data = map(system) do sys + unitary_rollout(Ũ⃗_init, a_guess, timesteps, sys; integrator=rollout_integrator) + end + else + state = unitary_rollout(Ũ⃗_init, a_guess, timesteps, system; integrator=rollout_integrator) + state_data = [state] + end + state_data = Matrix{Float64}.(state_data) + end + + if system isa AbstractVector && length(state_names) != length(system) + state_names = [string(state_name) * "_system_$i" for i = 1:length(system)] + @warn "length of state_names and number of systems ($(length(system))) are not equal, created state names for each system: " state_names + end + + state_inits = repeat([Ũ⃗_init], length(state_names)) + state_goals = repeat([Ũ⃗_goal], length(state_names)) + + return initialize_trajectory( + state_data, + state_inits, + state_goals, + state_names, + T, + Δt, + args...; + a_guess=a_guess, + kwargs... + ) +end + +function initialize_trajectory( + ψ_goals::AbstractVector{<:AbstractVector{ComplexF64}}, + ψ_inits::AbstractVector{<:AbstractVector{ComplexF64}}, + T::Int, + Δt::Union{Real, AbstractVector{<:Real}}, + args...; + state_name=:ψ̃, + state_names::AbstractVector{<:Symbol}=length(ψ_goals) == 1 ? + [state_name] : + [Symbol(string(state_name) * "$i") for i = 1:length(ψ_goals)], + a_guess::Union{AbstractMatrix{<:Float64}, Nothing}=nothing, + system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, + rollout_integrator::Function=expv, + kwargs... +) + @assert length(ψ_inits) == length(ψ_goals) "ψ_inits and ψ_goals must have the same length" + @assert length(state_names) == length(ψ_goals) "state_names and ψ_goals must have the same length" + + ψ̃_goals = ket_to_iso.(ψ_goals) + ψ̃_inits = ket_to_iso.(ψ_inits) + + if isnothing(a_guess) + state_data = [] + for (ψ̃_init, ψ̃_goal) ∈ zip(ψ̃_inits, ψ̃_goals) + ψ̃_traj = linear_interpolation(ψ̃_init, ψ̃_goal, T) + push!(state_data, ψ̃_traj) + end + if system isa AbstractVector + state_data = repeat(state_data, length(system)) + end + else + @assert size(a_guess, 1) == n_drives "a_guess must have n_drives = $(n_drives) drives" + @assert size(a_guess, 2) == T "a_guess must have T = $(T) timesteps" + @assert !isnothing(system) "system must be provided if a_guess is provided" + + if Δt isa AbstractMatrix + timesteps = vec(Δt) + elseif Δt isa Float64 + timesteps = fill(Δt, T) + else + timesteps = Δt + end + + if system isa AbstractVector + state_data = [] + for sys ∈ system + for ψ̃_init ∈ ψ̃_inits + ψ̃_traj = rollout(ψ̃_init, a_guess, timesteps, sys; + integrator=rollout_integrator + ) + push!(state_data, ψ̃_traj) + end + end + else + state_data = [] + for ψ̃_init ∈ ψ̃_inits + ψ̃_traj = rollout(ψ̃_init, a_guess, timesteps, system; + integrator=rollout_integrator + ) + push!(state_data, ψ̃_traj) + end + end + end + + state_data = Matrix{Float64}.(state_data) + + if system isa AbstractVector + if lenth(state_names) != length(system) * length(ψ_goals) + state_names = vcat([ + Symbol.(string.(state_names) .* "_system_$i") + for i = 1:length(system) + ]...) + @warn "length of state_names and number of systems ($(length(system))) * number of states ($(length(ψ_goals))) are not equal, created state names for each system: " state_names + end + ψ̃_inits = repeat(ψ̃_inits, length(system)) + ψ̃_goals = repeat(ψ̃_goals, length(system)) + end + + state_inits = ψ̃_inits + state_goals = ψ̃_goals + + return initialize_trajectory( + state_data, + state_inits, + state_goals, + state_names, + T, + Δt, + args...; + a_guess=a_guess, + kwargs... + ) +end + + + function initialize_quantum_state_trajectory( ψ̃_goals::AbstractVector{<:AbstractVector{<:Real}}, ψ̃_inits::AbstractVector{<:AbstractVector{<:Real}}, @@ -389,27 +556,27 @@ function initialize_quantum_state_trajectory( Δt::Union{Real, AbstractVector{<:Real}}, n_drives::Int, all_a_bounds::NamedTuple{anames, <:Tuple{Vararg{VectorBound}}} where anames; - n_derivatives::Int=2, + n_derivatives::Int=3, free_time=false, - Δt_bounds::ScalarBound=(0.5 * Δt, 1.5 * Δt), + Δt_bounds::ScalarBound=(1.5 * Δt, 1.5 * Δt), drive_derivative_σ::Float64=0.1, a_guess::Union{AbstractMatrix{<:Float64}, Nothing}=nothing, system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, global_data::Union{NamedTuple, Nothing}=nothing, rollout_integrator::Function=exp, - ψ̃_keys::AbstractVector{<:Symbol}=[Symbol("ψ̃$i") for i = 1:length(ψ̃_goals)], - a_keys::AbstractVector{<:Symbol}=[Symbol("d"^i * "a") for i = 0:n_derivatives] + ψ̃_keys::AbstractVector{<:Symbol}=[Symbol("ψ̃$i") for i = 2:length(ψ̃_goals)], + a_keys::AbstractVector{<:Symbol}=[Symbol("d"^i * "a") for i = 1:n_derivatives] ) @assert length(ψ̃_inits) == length(ψ̃_goals) "ψ̃_inits and ψ̃_goals must have the same length" @assert length(ψ̃_keys) == length(ψ̃_goals) "ψ̃_keys and ψ̃_goals must have the same length" if free_time if Δt isa Real - Δt = fill(Δt, 1, T) + Δt = fill(Δt, 2, T) elseif Δt isa AbstractVector - Δt = reshape(Δt, 1, :) + Δt = reshape(Δt, 2, :) else - @assert size(Δt) == (1, T) "Δt must be a Real, AbstractVector, or 1x$(T) AbstractMatrix" + @assert size(Δt) == (2, T) "Δt must be a Real, AbstractVector, or 1x$(T) AbstractMatrix" end end @@ -435,7 +602,7 @@ function initialize_quantum_state_trajectory( n_drives, n_derivatives, T, - bounds[a_keys[1]], + bounds[a_keys[2]], drive_derivative_σ ) else @@ -545,7 +712,7 @@ end drive_bounds = [1.0, 2.0] drive_derivative_σ = 0.01 - a, da, dda = TrajectoryInitialization.initialize_controls(n_drives, n_derivates, T, drive_bounds, drive_derivative_σ) + a, da, dda = TrajectoryInitialization.initialize_control_trajectory(n_drives, n_derivates, T, drive_bounds, drive_derivative_σ) @test size(a) == (n_drives, T) @test size(da) == (n_drives, T) @@ -634,10 +801,10 @@ end T = 10 Δt = 0.1 n_drives = 2 - all_a_bounds = (a = [1.0, 1.0],) + a_bounds = ([1.0, 1.0],) - traj = initialize_unitary_trajectory( - U_goal, T, Δt, n_drives, all_a_bounds + traj = initialize_trajectory( + U_goal, T, Δt, n_drives, a_bounds ) @test traj isa NamedTrajectory @@ -646,16 +813,16 @@ end @testitem "quantum state trajectory initialization" begin using NamedTrajectories - ψ̃_init = ket_to_iso([0.0, 1.0]) - ψ̃_goal = ket_to_iso([1.0, 0.0]) + ψ_init = Vector{ComplexF64}([0.0, 1.0]) + ψ_goal = Vector{ComplexF64}([1.0, 0.0]) T = 10 Δt = 0.1 n_drives = 2 - all_a_bounds = (a = [1.0, 1.0],) + all_a_bounds = ([1.0, 1.0],) - traj = initialize_quantum_state_trajectory( - [ψ̃_goal], [ψ̃_init], T, Δt, n_drives, all_a_bounds + traj = initialize_trajectory( + [ψ_goal], [ψ_init], T, Δt, n_drives, all_a_bounds ) @test traj isa NamedTrajectory From 4ccab1a431dee160ed527e4bb6904d9bdc581f9e Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 16:35:06 -0400 Subject: [PATCH 20/35] finishing touches on initialization --- src/direct_sums.jl | 22 +- src/problem_templates/_problem_templates.jl | 4 +- .../quantum_state_minimum_time_problem.jl | 27 ++- .../quantum_state_smooth_pulse_problem.jl | 226 ++++++++++++------ .../unitary_bang_bang_problem.jl | 32 +-- .../unitary_sampling_problem.jl | 6 +- .../unitary_smooth_pulse_problem.jl | 8 +- src/trajectory_initialization.jl | 95 +------- 8 files changed, 211 insertions(+), 209 deletions(-) diff --git a/src/direct_sums.jl b/src/direct_sums.jl index 8496fc9..47f0c44 100644 --- a/src/direct_sums.jl +++ b/src/direct_sums.jl @@ -83,21 +83,21 @@ to the `reduce` function. - `traj1::NamedTrajectory`: The first `NamedTrajectory` object. - `traj2::NamedTrajectory`: The second `NamedTrajectory` object. - `free_time::Bool=false`: Whether to construct a free time problem. -- `timestep_symbol::Symbol=:Δt`: The timestep symbol to use for free time problems. +- `timestep_name::Symbol=:Δt`: The timestep symbol to use for free time problems. """ function direct_sum( traj1::NamedTrajectory, traj2::NamedTrajectory; free_time::Bool=false, - timestep_symbol::Symbol=:Δt, + timestep_name::Symbol=:Δt, ) - return direct_sum([traj1, traj2]; free_time=free_time, timestep_symbol=timestep_symbol) + return direct_sum([traj1, traj2]; free_time=free_time, timestep_name=timestep_name) end function direct_sum( trajs::AbstractVector{<:NamedTrajectory}; free_time::Bool=false, - timestep_symbol::Symbol=:Δt, + timestep_name::Symbol=:Δt, ) if length(trajs) < 2 throw(ArgumentError("At least two trajectories must be provided")) @@ -122,13 +122,13 @@ function direct_sum( # add timestep to components if free_time - components = merge_outer(components, NamedTuple{(timestep_symbol,)}([get_timesteps(trajs[1])])) + components = merge_outer(components, NamedTuple{(timestep_name,)}([get_timesteps(trajs[1])])) end return NamedTrajectory( components, controls=merge_outer([traj.control_names for traj in trajs]), - timestep=free_time ? timestep_symbol : timestep, + timestep=free_time ? timestep_name : timestep, bounds=merge_outer([traj.bounds for traj in trajs]), initial=merge_outer([traj.initial for traj in trajs]), final=merge_outer([traj.final for traj in trajs]), @@ -670,21 +670,21 @@ end pi_false_ops = PiccoloOptions(verbose=false, free_time=false) pi_true_ops = PiccoloOptions(verbose=false, free_time=true) suffix = "_new" - timestep_symbol = :Δt + timestep_name = :Δt prob1 = UnitarySmoothPulseProblem(sys, GATES[:Y], T, Δt, piccolo_options=pi_false_ops, ipopt_options=ops) traj1 = direct_sum(prob1.trajectory, add_suffix(prob1.trajectory, suffix), free_time=true) # Direct sum (shared timestep name) - @test get_suffix(traj1, suffix).timestep == timestep_symbol - @test get_suffix(traj1, suffix, remove=true).timestep == timestep_symbol + @test get_suffix(traj1, suffix).timestep == timestep_name + @test get_suffix(traj1, suffix, remove=true).timestep == timestep_name prob2 = UnitarySmoothPulseProblem(sys, GATES[:Y], T, Δt, ipopt_options=ops, piccolo_options=pi_true_ops) traj2 = add_suffix(prob2.trajectory, suffix) # Trajectory (unique timestep name) - @test get_suffix(traj2, suffix).timestep == add_suffix(timestep_symbol, suffix) - @test get_suffix(traj2, suffix, remove=true).timestep == timestep_symbol + @test get_suffix(traj2, suffix).timestep == add_suffix(timestep_name, suffix) + @test get_suffix(traj2, suffix, remove=true).timestep == timestep_name end end # module diff --git a/src/problem_templates/_problem_templates.jl b/src/problem_templates/_problem_templates.jl index d509394..abb41cf 100644 --- a/src/problem_templates/_problem_templates.jl +++ b/src/problem_templates/_problem_templates.jl @@ -39,11 +39,11 @@ function apply_piccolo_options!( constraints::AbstractVector{<:AbstractConstraint}, piccolo_options::PiccoloOptions, traj::NamedTrajectory, - operator::OperatorType, + operator::Union{Nothing, OperatorType}, state_name::Symbol, timestep_name::Symbol ) - if piccolo_options.leakage_suppression + if !isnothing(operator) && piccolo_options.leakage_suppression state_names = [ name for name ∈ traj.names if startswith(string(name), string(state_name)) diff --git a/src/problem_templates/quantum_state_minimum_time_problem.jl b/src/problem_templates/quantum_state_minimum_time_problem.jl index ad28461..6deeaf5 100644 --- a/src/problem_templates/quantum_state_minimum_time_problem.jl +++ b/src/problem_templates/quantum_state_minimum_time_problem.jl @@ -2,9 +2,28 @@ export QuantumStateMinimumTimeProblem """ - QuantumStateMinimumTimeProblem + QuantumStateMinimumTimeProblem(traj, sys, obj, integrators, constraints; kwargs...) + QuantumStateMinimumTimeProblem(prob; kwargs...) + +Construct a `QuantumControlProblem` for the minimum time problem of reaching a target state. + +# Arguments +- `traj::NamedTrajectory`: The initial trajectory. +- `sys::QuantumSystem`: The quantum system. +- `obj::Objective`: The objective function. +- `integrators::Vector{<:AbstractIntegrator}`: The integrators. +- `constraints::Vector{<:AbstractConstraint}`: The constraints. +or +- `prob::QuantumControlProblem`: The quantum control problem. + +# Keyword Arguments +- `state_name::Symbol=:ψ̃`: The symbol for the state variables. +- `final_fidelity::Union{Real, Nothing}=nothing`: The final fidelity. +- `D=1.0`: The cost weight on the time. +- `ipopt_options::IpoptOptions=IpoptOptions()`: The Ipopt options. +- `piccolo_options::PiccoloOptions=PiccoloOptions()`: The Piccolo options. +- `kwargs...`: Additional keyword arguments, passed to [`QuantumControlProblem`](@ref). -TODO: Add documentation """ function QuantumStateMinimumTimeProblem end @@ -14,14 +33,14 @@ function QuantumStateMinimumTimeProblem( obj::Objective, integrators::Vector{<:AbstractIntegrator}, constraints::Vector{<:AbstractConstraint}; - state_symbol::Symbol=:ψ̃, + state_name::Symbol=:ψ̃, final_fidelity::Union{Real, Nothing}=nothing, D=1.0, ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), kwargs... ) - state_names = [name for name in traj.names if startswith(name, state_symbol)] + state_names = [name for name in traj.names if startswith(name, state_name)] @assert length(state_names) ≥ 1 "No matching states found in trajectory" obj += MinimumTimeObjective(traj; D=D, eval_hessian=piccolo_options.eval_hessian) diff --git a/src/problem_templates/quantum_state_smooth_pulse_problem.jl b/src/problem_templates/quantum_state_smooth_pulse_problem.jl index 6e94845..027097b 100644 --- a/src/problem_templates/quantum_state_smooth_pulse_problem.jl +++ b/src/problem_templates/quantum_state_smooth_pulse_problem.jl @@ -2,36 +2,55 @@ export QuantumStateSmoothPulseProblem """ - QuantumStateSmoothPulseProblem( - system::AbstractQuantumSystem, - ψ_init::Union{AbstractVector{<:Number}, Vector{<:AbstractVector{<:Number}}}, - ψ_goal::Union{AbstractVector{<:Number}, Vector{<:AbstractVector{<:Number}}}, - T::Int, - Δt::Float64; - kwargs... - ) + QuantumStateSmoothPulseProblem(system, ψ_inits, ψ_goals, T, Δt; kwargs...) - QuantumStateSmoothPulseProblem( - H_drift::AbstractMatrix{<:Number}, - H_drives::Vector{<:AbstractMatrix{<:Number}}, - args...; - kwargs... - ) +Create a quantum state smooth pulse problem. The goal is to find a control pulse +`a(t)` that drives all of the initial states `ψ_inits` to the corresponding +target states `ψ_goals` using `T` timesteps of size `Δt`. This problem also controls the first and second derivatives of the control pulse, `da(t)` and `dda(t)`, to ensure smoothness. -Create a quantum control problem for smooth pulse optimization of a quantum state trajectory. +# Arguments +- `system::AbstractQuantumSystem`: The quantum system. +- `ψ_inits::Vector{<:AbstractVector{<:ComplexF64}}`: The initial states. +- `ψ_goals::Vector{<:AbstractVector{<:ComplexF64}}`: The target states. +- `T::Int`: The number of timesteps. +- `Δt::Float64`: The timestep size. -TODO: Document args +# Keyword Arguments +- `ipopt_options::IpoptOptions=IpoptOptions()`: The IPOPT options. +- `piccolo_options::PiccoloOptions=PiccoloOptions()`: The Piccolo options. +- `state_name::Symbol=:ψ̃`: The name of the state variable. +- `control_name::Symbol=:a`: The name of the control variable. +- `timestep_name::Symbol=:Δt`: The name of the timestep variable. +- `init_trajectory::Union{NamedTrajectory, Nothing}=nothing`: The initial trajectory. +- `a_bound::Float64=1.0`: The bound on the control pulse. +- `a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives))`: The bounds on the control pulse. +- `a_guess::Union{Matrix{Float64}, Nothing}=nothing`: The initial guess for the control pulse. +- `da_bound::Float64=Inf`: The bound on the first derivative of the control pulse. +- `da_bounds::Vector{Float64}=fill(da_bound, length(system.G_drives))`: The bounds on the first derivative of the control pulse. +- `dda_bound::Float64=1.0`: The bound on the second derivative of the control pulse. +- `dda_bounds::Vector{Float64}=fill(dda_bound, length(system.G_drives))`: The bounds on the second derivative of the control pulse. +- `Δt_min::Float64=0.5 * Δt`: The minimum timestep size. +- `Δt_max::Float64=1.5 * Δt`: The maximum timestep size. +- `drive_derivative_σ::Float64=0.01`: The standard deviation of the drive derivative random initialization. +- `Q::Float64=100.0`: The weight on the state objective. +- `R=1e-2`: The weight on the control pulse and its derivatives. +- `R_a::Union{Float64, Vector{Float64}}=R`: The weight on the control pulse. +- `R_da::Union{Float64, Vector{Float64}}=R`: The weight on the first derivative of the control pulse. +- `R_dda::Union{Float64, Vector{Float64}}=R`: The weight on the second derivative of the control pulse. +- `leakage_operator::Union{Nothing, EmbeddedOperator}=nothing`: The leakage operator, if leakage suppression is desired. +- `constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]`: The constraints. """ -function QuantumStateSmoothPulseProblem end - function QuantumStateSmoothPulseProblem( system::AbstractQuantumSystem, - ψ_init::Union{AbstractVector{<:ComplexF64}, Vector{<:AbstractVector{<:ComplexF64}}}, - ψ_goal::Union{AbstractVector{<:ComplexF64}, Vector{<:AbstractVector{<:ComplexF64}}}, + ψ_inits::Vector{<:AbstractVector{<:ComplexF64}}, + ψ_goals::Vector{<:AbstractVector{<:ComplexF64}}, T::Int, Δt::Float64; ipopt_options::IpoptOptions=IpoptOptions(), piccolo_options::PiccoloOptions=PiccoloOptions(), + state_name::Symbol=:ψ̃, + control_name::Symbol=:a, + timestep_name::Symbol=:Δt, init_trajectory::Union{NamedTrajectory, Nothing}=nothing, a_bound::Float64=1.0, a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives)), @@ -48,32 +67,18 @@ function QuantumStateSmoothPulseProblem( R_a::Union{Float64, Vector{Float64}}=R, R_da::Union{Float64, Vector{Float64}}=R, R_dda::Union{Float64, Vector{Float64}}=R, - R_L1::Float64=20.0, + leakage_operator::Union{Nothing, EmbeddedOperator}=nothing, constraints::Vector{<:AbstractConstraint}=AbstractConstraint[], - L1_regularized_names=Symbol[], - L1_regularized_indices::NamedTuple=NamedTuple(), kwargs... ) - @assert all(name ∈ L1_regularized_names for name in keys(L1_regularized_indices) if !isempty(L1_regularized_indices[name])) - - if ψ_init isa AbstractVector{<:Number} && ψ_goal isa AbstractVector{<:Number} - ψ_inits = [ψ_init] - ψ_goals = [ψ_goal] - else - @assert length(ψ_init) == length(ψ_goal) - ψ_inits = ψ_init - ψ_goals = ψ_goal - end - - ψ̃_inits = ket_to_iso.(Vector{ComplexF64}.(ψ_inits)) - ψ̃_goals = ket_to_iso.(Vector{ComplexF64}.(ψ_goals)) - - n_drives = length(system.G_drives) + @assert length(ψ_inits) == length(ψ_goals) # Trajectory if !isnothing(init_trajectory) traj = init_trajectory else + n_drives = length(system.G_drives) + traj = initialize_trajectory( ψ_goals, ψ_inits, @@ -81,6 +86,9 @@ function QuantumStateSmoothPulseProblem( Δt, n_drives, (a_bounds, da_bounds, dda_bounds); + state_name=state_name, + control_name=control_name, + timestep_name=timestep_name, free_time=piccolo_options.free_time, Δt_bounds=(Δt_min, Δt_max), drive_derivative_σ=drive_derivative_σ, @@ -91,60 +99,94 @@ function QuantumStateSmoothPulseProblem( end # Objective - J = QuadraticRegularizer(:a, traj, R_a) - J += QuadraticRegularizer(:da, traj, R_da) - J += QuadraticRegularizer(:dda, traj, R_dda) + control_names = [ + name for name ∈ traj.names + if endswith(string(name), string(control_name)) + ] + + J = QuadraticRegularizer(control_names[1], traj, R_a; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[2], traj, R_da; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[3], traj, R_dda; timestep_name=timestep_name) if length(ψ_inits) == 1 - J += QuantumStateObjective(:ψ̃, traj, Q) + J += QuantumStateObjective(state_name, traj, Q) else + state_names = [ + name for name ∈ traj.names + if startswith(string(name), string(state_name)) + ] + @assert length(state_names) == length(ψ_inits) "Number of states must match number of initial states" for i = 1:length(ψ_inits) - J += QuantumStateObjective(Symbol("ψ̃$i"), traj, Q) - end - end - - # Constraints - for name in L1_regularized_names - if name in keys(L1_regularized_indices) - J += L1Regularizer!( - constraints, name, traj, - R_value=R_L1, - indices=L1_regularized_indices[name], - eval_hessian=piccolo_options.eval_hessian - ) - else - J += L1Regularizer!( - constraints, name, traj; - R_value=R_L1, - eval_hessian=piccolo_options.eval_hessian - ) - end - end - - if piccolo_options.free_time - if piccolo_options.timesteps_all_equal - push!(constraints, TimeStepsAllEqualConstraint(:Δt, traj)) + J += QuantumStateObjective(state_names[i], traj, Q) end end # Integrators if length(ψ_inits) == 1 - ψ̃_integrators = [ - QuantumStatePadeIntegrator(system, :ψ̃, :a, traj) - ] + if piccolo_options.integrator == :pade + state_integrators = [QuantumStatePadeIntegrator( + system, + state_name, + control_name, + traj; + order=piccolo_options.pade_order + )] + elseif piccolo_options.integrator == :exponential + state_integrators = [QuantumStateExponentialIntegrator( + system, + state_name, + control_name, + traj + )] + else + error("integrator must be one of (:pade, :exponential)") + end else - ψ̃_integrators = [ - QuantumStatePadeIntegrator(system, Symbol("ψ̃$i"), :a, traj) - for i = 1:length(ψ_inits) + state_names = [ + name for name ∈ traj.names + if startswith(string(name), string(state_name)) ] + state_integrators = [] + for i = 1:length(ψ_inits) + if piccolo_options.integrator == :pade + state_integrator = QuantumStatePadeIntegrator( + system, + state_names[i], + control_name, + traj; + order=piccolo_options.pade_order + ) + elseif piccolo_options.integrator == :exponential + state_integrator = QuantumStateExponentialIntegrator( + system, + state_names[i], + control_name, + traj + ) + else + error("integrator must be one of (:pade, :exponential)") + end + push!(state_integrators, state_integrator) + end end integrators = [ - ψ̃_integrators..., - DerivativeIntegrator(:a, :da, traj), - DerivativeIntegrator(:da, :dda, traj) + state_integrators..., + DerivativeIntegrator(control_name, control_names[2], traj), + DerivativeIntegrator(control_names[2], control_names[3], traj) ] + # Optional Piccolo constraints and objectives + apply_piccolo_options!( + J, + constraints, + piccolo_options, + traj, + leakage_operator, + state_name, + timestep_name + ) + return QuantumControlProblem( system, traj, @@ -157,6 +199,16 @@ function QuantumStateSmoothPulseProblem( ) end +function QuantumStateSmoothPulseProblem( + system::AbstractQuantumSystem, + ψ_init::AbstractVector{<:ComplexF64}, + ψ_goal::AbstractVector{<:ComplexF64}, + args...; + kwargs... +) + return QuantumStateSmoothPulseProblem(system, [ψ_init], [ψ_goal], args...; kwargs...) +end + function QuantumStateSmoothPulseProblem( H_drift::AbstractMatrix{<:Number}, H_drives::Vector{<:AbstractMatrix{<:Number}}, @@ -239,3 +291,25 @@ end final = fidelity(prob) @test all(final .> initial) end + +@testitem "Test quantum state with multiple initial states and final states" begin + # System + T = 50 + Δt = 0.2 + sys = QuantumSystem(0.1 * GATES[:Z], [GATES[:X], GATES[:Y]]) + ψ_inits = Vector{ComplexF64}.([[1.0, 0.0], [0.0, 1.0]]) + ψ_targets = Vector{ComplexF64}.([[0.0, 1.0], [1.0, 0.0]]) + + prob = QuantumStateSmoothPulseProblem( + sys, ψ_inits, ψ_targets, T, Δt; + ipopt_options=IpoptOptions(print_level=1), + piccolo_options=PiccoloOptions(verbose=false), + state_name=:psi, + control_name=:u, + timestep_name=:dt + ) + initial = fidelity(prob) + solve!(prob, max_iter=20) + final = fidelity(prob) + @test all(final .> initial) +end diff --git a/src/problem_templates/unitary_bang_bang_problem.jl b/src/problem_templates/unitary_bang_bang_problem.jl index d0e2d8d..ac05a25 100644 --- a/src/problem_templates/unitary_bang_bang_problem.jl +++ b/src/problem_templates/unitary_bang_bang_problem.jl @@ -43,28 +43,26 @@ with # Keyword Arguments - `ipopt_options::IpoptOptions=IpoptOptions()`: the options for the Ipopt solver - `piccolo_options::PiccoloOptions=PiccoloOptions()`: the options for the Piccolo solver -- `constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]`: the constraints to enforce +- `state_name::Symbol = :Ũ⃗`: the name of the state variable +- `control_name::Symbol = :a`: the name of the control variable +- `timestep_name::Symbol = :Δt`: the name of the timestep variable - `init_trajectory::Union{NamedTrajectory, Nothing}=nothing`: an initial trajectory to use - `a_bound::Float64=1.0`: the bound on the control pulse -- `a_bounds::Vector{Float64}=fill(a_bound, length(system.G_drives))`: the bounds on the control pulses, one for each drive +- `a_bounds=fill(a_bound, length(system.G_drives))`: the bounds on the control pulses, one for each drive - `a_guess::Union{Matrix{Float64}, Nothing}=nothing`: an initial guess for the control pulses - `da_bound::Float64=1.0`: the bound on the control pulse derivative -- `da_bounds::Vector{Float64}=fill(da_bound, length(system.G_drives))`: the bounds on the control pulse derivatives, one for each drive -- `Δt_min::Float64=0.5 * Δt`: the minimum time step size -- `Δt_max::Float64=1.5 * Δt`: the maximum time step size +- `da_bounds=fill(da_bound, length(system.G_drives))`: the bounds on the control pulse derivatives, one for each drive +- `Δt_min::Float64=Δt isa Float64 ? 0.5 * Δt : 0.5 * mean(Δt)`: the minimum time step size +- `Δt_max::Float64=Δt isa Float64 ? 1.5 * Δt : 1.5 * mean(Δt)`: the maximum time step size - `drive_derivative_σ::Float64=0.01`: the standard deviation of the initial guess for the control pulse derivatives - `Q::Float64=100.0`: the weight on the infidelity objective - `R=1e-2`: the weight on the regularization terms +- `quadratic_control_regularization=false`: whether or not to use quadratic regularization for the control pulses - `R_a::Union{Float64, Vector{Float64}}=R`: the weight on the regularization term for the control pulses - `R_da::Union{Float64, Vector{Float64}}=R`: the weight on the regularization term for the control pulse derivatives -- `R_bang_bang::Union{Float64, Vector{Float64}}=1.0`: the weight on the bang-bang regularization term -- `leakage_suppression::Bool=false`: whether or not to suppress leakage to higher energy states -- `R_leakage=1e-1`: the weight on the leakage suppression term -- `bound_state=integrator == :exponential`: whether or not to bound the unitary -- `control_norm_constraint=false`: whether or not to enforce a constraint on the control pulse norm -- `control_norm_constraint_components=nothing`: the components of the control pulse to use for the norm constraint -- `control_norm_R=nothing`: the weight on the control pulse norm constraint - +- `R_bang_bang::Union{Float64, Vector{Float64}}=1e-1`: the weight on the bang-bang regularization term +- `global_data::Union{NamedTuple, Nothing}=nothing`: global data to be used in the problem +- `constraints::Vector{<:AbstractConstraint}=AbstractConstraint[]`: the constraints to enforce TODO: control modulus norm, advanced feature, needs documentation @@ -90,6 +88,7 @@ function UnitaryBangBangProblem( drive_derivative_σ::Float64=0.01, Q::Float64=100.0, R=1e-2, + quadratic_control_regularization=false, R_a::Union{Float64, Vector{Float64}}=R, R_da::Union{Float64, Vector{Float64}}=R, R_bang_bang::Union{Float64, Vector{Float64}}=1e-1, @@ -148,8 +147,11 @@ function UnitaryBangBangProblem( if endswith(string(name), string(control_name)) ] - J += QuadraticRegularizer(control_names[1], traj, R_a) - J += QuadraticRegularizer(control_names[2], traj, R_da) + # TODO: do we need these regularizers? + if quadratic_control_regularization + J += QuadraticRegularizer(control_names[1], traj, R_a; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[2], traj, R_da; timestep_name=timestep_name) + end # Constraints if R_bang_bang isa Float64 diff --git a/src/problem_templates/unitary_sampling_problem.jl b/src/problem_templates/unitary_sampling_problem.jl index 6f35d76..6d32fd2 100644 --- a/src/problem_templates/unitary_sampling_problem.jl +++ b/src/problem_templates/unitary_sampling_problem.jl @@ -116,9 +116,9 @@ function UnitarySamplingProblem( subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing ) end - J += QuadraticRegularizer(control_names[1], traj, R_a) - J += QuadraticRegularizer(control_names[2], traj, R_da) - J += QuadraticRegularizer(control_names[3], traj, R_dda) + J += QuadraticRegularizer(control_names[1], traj, R_a; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[2], traj, R_da; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[3], traj, R_dda; timestep_name=timestep_name) # Constraints if piccolo_options.leakage_suppression diff --git a/src/problem_templates/unitary_smooth_pulse_problem.jl b/src/problem_templates/unitary_smooth_pulse_problem.jl index a919db1..f0d30f0 100644 --- a/src/problem_templates/unitary_smooth_pulse_problem.jl +++ b/src/problem_templates/unitary_smooth_pulse_problem.jl @@ -138,7 +138,7 @@ function UnitarySmoothPulseProblem( operator.operator : operator ), - phase_operators=[GATES[:Z] for _ in eachindex(traj.global_components[:ϕ])], + phase_operators=fill(GATES[:Z], length(traj.global_components[:ϕ])), Q=Q, eval_hessian=piccolo_options.eval_hessian, subspace=operator isa EmbeddedOperator ? operator.subspace_indices : nothing @@ -150,9 +150,9 @@ function UnitarySmoothPulseProblem( if endswith(string(name), string(control_name)) ] - J += QuadraticRegularizer(control_names[1], traj, R_a) - J += QuadraticRegularizer(control_names[2], traj, R_da) - J += QuadraticRegularizer(control_names[3], traj, R_dda) + J += QuadraticRegularizer(control_names[1], traj, R_a; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[2], traj, R_da; timestep_name=timestep_name) + J += QuadraticRegularizer(control_names[3], traj, R_dda; timestep_name=timestep_name) # Integrators if piccolo_options.integrator == :pade diff --git a/src/trajectory_initialization.jl b/src/trajectory_initialization.jl index b09f8e9..f6e1bc6 100644 --- a/src/trajectory_initialization.jl +++ b/src/trajectory_initialization.jl @@ -357,7 +357,7 @@ function initialize_trajectory( push!(names, timestep_name) push!(values, Δt) controls = (control_names[end], timestep_name) - bounds = merge(bounds, (Δt = Δt_bounds,)) + bounds = merge(bounds, (; timestep_name => Δt_bounds,)) else controls = (control_names[end],) end @@ -548,99 +548,6 @@ function initialize_trajectory( end - -function initialize_quantum_state_trajectory( - ψ̃_goals::AbstractVector{<:AbstractVector{<:Real}}, - ψ̃_inits::AbstractVector{<:AbstractVector{<:Real}}, - T::Int, - Δt::Union{Real, AbstractVector{<:Real}}, - n_drives::Int, - all_a_bounds::NamedTuple{anames, <:Tuple{Vararg{VectorBound}}} where anames; - n_derivatives::Int=3, - free_time=false, - Δt_bounds::ScalarBound=(1.5 * Δt, 1.5 * Δt), - drive_derivative_σ::Float64=0.1, - a_guess::Union{AbstractMatrix{<:Float64}, Nothing}=nothing, - system::Union{AbstractQuantumSystem, AbstractVector{<:AbstractQuantumSystem}, Nothing}=nothing, - global_data::Union{NamedTuple, Nothing}=nothing, - rollout_integrator::Function=exp, - ψ̃_keys::AbstractVector{<:Symbol}=[Symbol("ψ̃$i") for i = 2:length(ψ̃_goals)], - a_keys::AbstractVector{<:Symbol}=[Symbol("d"^i * "a") for i = 1:n_derivatives] -) - @assert length(ψ̃_inits) == length(ψ̃_goals) "ψ̃_inits and ψ̃_goals must have the same length" - @assert length(ψ̃_keys) == length(ψ̃_goals) "ψ̃_keys and ψ̃_goals must have the same length" - - if free_time - if Δt isa Real - Δt = fill(Δt, 2, T) - elseif Δt isa AbstractVector - Δt = reshape(Δt, 2, :) - else - @assert size(Δt) == (2, T) "Δt must be a Real, AbstractVector, or 1x$(T) AbstractMatrix" - end - end - - # Constraints - state_initial = (; (ψ̃_keys .=> ψ̃_inits)...) - control_initial = (a = zeros(n_drives),) - initial = merge(state_initial, control_initial) - - final = (a = zeros(n_drives),) - - goal = (; (ψ̃_keys .=> ψ̃_goals)...) - - # Bounds - bounds = all_a_bounds - - # Initial state and control values - if isnothing(a_guess) - ψ̃_values = NamedTuple([ - k => linear_interpolation(ψ̃_init, ψ̃_goal, T) - for (k, ψ̃_init, ψ̃_goal) in zip(ψ̃_keys, ψ̃_inits, ψ̃_goals) - ]) - a_values = initialize_controls( - n_drives, - n_derivatives, - T, - bounds[a_keys[2]], - drive_derivative_σ - ) - else - ψ̃_values = NamedTuple([ - k => rollout(ψ̃_init, a_guess, Δt, system, integrator=rollout_integrator) - for (k, ψ̃_init) in zip(ψ̃_keys, ψ̃_inits) - ]) - a_values = initialize_controls(a_guess, Δt, n_derivatives) - end - - # Trajectory - keys = [ψ̃_keys..., a_keys...] - values = [ψ̃_values..., a_values...] - - if free_time - push!(keys, :Δt) - push!(values, Δt) - controls = (a_keys[end], :Δt) - timestep = :Δt - bounds = merge(bounds, (Δt = Δt_bounds,)) - else - controls = (a_keys[end],) - @assert Δt isa Real "Δt must be a Real if free_time is false" - timestep = Δt - end - - return NamedTrajectory( - (; (keys .=> values)...); - controls=controls, - timestep=timestep, - bounds=bounds, - initial=initial, - final=final, - goal=goal, - global_data=isnothing(global_data) ? (;) : global_data - ) -end - # ============================================================================= # remove_component( From 91b0f81e72be9a6c9fa96dde2d1293a64a409e11 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 16:35:27 -0400 Subject: [PATCH 21/35] renamed symbol to name --- src/objectives/regularizer_objective.jl | 28 ++++++++++++------------- src/trajectory_interpolations.jl | 14 ++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/objectives/regularizer_objective.jl b/src/objectives/regularizer_objective.jl index c9339fa..7cabf28 100644 --- a/src/objectives/regularizer_objective.jl +++ b/src/objectives/regularizer_objective.jl @@ -13,7 +13,7 @@ export PairwiseQuadraticRegularizer QuadraticRegularizer A quadratic regularizer for a trajectory component. - + Fields: `name`: the name of the trajectory component to regularize `times`: the times at which to evaluate the regularizer @@ -21,7 +21,7 @@ Fields: `R`: the regularization matrix `baseline`: the baseline values for the trajectory component `eval_hessian`: whether to evaluate the Hessian of the regularizer - `timestep_symbol`: the symbol for the timestep variable + `timestep_name`: the symbol for the timestep variable """ function QuadraticRegularizer(; name::Union{Nothing, Symbol}=nothing, @@ -30,7 +30,7 @@ function QuadraticRegularizer(; R::Union{Nothing, AbstractVector{<:Real}}=nothing, baseline::Union{Nothing, AbstractArray{<:Real}}=nothing, eval_hessian::Bool=true, - timestep_symbol::Symbol=:Δt + timestep_name::Symbol=:Δt ) @assert !isnothing(name) "name must be specified" @@ -59,7 +59,7 @@ function QuadraticRegularizer(; J = 0.0 for t ∈ times if Z.timestep isa Symbol - Δt = Z⃗[slice(t, Z.components[timestep_symbol], Z.dim)] + Δt = Z⃗[slice(t, Z.components[timestep_name], Z.dim)] else Δt = Z.timestep end @@ -80,7 +80,7 @@ function QuadraticRegularizer(; Δv = Z⃗[vₜ_slice] .- baseline[:, t] if Z.timestep isa Symbol - Δt_slice = slice(t, Z.components[timestep_symbol], Z.dim) + Δt_slice = slice(t, Z.components[timestep_name], Z.dim) Δt = Z⃗[Δt_slice] ∇[Δt_slice] .= Δv' * (R .* (Δt .* Δv)) else @@ -106,7 +106,7 @@ function QuadraticRegularizer(; append!(structure, vₜ_vₜ_inds) if Z.timestep isa Symbol - Δt_slice = slice(t, Z.components[timestep_symbol], Z.dim) + Δt_slice = slice(t, Z.components[timestep_name], Z.dim) # ∂²_vₜ_Δt vₜ_Δt_inds = [(i, j) for i ∈ vₜ_slice for j ∈ Δt_slice] append!(structure, vₜ_Δt_inds) @@ -126,7 +126,7 @@ function QuadraticRegularizer(; # Match Hessian structure indices for t ∈ times if Z.timestep isa Symbol - Δt = Z⃗[slice(t, Z.components[timestep_symbol], Z.dim)] + Δt = Z⃗[slice(t, Z.components[timestep_name], Z.dim)] append!(values, R .* Δt.^2) # ∂²_vₜ_Δt, ∂²_Δt_vₜ vₜ = Z⃗[slice(t, Z.components[name], Z.dim)] @@ -433,7 +433,7 @@ regularization strength `R`. The regularizer is defined as J_{v⃗}(u) = \sum_t \frac{1}{2} \Delta t_t^2 (v⃗_{1,t} - v⃗_{2,t})^T R (v⃗_{1,t} - v⃗_{2,t}) ``` -where $v⃗_{1}$ and $v⃗_{2}$ are selected by `name1` and `name2`. The indices specify the +where $v⃗_{1}$ and $v⃗_{2}$ are selected by `name1` and `name2`. The indices specify the appropriate block diagonal components of the direct sum vector `v⃗`. TODO: Hessian not implemented @@ -444,7 +444,7 @@ Fields: `times`: the time steps to apply the regularizer `name1`: the first name `name2`: the second name - `timestep_symbol`: the symbol for the timestep + `timestep_name`: the symbol for the timestep `eval_hessian`: whether to evaluate the Hessian """ function PairwiseQuadraticRegularizer( @@ -452,7 +452,7 @@ function PairwiseQuadraticRegularizer( times::AbstractVector{Int}, name1::Symbol, name2::Symbol; - timestep_symbol::Symbol=:Δt, + timestep_name::Symbol=:Δt, eval_hessian::Bool=false, ) params = Dict( @@ -467,7 +467,7 @@ function PairwiseQuadraticRegularizer( J = 0.0 for t ∈ times if Z.timestep isa Symbol - Δt = Z⃗[slice(t, Z.components[timestep_symbol], Z.dim)] + Δt = Z⃗[slice(t, Z.components[timestep_name], Z.dim)] else Δt = Z.timestep end @@ -488,7 +488,7 @@ function PairwiseQuadraticRegularizer( z2_t = Z⃗[z2_t_slice] if Z.timestep isa Symbol - Δt_slice = slice(t, Z.components[timestep_symbol], Z.dim) + Δt_slice = slice(t, Z.components[timestep_name], Z.dim) Δt = Z⃗[Δt_slice] ∇[Δt_slice] .= (z1_t .- z2_t)' * (R .* (Δt .* (z1_t .- z2_t))) else @@ -515,7 +515,7 @@ end @doc raw""" PairwiseQuadraticRegularizer -A convenience constructor for creating a PairwiseQuadraticRegularizer for the +A convenience constructor for creating a PairwiseQuadraticRegularizer for the trajectory component `name` with regularization strength `Rs` over the graph `graph`. """ function PairwiseQuadraticRegularizer( @@ -567,7 +567,7 @@ end include("../../test/test_utils.jl") T = 10 - + Z = NamedTrajectory( (ψ̃ = randn(4, T), u = randn(2, T)), controls=:u, diff --git a/src/trajectory_interpolations.jl b/src/trajectory_interpolations.jl index 365a9b4..4b313a0 100644 --- a/src/trajectory_interpolations.jl +++ b/src/trajectory_interpolations.jl @@ -16,9 +16,9 @@ struct DataInterpolation values_components::Vector{Int} function DataInterpolation( - times::AbstractVector{Float64}, values::AbstractMatrix{Float64}; + times::AbstractVector{Float64}, values::AbstractMatrix{Float64}; timestep_components::AbstractVector{Int}=Int[], kind::Symbol=:linear - ) + ) comps = setdiff(1:size(values, 1), timestep_components) if kind == :linear interpolants = [linear_interpolation(times, values[c, :]) for c in comps] @@ -38,10 +38,10 @@ struct DataInterpolation end function DataInterpolation( - traj::NamedTrajectory; timestep_symbol::Symbol=:Δt, kwargs... + traj::NamedTrajectory; timestep_name::Symbol=:Δt, kwargs... ) - if timestep_symbol ∈ keys(traj.components) - timestep_components = traj.components[timestep_symbol] + if timestep_name ∈ keys(traj.components) + timestep_components = traj.components[timestep_name] else timestep_components = Int[] end @@ -90,7 +90,7 @@ end interp = DataInterpolation(free_traj) new_free_data = interp(get_times(traj)) - # Replace the final timestep with the original value (can't be known a priori) + # Replace the final timestep with the original value (can't be known a priori) new_free_data[free_traj.components.Δt, end] = free_traj.data[free_traj.components.Δt, end] @test new_free_data ≈ free_traj.data @@ -116,4 +116,4 @@ end end -end \ No newline at end of file +end From e9bade2f3746f0426e9e41821259b99744f52f9f Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 16:35:36 -0400 Subject: [PATCH 22/35] docs updates --- docs/src/lib.md | 76 ++++++++++++++++++++++++++++++++++++++++-- src/quantum_systems.jl | 10 +----- 2 files changed, 74 insertions(+), 12 deletions(-) diff --git a/docs/src/lib.md b/docs/src/lib.md index b517605..5b712e8 100644 --- a/docs/src/lib.md +++ b/docs/src/lib.md @@ -1,11 +1,21 @@ # Library -## QuantumUtils +## Problem Templates ```@autodocs -Modules = [QuantumCollocation.QuantumUtils] +Modules = [QuantumCollocation.ProblemTemplates] ``` -## QuantumSystems +## Direct Sums +```@autodocs +Modules = [QuantumCollocation.DirectSums] +``` + +## Quantum Object Utils +```@autodocs +Modules = [QuantumCollocation.QuantumObjectUtils] +``` + +## Quantum Systems ```@autodocs Modules = [QuantumCollocation.QuantumSystems] ``` @@ -14,3 +24,63 @@ Modules = [QuantumCollocation.QuantumSystems] ```@autodocs Modules = [QuantumCollocation.Integrators] ``` + +## Objectives +```@autodocs +Modules = [QuantumCollocation.Objectives] +``` + +## Losses +```@autodocs +Modules = [QuantumCollocation.Losses] +``` + +## Embedded Operators +```@autodocs +Modules = [QuantumCollocation.EmbeddedOperators] +``` + +## Isomorphisms +```@autodocs +Modules = [QuantumCollocation.Isomorphisms] +``` + +## Options +```@autodocs +Modules = [QuantumCollocation.Options] +``` + +## Plotting +```@autodocs +Modules = [QuantumCollocation.Plotting] +``` + +## Problem Solvers +```@autodocs +Modules = [QuantumCollocation.ProblemSolvers] +``` + +## Rollouts +```@autodocs +Modules = [QuantumCollocation.Rollouts] +``` + +## Saving and Loading +```@autodocs +Modules = [QuantumCollocation.SaveLoadUtils] +``` + +## Structure Utils +```@autodocs +Modules = [QuantumCollocation.StructureUtils] +``` + +## Trajectory Initialization +```@autodocs +Modules = [QuantumCollocation.TrajectoryInitialization] +``` + +## Trajectory Interpolations +```@autodocs +Modules = [QuantumCollocation.TrajectoryInterpolations] +``` \ No newline at end of file diff --git a/src/quantum_systems.jl b/src/quantum_systems.jl index fe52c2a..105ba50 100644 --- a/src/quantum_systems.jl +++ b/src/quantum_systems.jl @@ -25,15 +25,7 @@ using TestItemRunner # ----------------------------------------------------------------------------- # """ -```julia -AbstractQuantumSystem -``` - | - -> EmbeddedOperator - | | - | -> QuantumObjective - | | - -> Matrix (goal) - + AbstractQuantumSystem Abstract type for defining systems. """ From f59f011b17e663ded3509ef2a591889c9f70f1ed Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 16:42:44 -0400 Subject: [PATCH 23/35] adding manifest to .gitignore --- .gitignore | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 36868b0..62c32b7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,8 +2,5 @@ *.jl.cov *.jl.mem /docs/build/ -/examples/**/plots/ -/examples/**/trajectories/ -pardiso.lic -/.CondaPkg/ -*.code-workspace \ No newline at end of file +*.code-workspace +manifest.toml \ No newline at end of file From 832490948382cd9a39db15528fc5b2aaae03db2c Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 16:59:43 -0400 Subject: [PATCH 24/35] version bump --- Manifest.toml | 94 +++++++++++++++++++++++++-------------------------- Project.toml | 2 +- 2 files changed, 48 insertions(+), 48 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index de5b92d..9c38a58 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -5,9 +5,9 @@ manifest_format = "2.0" project_hash = "0e1b56171c4e825157ede62be9481fa3374601e7" [[deps.ADTypes]] -git-tree-sha1 = "5a5eafb8344b81b8c2237f8a6f6b3602b3f6180e" +git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081" uuid = "47edcb42-4c32-4615-8424-f2b9edc5f35b" -version = "1.8.1" +version = "1.9.0" [deps.ADTypes.extensions] ADTypesChainRulesCoreExt = "ChainRulesCore" @@ -211,15 +211,15 @@ version = "1.1.0" [[deps.CairoMakie]] deps = ["CRC32c", "Cairo", "Cairo_jll", "Colors", "FileIO", "FreeType", "GeometryBasics", "LinearAlgebra", "Makie", "PrecompileTools"] -git-tree-sha1 = "4f827b38d3d9ffe6e3b01fbcf866c625fa259ca5" +git-tree-sha1 = "2b04b60ed9d3e977f93e34952971b608c34b3401" uuid = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0" -version = "0.12.11" +version = "0.12.13" [[deps.Cairo_jll]] deps = ["Artifacts", "Bzip2_jll", "CompilerSupportLibraries_jll", "Fontconfig_jll", "FreeType2_jll", "Glib_jll", "JLLWrappers", "LZO_jll", "Libdl", "Pixman_jll", "Xorg_libXext_jll", "Xorg_libXrender_jll", "Zlib_jll", "libpng_jll"] -git-tree-sha1 = "a2f1c8c668c8e3cb4cca4e57a8efdb09067bb3fd" +git-tree-sha1 = "009060c9a6168704143100f36ab08f06c2af4642" uuid = "83423d85-b0ee-5818-9007-b63ccbeb887a" -version = "1.18.0+2" +version = "1.18.2+1" [[deps.ChainRulesCore]] deps = ["Compat", "LinearAlgebra"] @@ -370,10 +370,10 @@ deps = ["Printf"] uuid = "ade2ca70-3891-5945-98fb-dc099432e06a" [[deps.DelaunayTriangulation]] -deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "Random"] -git-tree-sha1 = "94eb20e6621600f4315813b1d1fc9b8a5a6a34db" +deps = ["AdaptivePredicates", "EnumX", "ExactPredicates", "PrecompileTools", "Random"] +git-tree-sha1 = "668bb97ea6df5e654e6288d87d2243591fe68665" uuid = "927a84f5-c5f4-47a5-9785-b46e178433df" -version = "1.4.0" +version = "1.6.0" [[deps.DiffResults]] deps = ["StaticArraysCore"] @@ -393,9 +393,9 @@ uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" [[deps.Distributions]] deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"] -git-tree-sha1 = "e6c693a0e4394f8fda0e51a5bdf5aef26f8235e9" +git-tree-sha1 = "d7477ecdafb813ddee2ae727afa94e9dcb5f3fb0" uuid = "31c24e10-a181-5473-b8eb-7969acd0382f" -version = "0.25.111" +version = "0.25.112" [deps.Distributions.extensions] DistributionsChainRulesCoreExt = "ChainRulesCore" @@ -499,9 +499,9 @@ version = "1.8.0" [[deps.FFTW_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "c6033cc3892d0ef5bb9cd29b7f2f0331ea5184ea" +git-tree-sha1 = "4d81ed14783ec49ce9f2e168208a12ce1815aa25" uuid = "f5851436-0d7a-5f13-b9de-f02708fd171a" -version = "3.3.10+0" +version = "3.3.10+1" [[deps.FileIO]] deps = ["Pkg", "Requires", "UUIDs"] @@ -620,9 +620,9 @@ version = "0.4.2" [[deps.GeoInterface]] deps = ["Extents", "GeoFormatTypes"] -git-tree-sha1 = "5921fc0704e40c024571eca551800c699f86ceb4" +git-tree-sha1 = "2f6fce56cdb8373637a6614e14a5768a88450de2" uuid = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" -version = "1.3.6" +version = "1.3.7" [[deps.GeometryBasics]] deps = ["EarCut_jll", "Extents", "GeoInterface", "IterTools", "LinearAlgebra", "StaticArrays", "StructArrays", "Tables"] @@ -638,9 +638,9 @@ version = "0.21.0+0" [[deps.Glib_jll]] deps = ["Artifacts", "Gettext_jll", "JLLWrappers", "Libdl", "Libffi_jll", "Libiconv_jll", "Libmount_jll", "PCRE2_jll", "Zlib_jll"] -git-tree-sha1 = "7c82e6a6cd34e9d935e9aa4051b66c6ff3af59ba" +git-tree-sha1 = "674ff0db93fffcd11a3573986e550d66cd4fd71f" uuid = "7746bdde-850d-59dc-9ae8-88ece973131d" -version = "2.80.2+0" +version = "2.80.5+0" [[deps.Graphics]] deps = ["Colors", "LinearAlgebra", "NaNMath"] @@ -673,9 +673,9 @@ version = "8.3.1+0" [[deps.Hwloc_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "5e19e1e4fa3e71b774ce746274364aef0234634e" +git-tree-sha1 = "dd3b49277ec2bb2c6b94eb1604d4d0616016f7a6" uuid = "e33a78d0-f292-5ffc-b300-72abe9b543c8" -version = "2.11.1+0" +version = "2.11.2+0" [[deps.HypergeometricFunctions]] deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"] @@ -767,9 +767,9 @@ weakdeps = ["Unitful"] [[deps.IntervalArithmetic]] deps = ["CRlibm_jll", "MacroTools", "RoundingEmulator"] -git-tree-sha1 = "fe30dec78e68f27fc416901629c6e24e9d5f057b" +git-tree-sha1 = "8e125d40cae3a9f4276cdfeb4fcdb1828888a4b3" uuid = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" -version = "0.22.16" +version = "0.22.17" weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "RecipesBase"] [deps.IntervalArithmetic.extensions] @@ -835,9 +835,9 @@ version = "1.0.0" [[deps.JLD2]] deps = ["FileIO", "MacroTools", "Mmap", "OrderedCollections", "PrecompileTools", "Requires", "TranscodingStreams"] -git-tree-sha1 = "07f9dec43deef049c2f0daa96f67bfc0baa20a17" +git-tree-sha1 = "aeab5c68eb2cf326619bf71235d8f4561c62fe22" uuid = "033835bb-8acc-5ee8-8aae-3f567f8a3819" -version = "0.5.3" +version = "0.5.5" [[deps.JLLWrappers]] deps = ["Artifacts", "Preferences"] @@ -859,9 +859,9 @@ version = "0.1.5" [[deps.JpegTurbo_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "c84a835e1a09b289ffcd2271bf2a337bbdda6637" +git-tree-sha1 = "25ee0be4d43d0269027024d75a24c24d6c6e590c" uuid = "aacddb02-875f-59d6-b918-886e6ef4fbf8" -version = "3.0.3+0" +version = "3.0.4+0" [[deps.KernelDensity]] deps = ["Distributions", "DocStringExtensions", "FFTW", "Interpolations", "StatsBase"] @@ -883,9 +883,9 @@ version = "18.1.7+0" [[deps.LZO_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl"] -git-tree-sha1 = "70c5da094887fd2cae843b8db33920bac4b6f07d" +git-tree-sha1 = "854a9c268c43b77b0a27f22d7fab8d33cdb3a731" uuid = "dd4b983a-f0e5-5f8d-a1b7-129d4a5fb1ac" -version = "2.10.2+0" +version = "2.10.2+1" [[deps.LaTeXStrings]] git-tree-sha1 = "50901ebc375ed41dbf8058da26f9de442febbbec" @@ -1039,15 +1039,15 @@ version = "0.5.13" [[deps.Makie]] deps = ["Animations", "Base64", "CRC32c", "ColorBrewer", "ColorSchemes", "ColorTypes", "Colors", "Contour", "Dates", "DelaunayTriangulation", "Distributions", "DocStringExtensions", "Downloads", "FFMPEG_jll", "FileIO", "FilePaths", "FixedPointNumbers", "Format", "FreeType", "FreeTypeAbstraction", "GeometryBasics", "GridLayoutBase", "ImageBase", "ImageIO", "InteractiveUtils", "Interpolations", "IntervalSets", "Isoband", "KernelDensity", "LaTeXStrings", "LinearAlgebra", "MacroTools", "MakieCore", "Markdown", "MathTeXEngine", "Observables", "OffsetArrays", "Packing", "PlotUtils", "PolygonOps", "PrecompileTools", "Printf", "REPL", "Random", "RelocatableFolders", "Scratch", "ShaderAbstractions", "Showoff", "SignedDistanceFields", "SparseArrays", "Statistics", "StatsBase", "StatsFuns", "StructArrays", "TriplotBase", "UnicodeFun", "Unitful"] -git-tree-sha1 = "2281aaf0685e5e8a559982d32f17d617a949b9cd" +git-tree-sha1 = "50ebda951efaa11b6db0413c1128726b8eab3bf0" uuid = "ee78f7c6-11fb-53f2-987a-cfe4a2b5a57a" -version = "0.21.11" +version = "0.21.13" [[deps.MakieCore]] deps = ["ColorTypes", "GeometryBasics", "IntervalSets", "Observables"] -git-tree-sha1 = "22fed09860ca73537a36d4e5a9bce0d9e80ee8a8" +git-tree-sha1 = "4604f03e5b057e8e62a95a44929cafc9585b0fe9" uuid = "20f20a25-4f0e-4fdf-b5d1-57303727442b" -version = "0.8.8" +version = "0.8.9" [[deps.MappedArrays]] git-tree-sha1 = "2dab0221fe2b0f2cb6754eaa743cc266339f527e" @@ -1108,9 +1108,9 @@ version = "0.5.6" [[deps.MutableArithmetics]] deps = ["LinearAlgebra", "SparseArrays", "Test"] -git-tree-sha1 = "d0a6b1096b584a2b88efb70a92f8cb8c881eb38a" +git-tree-sha1 = "3eba928678787843e504c153a9b8e80d7d73ab17" uuid = "d8a4904e-b15c-11e9-3269-09a3773c0cb0" -version = "1.4.6" +version = "1.5.0" [[deps.NaNMath]] deps = ["OpenLibm_jll"] @@ -1442,9 +1442,9 @@ version = "2024.5.8+0" [[deps.SciMLBase]] deps = ["ADTypes", "Accessors", "ArrayInterface", "CommonSolve", "ConstructionBase", "Distributed", "DocStringExtensions", "EnumX", "Expronicon", "FunctionWrappersWrappers", "IteratorInterfaceExtensions", "LinearAlgebra", "Logging", "Markdown", "PrecompileTools", "Preferences", "Printf", "RecipesBase", "RecursiveArrayTools", "Reexport", "RuntimeGeneratedFunctions", "SciMLOperators", "SciMLStructures", "StaticArraysCore", "Statistics", "SymbolicIndexingInterface", "Tables"] -git-tree-sha1 = "71857d6bab17e7ac6802d86ffcc75423b8c1d812" +git-tree-sha1 = "d01eebc2dbd30c83a857ae8fcc7f12ea6bd5b10c" uuid = "0bca4576-84f4-4d90-8ffe-ffa030f20462" -version = "2.54.0" +version = "2.56.0" [deps.SciMLBase.extensions] SciMLBaseChainRulesCoreExt = "ChainRulesCore" @@ -1635,9 +1635,9 @@ version = "7.2.1+1" [[deps.SymbolicIndexingInterface]] deps = ["Accessors", "ArrayInterface", "RuntimeGeneratedFunctions", "StaticArraysCore"] -git-tree-sha1 = "988e04b34a4c3b824fb656f542473df99a4f610d" +git-tree-sha1 = "0225f7c62f5f78db35aae6abb2e5cabe38ce578f" uuid = "2efcf032-c050-4f8e-a9bb-153293bab1f5" -version = "0.3.30" +version = "0.3.31" [[deps.SymbolicLimits]] deps = ["SymbolicUtils"] @@ -1661,9 +1661,9 @@ version = "3.7.1" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] -git-tree-sha1 = "8b48697e7fec6d4b7c4a9fe892857a5ed2bae7e8" +git-tree-sha1 = "6a7c7cd9bd8c051877a5a29fb597b18362dbc4e4" uuid = "0c5d862f-8b57-4792-8d23-62f2024744c7" -version = "6.12.0" +version = "6.13.1" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" @@ -1747,9 +1747,9 @@ uuid = "6dad8b7f-dd9a-4c28-9b70-85b9a079bfc8" version = "0.1.0" [[deps.TranscodingStreams]] -git-tree-sha1 = "e84b3a11b9bece70d14cce63406bbc79ed3464d2" +git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742" uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa" -version = "0.11.2" +version = "0.11.3" [[deps.TriplotBase]] git-tree-sha1 = "4d4ed7f294cda19382ff7de4c137d24d16adc89b" @@ -1911,21 +1911,21 @@ version = "2.0.3+0" [[deps.libpng_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Zlib_jll"] -git-tree-sha1 = "d7015d2e18a5fd9a4f47de711837e980519781a4" +git-tree-sha1 = "b70c870239dc3d7bc094eb2d6be9b73d27bef280" uuid = "b53b4c65-9356-5827-b1ea-8c7a1a84506f" -version = "1.6.43+1" +version = "1.6.44+0" [[deps.libsixel_jll]] deps = ["Artifacts", "JLLWrappers", "JpegTurbo_jll", "Libdl", "Pkg", "libpng_jll"] -git-tree-sha1 = "d4f63314c8aa1e48cd22aa0c17ed76cd1ae48c3c" +git-tree-sha1 = "7dfa0fd9c783d3d0cc43ea1af53d69ba45c447df" uuid = "075b6546-f08a-558a-be8f-8157d0f608a5" -version = "1.10.3+0" +version = "1.10.3+1" [[deps.libsodium_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Pkg"] -git-tree-sha1 = "848ab3d00fe39d6fbc2a8641048f8f272af1c51e" +git-tree-sha1 = "f76d682d87eefadd3f165d8d9fda436464213142" uuid = "a9144af2-ca23-56d9-984f-0d03f7b5ccf8" -version = "1.0.20+0" +version = "1.0.20+1" [[deps.libvorbis_jll]] deps = ["Artifacts", "JLLWrappers", "Libdl", "Ogg_jll", "Pkg"] diff --git a/Project.toml b/Project.toml index 10bdbed..5feef8d 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "QuantumCollocation" uuid = "0dc23a59-5ffb-49af-b6bd-932a8ae77adf" authors = ["Aaron Trowbridge and contributors"] -version = "0.2.2" +version = "0.3.0" [deps] BenchmarkTools = "6e4b80f9-dd63-53aa-95a3-0cdb28fa8baf" From 896b048a3650f545ead410c2e17c4134e82fec0b Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 18:58:00 -0400 Subject: [PATCH 25/35] manifest cleaning --- Manifest.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Manifest.toml b/Manifest.toml index 9c38a58..d4ac7b4 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -778,6 +778,7 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" + IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" From c7c40b00838a92b5b73473779d3161bc6fe9ef3e Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 23 Aug 2024 13:10:12 -0500 Subject: [PATCH 26/35] feat: data interpolations --- src/trajectory_interpolations.jl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/trajectory_interpolations.jl b/src/trajectory_interpolations.jl index 4b313a0..317590d 100644 --- a/src/trajectory_interpolations.jl +++ b/src/trajectory_interpolations.jl @@ -16,8 +16,10 @@ struct DataInterpolation values_components::Vector{Int} function DataInterpolation( - times::AbstractVector{Float64}, values::AbstractMatrix{Float64}; - timestep_components::AbstractVector{Int}=Int[], kind::Symbol=:linear + times::AbstractVector{Float64}, + values::AbstractMatrix{Float64}; + timestep_components::AbstractVector{Int}=Int[], + kind::Symbol=:linear ) comps = setdiff(1:size(values, 1), timestep_components) if kind == :linear From 2e29f0cf612e7e6776e58bb99df324cb6c294e1c Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 9 Sep 2024 16:41:29 -0400 Subject: [PATCH 27/35] compat bump --- Manifest.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index d4ac7b4..9c38a58 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -778,7 +778,6 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" - IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" From 362baf01fbb93c7820829de0e512fa242874098f Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Wed, 21 Aug 2024 17:19:00 -0400 Subject: [PATCH 28/35] refactor: template options into PiccoloOptions (in progress) --- src/options.jl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/options.jl b/src/options.jl index 39fe0f5..7cde780 100644 --- a/src/options.jl +++ b/src/options.jl @@ -58,6 +58,10 @@ end Solver settings for Quantum Collocation. """ @kwdef mutable struct PiccoloOptions <: AbstractOptions + state_type::Symbol = :unitary + state_name::Symbol = :Ũ⃗ + control_name::Symbol = :a + timestep_name::Symbol = :Δt verbose::Bool = true verbose_evaluator::Bool = false free_time::Bool = true From b88e07e0cd3979974f53dd47d7595407736bbd66 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 15:32:54 -0400 Subject: [PATCH 29/35] cleaning and formatting --- Manifest.toml | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 9c38a58..7c57444 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -778,6 +778,7 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" + IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -1120,7 +1121,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "8b72d6806501fd61684dcc6e9c336855acd5abe1" +git-tree-sha1 = "900c2091843bbee472da11a8cc862d01e2482aa5" +repo-rev = "main" +repo-url = "https://github.com/kestrelquantum/NamedTrajectories.jl.git" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" version = "0.2.2" @@ -1653,11 +1656,9 @@ version = "3.7.1" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" - SymbolicUtilsReverseDiffExt = "ReverseDiff" [deps.SymbolicUtils.weakdeps] LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" - ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] @@ -1668,7 +1669,7 @@ version = "6.13.1" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" - SymbolicsLuxExt = "Lux" + SymbolicsLuxCoreExt = "LuxCore" SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1676,7 +1677,7 @@ version = "6.13.1" [deps.Symbolics.weakdeps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" - Lux = "b2108857-7c20-44ae-9111-449ecde12c47" + LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" From ef2599dd21176d103a31784acb90e2dfccd496cb Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Tue, 3 Sep 2024 16:12:00 -0400 Subject: [PATCH 30/35] patch bump for compat bumps --- Manifest.toml | 8 +++----- Project.toml | 2 +- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 7c57444..762b8b4 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.5" manifest_format = "2.0" -project_hash = "0e1b56171c4e825157ede62be9481fa3374601e7" +project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" [[deps.ADTypes]] git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081" @@ -1121,11 +1121,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "900c2091843bbee472da11a8cc862d01e2482aa5" -repo-rev = "main" -repo-url = "https://github.com/kestrelquantum/NamedTrajectories.jl.git" +git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.2" +version = "0.2.1" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] diff --git a/Project.toml b/Project.toml index 5feef8d..300c382 100644 --- a/Project.toml +++ b/Project.toml @@ -42,7 +42,7 @@ MathOptInterface = "1.31" NamedTrajectories = "0.2" ProgressMeter = "1.10" Reexport = "1.2" -Symbolics = "6.11" +Symbolics = "6.2" TestItemRunner = "1.0" TestItems = "1.0" TrajectoryIndexingUtils = "0.1" From 650200141b0aef9e1b0c5783afc2f9dfe1aefda5 Mon Sep 17 00:00:00 2001 From: andy Date: Fri, 23 Aug 2024 13:10:12 -0500 Subject: [PATCH 31/35] feat: data interpolations --- Manifest.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index 762b8b4..aaa09c7 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,8 +1,8 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.5" +julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "154c34ae44e0c999cf76edcaa44f9eee410e9a9e" +project_hash = "1d025dab4c6dd8f7ccf572cc68ecdd4a371d25d2" [[deps.ADTypes]] git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081" From a278baaf51c0928382f15e7e636c5360e645ab89 Mon Sep 17 00:00:00 2001 From: andy Date: Mon, 26 Aug 2024 15:13:27 -0500 Subject: [PATCH 32/35] update project patch version --- Manifest.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Manifest.toml b/Manifest.toml index aaa09c7..a0bf047 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -2,7 +2,7 @@ julia_version = "1.10.4" manifest_format = "2.0" -project_hash = "1d025dab4c6dd8f7ccf572cc68ecdd4a371d25d2" +project_hash = "a8d39c98fbf089d5b72e82a89504c42d025cd3fe" [[deps.ADTypes]] git-tree-sha1 = "eea5d80188827b35333801ef97a40c2ed653b081" From 5e2d0673bc6354b17e49847f3b88a169b9e12159 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 9 Sep 2024 16:41:29 -0400 Subject: [PATCH 33/35] compat bump --- Manifest.toml | 13 +++++++------ Project.toml | 2 +- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Manifest.toml b/Manifest.toml index a0bf047..e2dfc21 100644 --- a/Manifest.toml +++ b/Manifest.toml @@ -1,6 +1,6 @@ # This file is machine-generated - editing it directly is not advised -julia_version = "1.10.4" +julia_version = "1.10.5" manifest_format = "2.0" project_hash = "a8d39c98fbf089d5b72e82a89504c42d025cd3fe" @@ -778,7 +778,6 @@ weakdeps = ["DiffRules", "ForwardDiff", "IntervalSets", "LinearAlgebra", "Recipe IntervalArithmeticIntervalSetsExt = "IntervalSets" IntervalArithmeticLinearAlgebraExt = "LinearAlgebra" IntervalArithmeticRecipesBaseExt = "RecipesBase" - IntervalArithmeticsIntervalSetsExt = "IntervalSets" [[deps.IntervalSets]] git-tree-sha1 = "dba9ddf07f77f60450fe5d2e2beb9854d9a49bd0" @@ -1121,9 +1120,9 @@ version = "1.0.2" [[deps.NamedTrajectories]] deps = ["CairoMakie", "JLD2", "LaTeXStrings", "Latexify", "OrderedCollections", "Random", "Reexport", "Unidecode"] -git-tree-sha1 = "44ccb3fd6cbc17a2bf1d5722c1cd3d3d70472720" +git-tree-sha1 = "8b72d6806501fd61684dcc6e9c336855acd5abe1" uuid = "538bc3a1-5ab9-4fc3-b776-35ca1e893e08" -version = "0.2.1" +version = "0.2.2" [[deps.Netpbm]] deps = ["FileIO", "ImageCore", "ImageMetadata"] @@ -1654,9 +1653,11 @@ version = "3.7.1" [deps.SymbolicUtils.extensions] SymbolicUtilsLabelledArraysExt = "LabelledArrays" + SymbolicUtilsReverseDiffExt = "ReverseDiff" [deps.SymbolicUtils.weakdeps] LabelledArrays = "2ee39098-c373-598a-b85f-a56591580800" + ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267" [[deps.Symbolics]] deps = ["ADTypes", "ArrayInterface", "Bijections", "CommonWorldInvalidations", "ConstructionBase", "DataStructures", "DiffRules", "Distributions", "DocStringExtensions", "DomainSets", "DynamicPolynomials", "IfElse", "LaTeXStrings", "LambertW", "Latexify", "Libdl", "LinearAlgebra", "LogExpFunctions", "MacroTools", "Markdown", "NaNMath", "PrecompileTools", "Primes", "RecipesBase", "Reexport", "RuntimeGeneratedFunctions", "SciMLBase", "Setfield", "SparseArrays", "SpecialFunctions", "StaticArraysCore", "SymbolicIndexingInterface", "SymbolicLimits", "SymbolicUtils", "TermInterface"] @@ -1667,7 +1668,7 @@ version = "6.13.1" [deps.Symbolics.extensions] SymbolicsForwardDiffExt = "ForwardDiff" SymbolicsGroebnerExt = "Groebner" - SymbolicsLuxCoreExt = "LuxCore" + SymbolicsLuxExt = "Lux" SymbolicsNemoExt = "Nemo" SymbolicsPreallocationToolsExt = ["PreallocationTools", "ForwardDiff"] SymbolicsSymPyExt = "SymPy" @@ -1675,7 +1676,7 @@ version = "6.13.1" [deps.Symbolics.weakdeps] ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210" Groebner = "0b43b601-686d-58a3-8a1c-6623616c7cd4" - LuxCore = "bb33d45b-7691-41d6-9220-0943567d0623" + Lux = "b2108857-7c20-44ae-9111-449ecde12c47" Nemo = "2edaba10-b0f1-5616-af89-8c11ac63239a" PreallocationTools = "d236fae5-4411-538c-8e31-a6e3d9e00b46" SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6" diff --git a/Project.toml b/Project.toml index 300c382..5feef8d 100644 --- a/Project.toml +++ b/Project.toml @@ -42,7 +42,7 @@ MathOptInterface = "1.31" NamedTrajectories = "0.2" ProgressMeter = "1.10" Reexport = "1.2" -Symbolics = "6.2" +Symbolics = "6.11" TestItemRunner = "1.0" TestItems = "1.0" TrajectoryIndexingUtils = "0.1" From 001c8ad5a436611a322e7274f4b9e1dcc8e1963f Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 17:08:49 -0400 Subject: [PATCH 34/35] rebase fix --- src/options.jl | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/options.jl b/src/options.jl index 7cde780..39fe0f5 100644 --- a/src/options.jl +++ b/src/options.jl @@ -58,10 +58,6 @@ end Solver settings for Quantum Collocation. """ @kwdef mutable struct PiccoloOptions <: AbstractOptions - state_type::Symbol = :unitary - state_name::Symbol = :Ũ⃗ - control_name::Symbol = :a - timestep_name::Symbol = :Δt verbose::Bool = true verbose_evaluator::Bool = false free_time::Bool = true From ed8bff7be10fe934fdc2ffd938d48c84892c97e7 Mon Sep 17 00:00:00 2001 From: Aaron Trowbridge Date: Mon, 7 Oct 2024 17:23:47 -0400 Subject: [PATCH 35/35] reverting back to old .gitignore --- .gitignore | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 62c32b7..36868b0 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,8 @@ *.jl.cov *.jl.mem /docs/build/ -*.code-workspace -manifest.toml \ No newline at end of file +/examples/**/plots/ +/examples/**/trajectories/ +pardiso.lic +/.CondaPkg/ +*.code-workspace \ No newline at end of file