QuantumControlTestUtils

Github v0.3.1

The QuantumControlTestUtils package collects methods that are used for testing and benchmarking within the JuliaQuantumControl organization

QuantumControlTestUtils.generate_coverage_htmlFunction

Generate an HTML report for existing coverage data.

generate_coverage_html(
    paths=["src", "ext"]; root=pwd(), covdir="coverage", genhtml="genhtml"
)

creates a folder covdir in root and use the external genhtml program to write an HTML coverage report into that folder.

source
QuantumControlTestUtils.show_coverageFunction

Print out a coverage summary from existing coverage data.

show_coverage(paths=["./src", "./ext"]; root=pwd(), sort_by=nothing)

prints a a table showing the tracked files in paths, the total number of tracked lines in that file ("Total"), the number of lines with coverage ("Hit"), the number of lines without coverage ("Missed") and the "Coverage" as a percentage.

The coverage data is collected from .cov files in paths as well as tracefile-*.info files in root.

Optionally, the table can be sorted by passing the name of a column to sort_by, e..g. sort_py=:Missed.

source
QuantumControlTestUtils.testFunction

Run a package test-suite in a subprocess.

test(
    file="test/runtests.jl";
    root=pwd(),
    project="test",
    code_coverage=".coverage/tracefile-%p.info",
    show_coverage=(code_coverage != "none"),
    color=<inherit>,
    compiled_modules=<inherit>,
    startup_file=<inherit>,
    depwarn=<inherit>,
    inline=<inherit>,
    check_bounds="yes",
    track_allocation=<inherit>,
    threads=<inherit>,
    genhtml=false,
    covdir="coverage"
)

runs the test suite of the package located at root by running include(file) inside a new julia process.

This is similar to what Pkg.test() does, but differs in the "sandboxing" approach. While Pkg.test() creates a new temporary sandboxed environment, test() uses an existing environment in project (the test subfolder by default). This allows testing against the dev-versions of other packages. It requires that the test folder contains both a Project.toml and a Manifest.toml file.

The test() function also differs from directly including test/runtests.jl in the REPL in that it can generate coverage data and reports (this is only possible when running tests in a subprocess).

If show_coverage is passed as true (default), a coverage summary is shown. Further, if genhtml is true, a full HTML coverage report will be generated in covdir (relative to root). This requires the genhtml executable (part of the lcov package). Instead of true, it is also possible to pass the path to the genhtml executable.

All other keyword arguments correspond to the respective command line flag for the julia executable that is run as the subprocess.

This function is intended to be exposed in a project's development-REPL.

source
QuantumControlTestUtils.RandomObjects.random_dynamic_generatorMethod

Construct a random dynamic generator (time-dependent Hamiltonian).

tlist = collection(range(0, 100, length=1001))
Ĥ = random_dynamic_generator(N, tlist; kwargs...)

by default initializes as a real Hermitian Generator of dimension N. The generator consists of one random drift term and one random control term with a random control amplitude value ∈ [-1, 1] for each interval of the given tlist. The spectral envelope of the generator will be 1.0. That is, the largest absolute eigenvalue at any point in time should be less than 1.0. The larger N, the more tightly the envelope will fit.

Keyword arguments

  • number_of_controls=1: The number of control terms in the generator.
  • density=1.0: A number > 0.0 and ≤ 1.0. Any value < 1.0 implies a sparse matrix where density is the approximate fraction of non-zero elements to total elements
  • complex=false: Whether the matrix should be real-valued (default) or complex-valued
  • hermitian=false: Whether the matrix should be Hermitian (have real eigenvalues, default) or non-Hermitian (eigenvalues in the complex plane with a circle of the spectral_envelope)
  • spectral_envelope=1.0: An upper bound for the spectral radius for the generator evaluated at different points in time. For large N, the spectral envelope should be approximately touched for the extremal pulse amplitudes, ±1. Note that the average spectral radius is always well within the spectral_envelope`)
  • exact_spectral_envelope=false: If true, the spectral radius when plugging in the extremal pulse amplitudes ±1 will touch exactly the specified spectral_envelope. This is done via diagonalization, so it is only feasible for moderately large dimensions N.
  • amplitudes: If given, a vector of amplitudes to use in the generator. Must be of length number_of_controls. This can be used to supersede the creation of random control pulses.
  • rng=Random.GLOBAL_RNG: The random number generator to use. The call Random.rand(rng, N, N) must produces a real-valued $N×N$ matrix with elements uniformly distributed between 0 and 1

See also

source
QuantumControlTestUtils.RandomObjects.random_matrixMethod

Construct a random matrix.

Ĥ = random_matrix(N; kwargs...)

by default initializes as a general complex $N×N$ matrix with a spectral radius of approximately 1.0. Keyword arguments allow to initialize real or complex, Hermitian or non-Hermitian, dense or sparse matrices with arbitrary spectral radius. The non-zero entries in Ĥ will be uniformly distributed around zero, with a range of values that depends on N and the desired spectral radius.

Keyword arguments

  • density=1.0: A number > 0.0 and ≤ 1.0. Any value < 1.0 implies a sparse matrix where density is the approximate fraction of non-zero elements to total elements
  • complex=true: Whether the matrix should be complex-valued (default) or real-valued
  • hermitian=false: Whether the matrix should be general (default) or Hermitian (real eigenvalues)
  • spectral_radius=1.0: The approximate spectral radius, i.e. maximum absolute eigenvalue. This is according to Girko-Ginibri's circular law, in the limit of large $N$
  • exact_spectral_radius=false: If given as true, ensure that the spectral_radius is exact. This is done via diagonalization, so it is only feasible for moderately large dimensions N. On the other hand, for large N, the spectral_radius, respectively the circular law becomes more exact anyway.
  • rng=Random.GLOBAL_RNG: The random number generator to use. The call Random.rand(rng, N, N) must produces a real-valued $N×N$ matrix with elements uniformly distributed between 0 and 1

See also

Hamiltonian.

source
QuantumControlTestUtils.DummyOptimization.dummy_control_problemMethod

Set up a dummy control problem.

problem = dummy_control_problem(;
    N=10, n_trajectories=1, n_controls=1, n_steps=50, dt=1.0, density=0.5,
    complex_operators=true, hermitian=true, pulses_as_controls=false, rng,
    kwargs...)

Sets up a control problem with random (sparse) Hermitian matrices.

Arguments

  • N: The dimension of the Hilbert space
  • n_trajectories: The number of trajectories in the optimization. All trajectories will have the same Hamiltonian, but random initial and target states.
  • n_controls: The number of controls, that is, the number of control terms in the control Hamiltonian. Each control is an array of random values, normalized on the intervals of the time grid.
  • n_steps: The number of time steps (intervals of the time grid)
  • dt: The time step
  • density: The density of the Hamiltonians, as a number between 0.0 and 1.0. For density=1.0, the Hamiltonians will be dense matrices.
  • complex_operators: Whether or not the drift/control operators will be complex-valued or real-valued.
  • hermitian: Whether or not all drift/control operators will be Hermitian matrices.
  • pulses_as_controls=false: If true, directly use pulses (discretized to the midpoints of the time grid) as controls, instead of the normal controls discretized to the points of the time grid.
  • rng=Random.GLOBAL_RNG: The random number generator to use. See random_matrix and random_state_vector.
  • kwargs: All other keyword arguments are passed on to QuantumControl.ControlProblem
source
QuantumControlTestUtils.DummyOptimization.optimize_with_dummy_methodMethod

Run a dummy optimization.

result = optimize(problem, method=:dummymethod)

runs through and "optimization" of the given problem where in each iteration, the amplitude of the guess pulses is diminished by 10%. The (summed) vector norm of the the control serves as the value of the optimization functional.

source