Skip to content

Commit

Permalink
Merge pull request #1044 from qiboteam/overlap
Browse files Browse the repository at this point in the history
Implementation of `backend.calculate_overlap_density_matrix` in `numpy` backend
  • Loading branch information
renatomello authored Oct 17, 2023
2 parents 327462a + c17e26a commit 2debe49
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/qibo/backends/abstract.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ def calculate_overlap(self, state1, state2): # pragma: no cover

@abc.abstractmethod
def calculate_overlap_density_matrix(self, state1, state2): # pragma: no cover
"""Calculate norm of two density matrices."""
"""Calculate overlap of two density matrices."""
raise_error(NotImplementedError)

@abc.abstractmethod
Expand Down
4 changes: 3 additions & 1 deletion src/qibo/backends/numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -687,7 +687,9 @@ def calculate_overlap(self, state1, state2):
return self.np.abs(self.np.sum(self.np.conj(state1) * state2))

def calculate_overlap_density_matrix(self, state1, state2):
raise_error(NotImplementedError)
state1 = self.cast(state1)
state2 = self.cast(state2)
return self.np.trace(self.np.transpose(self.np.conj(state1)) @ state2)

def calculate_eigenvalues(self, matrix, k=6):
if self.issparse(matrix):
Expand Down
2 changes: 1 addition & 1 deletion src/qibo/callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ def apply(self, backend, state):
self.append(overlap)
return overlap

def apply_density_matrix(self, backend, state): # pragma: no cover
def apply_density_matrix(self, backend, state):
overlap = backend.calculate_overlap_density_matrix(self.state, state)
self.append(overlap)
return overlap
Expand Down
26 changes: 18 additions & 8 deletions tests/test_callbacks.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,19 +343,29 @@ def test_norm(backend, density_matrix, seed):
backend.assert_allclose(final_norm, target_norm)


@pytest.mark.parametrize("seed", list(range(1, 5 + 1)))
@pytest.mark.parametrize("density_matrix", [False, True])
def test_overlap(backend, density_matrix):
state0 = np.random.random(4) + 1j * np.random.random(4)
state1 = np.random.random(4) + 1j * np.random.random(4)
@pytest.mark.parametrize("nqubits", list(range(2, 6 + 1, 2)))
def test_overlap(backend, nqubits, density_matrix, seed):
dims = 2**nqubits
if density_matrix:
state0 = random_density_matrix(dims, seed=seed, backend=backend)
state1 = random_density_matrix(dims, seed=seed + 1, backend=backend)
else:
state0 = random_statevector(dims, seed=seed, backend=backend)
state1 = random_statevector(dims, seed=seed + 1, backend=backend)

overlap = callbacks.Overlap(state0)
overlap.nqubits = 2
overlap.nqubits = nqubits

if density_matrix:
with pytest.raises(NotImplementedError):
overlap.apply_density_matrix(backend, state1)
final_overlap = overlap.apply_density_matrix(backend, state1)
target_overlap = np.trace(np.transpose(np.conj(state0)) @ state1)
else:
final_overlap = overlap.apply(backend, state1)
target_overlap = np.abs((state0.conj() * state1).sum())
backend.assert_allclose(final_overlap, target_overlap)
target_overlap = np.abs(np.sum(np.conj(state0) * state1))

backend.assert_allclose(final_overlap, target_overlap)


@pytest.mark.parametrize("density_matrix", [False, True])
Expand Down

0 comments on commit 2debe49

Please sign in to comment.