Skip to content

Commit

Permalink
Do not separate substates when measurements are ignored (quantumlib#4816
Browse files Browse the repository at this point in the history
)

Density matrix separates qubit states after measurement when split_untanged_states=True. However when ignore_measurement_results=True, this should not happen, as the this changes the measurement into a dephase and does not make the state separable.

For instance, when measuring a Bell state, the result should be 0.5 |00> + 0.5 |11>. However, separating those states (partial tracing each qubit) and re-kronning them gives 0.25 of each; i.e. it causes each qubit to be 0.5 |0> and 0.5 |1> independently. Therefore we need to avoid separating states after measurements if ignore_measurement_results=True.

This PR fixes quantumlib#4817.
  • Loading branch information
daxfohl authored Jan 11, 2022
1 parent 1f3b502 commit 3de569a
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 2 deletions.
5 changes: 3 additions & 2 deletions cirq/sim/act_on_args_container.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,8 +118,9 @@ def _act_on_fallback_(
protocols.act_on(action, op_args, act_on_qubits, allow_decompose=allow_decompose)

# Decouple any measurements or resets
if self.split_untangled_states and isinstance(
gate, (ops.MeasurementGate, ops.ResetChannel)
if self.split_untangled_states and (
isinstance(gate, ops.ResetChannel)
or (isinstance(gate, ops.MeasurementGate) and not op_args.ignore_measurement_results)
):
for q in qubits:
q_args, op_args = op_args.factor((q,), validate=False)
Expand Down
22 changes: 22 additions & 0 deletions cirq/sim/density_matrix_simulator_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -571,6 +571,28 @@ def test_reset_one_qubit_does_not_affect_partial_trace_of_other_qubits(
np.testing.assert_almost_equal(result.final_density_matrix, expected)


def test_ignore_measurements_remains_entangled():
q0, q1 = cirq.LineQubit.range(2)
simulator1 = cirq.DensityMatrixSimulator(
ignore_measurement_results=True, split_untangled_states=False
)
simulator2 = cirq.DensityMatrixSimulator(
ignore_measurement_results=True, split_untangled_states=True
)
circuit = cirq.Circuit(
cirq.H(q0),
cirq.CX(q0, q1),
cirq.measure(q0),
)
result1 = simulator1.simulate(circuit)
result2 = simulator2.simulate(circuit)
np.testing.assert_almost_equal(result2.final_density_matrix, result1.final_density_matrix)
expected = np.zeros((4, 4))
expected[0, 0] = 0.5
expected[3, 3] = 0.5
np.testing.assert_almost_equal(result2.final_density_matrix, expected)


@pytest.mark.parametrize(
'dtype,circuit',
itertools.product(
Expand Down

0 comments on commit 3de569a

Please sign in to comment.