Skip to content

Commit

Permalink
Adds 2q prep for iswap instead of sqrt_iswap (#6314)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dripto authored Oct 13, 2023
1 parent a98fc61 commit 105d975
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 0 deletions.
1 change: 1 addition & 0 deletions cirq-core/cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@
optimize_for_target_gateset,
parameterized_2q_op_to_sqrt_iswap_operations,
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_iswap,
prepare_two_qubit_state_using_sqrt_iswap,
quantum_shannon_decomposition,
RouteCQC,
Expand Down
1 change: 1 addition & 0 deletions cirq-core/cirq/transformers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
is_negligible_turn,
parameterized_2q_op_to_sqrt_iswap_operations,
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_iswap,
prepare_two_qubit_state_using_sqrt_iswap,
quantum_shannon_decomposition,
single_qubit_matrix_to_gates,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
from cirq.transformers.analytical_decompositions.two_qubit_state_preparation import (
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_sqrt_iswap,
prepare_two_qubit_state_using_iswap,
)

from cirq.transformers.analytical_decompositions.single_to_two_qubit_isometry import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,3 +106,41 @@ def prepare_two_qubit_state_using_cz(
return op_list + _1q_matrices_to_ops(
np.dot(u, np.linalg.inv(u_CZ)), np.dot(vh.T, np.linalg.inv(vh_CZ.T)), q0, q1
)


def prepare_two_qubit_state_using_iswap(
q0: 'cirq.Qid', q1: 'cirq.Qid', state: 'cirq.STATE_VECTOR_LIKE', use_iswap_inv: bool = False
) -> List['cirq.Operation']:
"""Prepares the given 2q state from |00> using at-most 1 ISWAP gate + single qubit rotations.
Entangled states are prepared using exactly 1 ISWAP gate while product states are prepared
using only single qubit rotations (0 ISWAP gates)
Args:
q0: The first qubit being operated on.
q1: The other qubit being operated on.
state: 4x1 matrix representing two qubit state vector, ordered as 00, 01, 10, 11.
use_iswap_inv: If True, uses `cirq.ISWAP_INV` instead of `cirq.ISWAP`.
Returns:
List of operations (at-most 1 ISWAP + single qubit rotations) preparing state from |00>.
"""
state_vector = qis.to_valid_state_vector(state, num_qubits=2)
state_vector = state_vector / np.linalg.norm(state_vector)
u, s, vh = np.linalg.svd(state_vector.reshape(2, 2))
if np.isclose(s[0], 1):
# Product state can be prepare with just single qubit unitaries.
return _1q_matrices_to_ops(u, vh.T, q0, q1, True)
alpha = np.arccos(np.clip(s[0], 0, 1))
op_list = [
ops.ry(2 * alpha).on(q0),
ops.H.on(q1),
ops.ISWAP_INV.on(q0, q1) if use_iswap_inv else ops.ISWAP.on(q0, q1),
]
intermediate_state = circuits.Circuit(op_list).final_state_vector(
ignore_terminal_measurements=False, dtype=np.complex64
)
u_CZ, _, vh_CZ = np.linalg.svd(intermediate_state.reshape(2, 2))
return op_list + _1q_matrices_to_ops(
np.dot(u, np.linalg.inv(u_CZ)), np.dot(vh.T, np.linalg.inv(vh_CZ.T)), q0, q1
)
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,24 @@ def test_prepare_two_qubit_state_using_cz(state):
)


@pytest.mark.parametrize("state", STATES_TO_PREPARE)
@pytest.mark.parametrize("use_iswap_inv", [True, False])
def test_prepare_two_qubit_state_using_iswap(state, use_iswap_inv):
state = cirq.to_valid_state_vector(state, num_qubits=2)
q = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
cirq.prepare_two_qubit_state_using_iswap(*q, state, use_iswap_inv=use_iswap_inv)
)
iswap_gate = cirq.ISWAP_INV if use_iswap_inv else cirq.ISWAP
ops_iswap = [*circuit.findall_operations(lambda op: op.gate == iswap_gate)]
ops_2q = [*circuit.findall_operations(lambda op: cirq.num_qubits(op) > 1)]
assert ops_iswap == ops_2q
assert len(ops_iswap) <= 1
assert cirq.allclose_up_to_global_phase(
circuit.final_state_vector(ignore_terminal_measurements=False, dtype=np.complex64), state
)


@pytest.mark.parametrize("state", STATES_TO_PREPARE)
@pytest.mark.parametrize("use_sqrt_iswap_inv", [True, False])
def test_prepare_two_qubit_state_using_sqrt_iswap(state, use_sqrt_iswap_inv):
Expand Down

0 comments on commit 105d975

Please sign in to comment.