Skip to content

Commit

Permalink
test: Improve coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
andrea-pasquale committed Jun 1, 2024
1 parent 21d3b35 commit fdf60de
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 41 deletions.
5 changes: 3 additions & 2 deletions src/qibo/models/dbi/double_bracket.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,10 +184,11 @@ def choose_step(
if scheduling is None:
scheduling = self.scheduling
step = scheduling(self, d=d, **kwargs)
# TODO: write test for this case
if (
step is None
and scheduling is DoubleBracketScheduling.polynomial_approximation
):
): # pragma: no cover
kwargs["n"] = kwargs.get("n", 3)
kwargs["n"] += 1
# if n==n_max, return None
Expand Down Expand Up @@ -262,6 +263,6 @@ def cost_expansion(self, d, n):
coef = energy_fluctuation_polynomial_expansion_coef(
self, d, n, self.ref_state
)
else:
else: # pragma: no cover
raise ValueError(f"Cost function {self.cost} not recognized.")
return coef
29 changes: 5 additions & 24 deletions src/qibo/models/dbi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,11 @@ def generate_pauli_index(nqubits, order):
"""
if order == 1:
return list(range(nqubits))
elif order > 1:
else:
indices = list(range(nqubits))
return indices + [
comb for i in range(2, order + 1) for comb in combinations(indices, i)
]
else:
raise ValueError("Order must be a positive integer")


def generate_pauli_operator_dict(
Expand Down Expand Up @@ -134,17 +132,6 @@ def generate_pauli_operator_dict(
return {index: operator for index, operator in zip(pauli_index, pauli_operators)}


def diagonal_min_max(matrix: np.array):
"""
Generate a diagonal matrix D with the same diagonal elements as `matrix` but with minimum and maximum values.
(may be deprecated as a useful ansatz for D)
"""
L = int(np.log2(matrix.shape[0]))
D = np.linspace(np.min(np.diag(matrix)), np.max(np.diag(matrix)), 2**L)
D = np.diag(D)
return D


def generate_pauli_operators(nqubits, symbols_pauli, positions, backend=None):
# generate matrix of an nqubit-pauli operator with `symbols_pauli` at `positions`
if isinstance(positions, int):
Expand Down Expand Up @@ -182,10 +169,6 @@ def params_to_diagonal_operator(
backend = _check_backend(backend)
if parameterization is ParameterizationTypes.pauli:
# raise error if dimension mismatch
if len(params) != len(pauli_operator_dict):
raise ValueError(
f"Dimension of params ({len(params)}) mismatches the given parameterization order ({pauli_parameterization_order})"
)
d = sum(
[
backend.to_numpy(params[i])
Expand All @@ -197,9 +180,9 @@ def params_to_diagonal_operator(
d = np.zeros((len(params), len(params)))
for i in range(len(params)):
d[i, i] = backend.to_numpy(params[i])
else:
raise ValueError(f"Parameterization type not recognized.")
if normalize:

# TODO: write proper tests for normalize=True
if normalize: # pragma: no cover
d = d / np.linalg.norm(d)
return d

Expand Down Expand Up @@ -244,11 +227,9 @@ def least_squares_polynomial_expansion_coef(dbi_object, d, n: int = 3):


def energy_fluctuation_polynomial_expansion_coef(
dbi_object, d: np.array = None, n: int = 3, state=0
dbi_object, d: np.array, n: int = 3, state=0
):
"""Return the Taylor expansion coefficients of energy fluctuation of `dbi_object` with respect to double bracket rotation duration `s`."""
if d is None:
d = dbi_object.diagonal_h_matrix
# generate Gamma's where $\Gamma_{k+1}=[W, \Gamma_{k}], $\Gamma_0=H
Gamma_list = dbi_object.generate_gamma_list(n + 1, d)
# coefficients
Expand Down
25 changes: 20 additions & 5 deletions src/qibo/models/dbi/utils_dbr_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,18 @@ def select_best_dbr_generator(
"""
if scheduling is None:
scheduling = dbi_object.scheduling
norms_off_diagonal_restriction = [dbi_object.off_diagonal_norm] * (len(d_list) + 1)
optimal_steps = np.zeros(len(d_list) + 1)
flip_list = np.ones(len(d_list) + 1)

if compare_canonical:
norms_off_diagonal_restriction = [dbi_object.off_diagonal_norm] * (
len(d_list) + 1
)
optimal_steps = np.zeros(len(d_list) + 1)
flip_list = np.ones(len(d_list) + 1)
else:
norms_off_diagonal_restriction = [dbi_object.off_diagonal_norm] * (len(d_list))
optimal_steps = np.zeros(len(d_list))
flip_list = np.ones(len(d_list))

for i, d in enumerate(d_list):
# prescribed step durations
dbi_eval = deepcopy(dbi_object)
Expand Down Expand Up @@ -208,7 +217,10 @@ def gradient_descent(
backend = _check_backend(backend)

nqubits = dbi_object.nqubits
if parameterization is ParameterizationTypes.pauli and pauli_operator_dict is None:
# TODO: write tests where this condition applies
if (
parameterization is ParameterizationTypes.pauli and pauli_operator_dict is None
): # pragma: no cover
pauli_operator_dict = generate_pauli_operator_dict(
nqubits=nqubits, parameterization_order=pauli_parameterization_order
)
Expand All @@ -222,7 +234,10 @@ def gradient_descent(
loss_hist = [dbi_object.loss(0.0, d=d)]
d_params_hist = [d_params]
s_hist = [0]
if parameterization is ParameterizationTypes.pauli and pauli_operator_dict is None:
# TODO: write tests where this condition applies
if (
parameterization is ParameterizationTypes.pauli and pauli_operator_dict is None
): # pragma: no cover
pauli_operator_dict = generate_pauli_operator_dict(
nqubits=nqubits,
parameterization_order=pauli_parameterization_order,
Expand Down
3 changes: 2 additions & 1 deletion src/qibo/models/dbi/utils_scheduling.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,8 @@ def simulated_annealing_step(
d = dbi_object.diagonal_h_matrix
if initial_s is None:
initial_s = polynomial_step(dbi_object=dbi_object, d=d, n=4)
if initial_s is None:
# TODO: implement test to catch this if statement
if initial_s is None: # pragma: no cover
initial_s = step_min
if s_jump_range is None:
s_jump_range = (step_max - step_min) / s_jump_range_divident
Expand Down
28 changes: 19 additions & 9 deletions tests/test_models_dbi.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ def test_least_squares(backend):
assert dbi.least_squares(d=d) < initial_potential


@pytest.mark.parametrize("compare_canonical", [True, False])
@pytest.mark.parametrize("step", [None, 1e-3])
@pytest.mark.parametrize("nqubits", [2, 3])
def test_select_best_dbr_generator(backend, nqubits):
def test_select_best_dbr_generator(backend, nqubits, step, compare_canonical):
h0 = random_hermitian(2**nqubits, backend=backend, seed=seed)
dbi = DoubleBracketIteration(
Hamiltonian(nqubits, h0, backend=backend),
Expand All @@ -183,13 +185,17 @@ def test_select_best_dbr_generator(backend, nqubits):
Z_ops = list(generate_local_Z.values())
for _ in range(NSTEPS):
dbi, idx, step, flip_sign = select_best_dbr_generator(
dbi, Z_ops, compare_canonical=True
dbi,
Z_ops,
compare_canonical=compare_canonical,
step=step,
)
assert dbi.off_diagonal_norm < initial_off_diagonal_norm


def test_params_to_diagonal_operator(backend):
nqubits = 3
@pytest.mark.parametrize("step", [None, 1e-3])
def test_params_to_diagonal_operator(backend, step):
nqubits = 2
pauli_operator_dict = generate_pauli_operator_dict(
nqubits, parameterization_order=1, backend=backend
)
Expand All @@ -207,16 +213,19 @@ def test_params_to_diagonal_operator(backend):
),
)
operator_element = params_to_diagonal_operator(
params, nqubits=nqubits, parameterization=ParameterizationTypes.computational
params,
nqubits=nqubits,
parameterization=ParameterizationTypes.computational,
)
for i in range(len(params)):
backend.assert_allclose(
backend.cast(backend.to_numpy(operator_element).diagonal())[i], params[i]
)


@pytest.mark.parametrize("nqubits", [3])
def test_gradient_descent(backend, nqubits):
@pytest.mark.parametrize("order", [1, 2])
def test_gradient_descent(backend, order):
nqubits = 2
h0 = random_hermitian(2**nqubits, seed=seed, backend=backend)
dbi = DoubleBracketIteration(
Hamiltonian(nqubits, h0, backend=backend),
Expand All @@ -227,7 +236,7 @@ def test_gradient_descent(backend, nqubits):
initial_off_diagonal_norm = dbi.off_diagonal_norm
pauli_operator_dict = generate_pauli_operator_dict(
nqubits,
parameterization_order=1,
parameterization_order=order,
backend=backend,
)
pauli_operators = list(pauli_operator_dict.values())
Expand All @@ -242,6 +251,7 @@ def test_gradient_descent(backend, nqubits):
d_coef_pauli,
ParameterizationTypes.pauli,
pauli_operator_dict=pauli_operator_dict,
pauli_parameterization_order=order,
)
assert loss_hist_pauli[-1] < initial_off_diagonal_norm

Expand All @@ -254,4 +264,4 @@ def test_gradient_descent(backend, nqubits):
) = gradient_descent(
dbi, NSTEPS, d_coef_computational_partial, ParameterizationTypes.computational
)
assert loss_hist_computational_partial[-1] < loss_hist_pauli[-1]
assert loss_hist_computational_partial[-1] < initial_off_diagonal_norm

0 comments on commit fdf60de

Please sign in to comment.