Skip to content

Commit

Permalink
try an ancilla
Browse files Browse the repository at this point in the history
  • Loading branch information
daxfohl committed Mar 25, 2023
1 parent f114996 commit 548e61f
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
12 changes: 12 additions & 0 deletions cirq-core/cirq/sim/simulation_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ def kronecker_product(self: TSelf, other: TSelf, *, inplace=False) -> TSelf:
args._set_qubits(self.qubits + other.qubits)
return args

def add_qubits(self: TSelf, qubits: Sequence['cirq.Qid']) -> TSelf:
new_space = type(self)(qubits=qubits) # type: ignore
return self.kronecker_product(new_space, inplace=True)

def remove_qubits(self: TSelf, qubits: Sequence['cirq.Qid']) -> TSelf:
return self.factor(qubits, inplace=True)[1]

def factor(
self: TSelf, qubits: Sequence['cirq.Qid'], *, validate=True, atol=1e-07, inplace=False
) -> Tuple[TSelf, TSelf]:
Expand Down Expand Up @@ -298,11 +305,16 @@ def strat_act_on_from_apply_decompose(
operations, qubits1, _ = _try_decompose_into_operations_and_qubits(val)
assert len(qubits1) == len(qubits)
qubit_map = {q: qubits[i] for i, q in enumerate(qubits1)}
ancillas = list(set([q for op in operations for q in op.qubits if q not in qubits1]))
for q in ancillas:
qubit_map[q] = q
args.add_qubits(ancillas)
if operations is None:
return NotImplemented
for operation in operations:
operation = operation.with_qubits(*[qubit_map[q] for q in operation.qubits])
protocols.act_on(operation, args)
args.remove_qubits(ancillas)
return True


Expand Down
28 changes: 28 additions & 0 deletions cirq-core/cirq/sim/simulation_state_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,3 +101,31 @@ def test_field_getters():
args = DummySimulationState()
assert args.prng is np.random
assert args.qubit_map == {q: i for i, q in enumerate(cirq.LineQubit.range(2))}


@pytest.mark.parametrize('exp', [-3, -2, -1, 0, 1, 2, 3])
def test_ancilla(exp):
class AncillaX(cirq.Gate):
def __init__(self, exponent=1):
self._exponent = exponent

def num_qubits(self) -> int:
return 1

def _decompose_(self, qubits):
ancilla = cirq.NamedQubit('Ancilla')
yield cirq.X(ancilla) ** self._exponent
yield cirq.CX(ancilla, qubits[0])
yield cirq.X(ancilla) ** -self._exponent

q = cirq.LineQubit(0)
test_circuit = cirq.Circuit(AncillaX(exp).on(q))
control_circuit = cirq.Circuit(cirq.XPowGate(exponent=exp).on(q))

test_sv = cirq.final_state_vector(test_circuit)
control_sv = cirq.final_state_vector(control_circuit)
assert np.allclose(test_sv, control_sv)

test_dm = cirq.final_density_matrix(test_circuit)
control_dm = cirq.final_density_matrix(control_circuit)
assert np.allclose(test_dm, control_dm)

0 comments on commit 548e61f

Please sign in to comment.