Skip to content

Commit

Permalink
Merge pull request #82 from zapatacomputing/zqs-1313-implement-contro…
Browse files Browse the repository at this point in the history
…lled-version-of-circuit

feat(circuit.py): add controlled()
  • Loading branch information
Athena Caesura authored Mar 17, 2023
2 parents c49d096 + d596a85 commit ecb2726
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
18 changes: 18 additions & 0 deletions src/orquestra/quantum/circuits/_circuit.py
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,24 @@ def inverse(self) -> "Circuit":
" since there are operators in it without the `dagger` method."
) from e

def controlled(self, control_index: int) -> "Circuit":
"""Return a circuit where all the operations from self are turned into their
respective controlled operations whose control is the qubit with index given
by control_index.
Args:
control_index: the index for the added qubit used to control the circuit
given by self.
"""
c_ops = []
for op in self.operations:
controlled_op = op.gate.controlled(1)
new_indices = (i + 1 if i >= control_index else i for i in op.qubit_indices)
new_indices_with_control = (control_index, *new_indices)
c_ops.append(controlled_op(*new_indices_with_control))

return Circuit(c_ops)


@singledispatch
def _append_to_circuit(other, circuit: Circuit):
Expand Down
36 changes: 36 additions & 0 deletions tests/orquestra/quantum/circuits/_circuit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -270,3 +270,39 @@ def test_inverting_a_circuit_without_dagger_fails(self):
circuit = Circuit(operations=[gate])
with pytest.raises(AttributeError):
circuit.inverse()


@pytest.mark.parametrize(
"circuit, control_index, target_circuit",
[
(Circuit([X(0)]), 0, Circuit([X.controlled(1)(0, 1)])),
(Circuit([H(0)]), 0, Circuit([H.controlled(1)(0, 1)])),
(Circuit([X(0)]), 1, Circuit([X.controlled(1)(1, 0)])),
(Circuit([H(0)]), 4, Circuit([H.controlled(1)(4, 0)])),
(Circuit([X(2)]), 1, Circuit([X.controlled(1)(1, 3)])),
(Circuit([CNOT(0, 1)]), 0, Circuit([CNOT.controlled(1)(0, 1, 2)])),
(Circuit([CNOT(0, 1)]), 1, Circuit([CNOT.controlled(1)(1, 0, 2)])),
(
Circuit([X(0), CNOT(0, 1)]),
0,
Circuit([X.controlled(1)(0, 1), CNOT.controlled(1)(0, 1, 2)]),
),
(
Circuit([X(2), CNOT(0, 1)]),
0,
Circuit([X.controlled(1)(0, 3), CNOT.controlled(1)(0, 1, 2)]),
),
(
Circuit([X(2), CNOT(0, 1)]),
2,
Circuit([X.controlled(1)(2, 3), CNOT.controlled(1)(2, 0, 1)]),
),
],
)
def test_controlled_circuit_gives_correct_output(
circuit, control_index, target_circuit
):
test_circuit = circuit.controlled(control_index)

assert test_circuit.n_qubits == target_circuit.n_qubits
assert test_circuit == target_circuit

0 comments on commit ecb2726

Please sign in to comment.