# QuantumControlTestUtils

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

`QuantumControlTestUtils.generate_coverage_html`

— FunctionGenerate 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.

`QuantumControlTestUtils.show_coverage`

— FunctionPrint 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`

.

`QuantumControlTestUtils.test`

— FunctionRun 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.

`QuantumControlTestUtils.RandomObjects.random_dynamic_generator`

— MethodConstruct 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**

`random_matrix`

— generate a*static*random Hamiltonian

`QuantumControlTestUtils.RandomObjects.random_matrix`

— MethodConstruct 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**

`random_dynamic_generator`

— generate a time-dependent random

Hamiltonian.

`QuantumControlTestUtils.RandomObjects.random_state_vector`

— MethodReturn a random, normalized Hilbert space state vector of dimension `N`

.

`random_state_vector(N; rng=GLOBAL_RNG)`

`QuantumControlTestUtils.DummyOptimization.dummy_control_problem`

— MethodSet 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`

`QuantumControlTestUtils.DummyOptimization.optimize_with_dummy_method`

— MethodRun 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.