From 8212c85062a3e17e8e5bfe1392bac3d8d8af1ec7 Mon Sep 17 00:00:00 2001 From: Michael Goerz Date: Sun, 26 Mar 2023 13:33:01 -0400 Subject: [PATCH] Catch empty controls in optimization Trying to run `optimize` when there were no controls in the problem would produce a very non-obvious MethodError. Since this is an easy mistake to make, we can catch this situation with a proper error message. --- src/workspace.jl | 3 +++ test/runtests.jl | 5 +++++ test/test_empty_optimization.jl | 33 +++++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) create mode 100644 test/test_empty_optimization.jl diff --git a/src/workspace.jl b/src/workspace.jl index b3c741f..c662171 100644 --- a/src/workspace.jl +++ b/src/workspace.jl @@ -68,6 +68,9 @@ function KrotovWrk(problem::QuantumControlBase.ControlProblem; verbose=false) objectives = [obj for obj in problem.objectives] adjoint_objectives = [adjoint(obj) for obj in problem.objectives] controls = get_controls(objectives) + if length(controls) == 0 + error("no controls in objectives: cannot optimize") + end control_derivs = [get_control_derivs(obj.generator, controls) for obj in objectives] tlist = problem.tlist kwargs = Dict(problem.kwargs) # creates a shallow copy; ok to modify diff --git a/test/runtests.jl b/test/runtests.jl index eae43bd..8d24360 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -16,6 +16,11 @@ include(joinpath(@__DIR__, "download_dumps.jl")) include("test_pulse_optimization.jl") end + print("\n* Emptry Optimization (test_empty_optimization.jl)") + @time @safetestset "Empty Optimization" begin + include("test_empty_optimization.jl") + end + print("\n* Example 1 (examples/simple_state_to_state.jl):") @time @safetestset "Example 1" begin include(joinpath("examples", "simple_state_to_state.jl")) diff --git a/test/test_empty_optimization.jl b/test/test_empty_optimization.jl new file mode 100644 index 0000000..750532d --- /dev/null +++ b/test/test_empty_optimization.jl @@ -0,0 +1,33 @@ +using Test +using StableRNGs +using QuantumControl: hamiltonian, optimize, ControlProblem, Objective +using QuantumControl.Controls: get_controls +using QuantumControlTestUtils.RandomObjects: random_matrix, random_state_vector + +@testset "empty optimization" begin + + # Test that trying to run an optimization without any controls produces a + # meaningful error message + + rng = StableRNG(2264511904) + + N = 10 + H = random_matrix(N; rng) + objectives = [ + Objective(; + initial_state=random_state_vector(N; rng), + generator=H, + target_state=random_state_vector(N; rng) + ) + ] + + @test length(get_controls(objectives)) == 0 + + tlist = collect(range(0; length=1001, step=1.0)) + + problem = ControlProblem(; objectives, tlist, pulse_options=Dict()) + + msg = "no controls in objectives: cannot optimize" + @test_throws ErrorException(msg) optimize(problem; method=:krotov) + +end