Skip to content

Commit

Permalink
Move optimizers/decompositions.py to `transformers/analytical_decom…
Browse files Browse the repository at this point in the history
…positions/single_qubit_decompositions.py` (quantumlib#4799)

Moves the following file from `cirq/optimizers/` to `cirq/transformers/analytical_decompositions/` using `deprecated_submodule`:

 - decompositions.py --> single_qubit_decompositions.py

Part of quantumlib#4722
  • Loading branch information
tanujkhattar authored and rht committed May 1, 2023
1 parent 2fc9dc8 commit 4db207e
Show file tree
Hide file tree
Showing 17 changed files with 71 additions and 42 deletions.
12 changes: 6 additions & 6 deletions cirq-core/cirq/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,17 +335,11 @@
EjectPhasedPaulis,
EjectZ,
ExpandComposite,
is_negligible_turn,
merge_single_qubit_gates_into_phased_x_z,
merge_single_qubit_gates_into_phxz,
MergeInteractions,
MergeInteractionsToSqrtIswap,
MergeSingleQubitGates,
single_qubit_matrix_to_gates,
single_qubit_matrix_to_pauli_rotations,
single_qubit_matrix_to_phased_x_z,
single_qubit_matrix_to_phxz,
single_qubit_op_to_framed_phase_form,
stratified_circuit,
SynchronizeTerminalMeasurements,
two_qubit_matrix_to_operations,
Expand All @@ -360,13 +354,19 @@
decompose_cphase_into_two_fsim,
decompose_multi_controlled_x,
decompose_multi_controlled_rotation,
is_negligible_turn,
map_moments,
map_operations,
map_operations_and_unroll,
merge_moments,
merge_operations,
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_sqrt_iswap,
single_qubit_matrix_to_gates,
single_qubit_matrix_to_pauli_rotations,
single_qubit_matrix_to_phased_x_z,
single_qubit_matrix_to_phxz,
single_qubit_op_to_framed_phase_form,
unroll_circuit_op,
unroll_circuit_op_greedy_earliest,
unroll_circuit_op_greedy_frontier,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import numpy as np

from cirq import ops, protocols, optimizers, linalg
from cirq import ops, protocols, transformers, linalg
from cirq.circuits.circuit import Circuit
from cirq.circuits.optimization_pass import (
PointOptimizationSummary,
Expand Down Expand Up @@ -67,7 +67,7 @@ def _rotation_to_clifford_gate(
return ops.SingleQubitCliffordGate.I

def _matrix_to_clifford_op(self, mat: np.ndarray, qubit: 'cirq.Qid') -> Optional[ops.Operation]:
rotations = optimizers.single_qubit_matrix_to_pauli_rotations(mat, self.atol)
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, self.atol)
clifford_gate = ops.SingleQubitCliffordGate.I
for pauli, half_turns in rotations:
if linalg.all_near_zero_mod(half_turns, 0.5):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

import numpy as np

from cirq import ops, optimizers, protocols, linalg
from cirq import ops, protocols, linalg, transformers
from cirq.circuits.circuit import Circuit
from cirq.circuits.optimization_pass import (
PointOptimizationSummary,
Expand Down Expand Up @@ -56,7 +56,7 @@ def __init__(
self.atol = atol

def _matrix_to_pauli_string_phasors(self, mat: np.ndarray, qubit: 'cirq.Qid') -> ops.OP_TREE:
rotations = optimizers.single_qubit_matrix_to_pauli_rotations(mat, self.atol)
rotations = transformers.single_qubit_matrix_to_pauli_rotations(mat, self.atol)
out_ops: List[ops.Operation] = []
for pauli, half_turns in rotations:
if self.keep_clifford and linalg.all_near_zero_mod(half_turns, 0.5):
Expand Down
4 changes: 2 additions & 2 deletions cirq-core/cirq/ion/convert_to_ion_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

import numpy as np

from cirq import ops, protocols, optimizers, circuits
from cirq import ops, protocols, optimizers, circuits, transformers
from cirq.ion import ms, two_qubit_matrix_to_ion_operations, ion_device


Expand Down Expand Up @@ -66,7 +66,7 @@ def convert_one(self, op: ops.Operation) -> ops.OP_TREE:
# Known matrix
mat = protocols.unitary(op, None) if len(op.qubits) <= 2 else None
if mat is not None and len(op.qubits) == 1:
gates = optimizers.single_qubit_matrix_to_phased_x_z(mat)
gates = transformers.single_qubit_matrix_to_phased_x_z(mat)
return [g.on(op.qubits[0]) for g in gates]
if mat is not None and len(op.qubits) == 2:
return two_qubit_matrix_to_ion_operations(op.qubits[0], op.qubits[1], mat)
Expand Down
4 changes: 2 additions & 2 deletions cirq-core/cirq/ion/ion_decomposition.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

import numpy as np

from cirq import ops, linalg, protocols, optimizers, circuits
from cirq import ops, linalg, protocols, optimizers, circuits, transformers
from cirq.ion import ms

if TYPE_CHECKING:
Expand Down Expand Up @@ -83,7 +83,7 @@ def _kak_decomposition_to_operations(


def _do_single_on(u: np.ndarray, q: 'cirq.Qid', atol: float = 1e-8):
for gate in optimizers.single_qubit_matrix_to_gates(u, atol):
for gate in transformers.single_qubit_matrix_to_gates(u, atol):
yield gate(q)


Expand Down
4 changes: 2 additions & 2 deletions cirq-core/cirq/neutral_atoms/convert_to_neutral_atom_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
PointOptimizer,
)
from cirq.neutral_atoms import neutral_atom_devices
from cirq import optimizers
from cirq import optimizers, transformers

if TYPE_CHECKING:
import cirq
Expand Down Expand Up @@ -57,7 +57,7 @@ def _convert_one(self, op: ops.Operation) -> ops.OP_TREE:
# Known matrix?
mat = protocols.unitary(op, None) if len(op.qubits) <= 2 else None
if mat is not None and len(op.qubits) == 1:
gates = optimizers.single_qubit_matrix_to_phased_x_z(mat)
gates = transformers.single_qubit_matrix_to_phased_x_z(mat)
return [g.on(op.qubits[0]) for g in gates]
if mat is not None and len(op.qubits) == 2:
return optimizers.two_qubit_matrix_to_operations(
Expand Down
17 changes: 8 additions & 9 deletions cirq-core/cirq/optimizers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,6 @@
MergeSingleQubitGates,
)

from cirq.optimizers.decompositions import (
is_negligible_turn,
single_qubit_matrix_to_gates,
single_qubit_matrix_to_pauli_rotations,
single_qubit_matrix_to_phased_x_z,
single_qubit_matrix_to_phxz,
single_qubit_op_to_framed_phase_form,
)

from cirq.optimizers.stratify import (
stratified_circuit,
)
Expand Down Expand Up @@ -119,3 +110,11 @@
deadline="v0.16",
create_attribute=True,
)

_compat.deprecated_submodule(
new_module_name="cirq.transformers.analytical_decompositions.single_qubit_decompositions",
old_parent="cirq.optimizers",
old_child="decompositions",
deadline="v0.16",
create_attribute=True,
)
8 changes: 5 additions & 3 deletions cirq-core/cirq/optimizers/eject_phased_paulis.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import sympy

from cirq import circuits, ops, value, protocols
from cirq.optimizers import decompositions
from cirq.transformers.analytical_decompositions import single_qubit_decompositions

if TYPE_CHECKING:
import cirq
Expand Down Expand Up @@ -69,7 +69,9 @@ def optimize_circuit(self, circuit: circuits.Circuit):
# Collect, phase, and merge Ws.
w = _try_get_known_phased_pauli(op, no_symbolic=not self.eject_parameterized)
if w is not None:
if decompositions.is_negligible_turn((w[0] - 1) / 2, self.tolerance):
if single_qubit_decompositions.is_negligible_turn(
(w[0] - 1) / 2, self.tolerance
):
_potential_cross_whole_w(moment_index, op, self.tolerance, state)
else:
_potential_cross_partial_w(moment_index, op, state)
Expand Down Expand Up @@ -180,7 +182,7 @@ def _potential_cross_whole_w(
# Cancel the gate.
del state.held_w_phases[q]
t = 2 * (b - a)
if not decompositions.is_negligible_turn(t / 2, tolerance):
if not single_qubit_decompositions.is_negligible_turn(t / 2, tolerance):
leftover_phase = ops.Z(q) ** t
state.inline_intos.append((moment_index, leftover_phase))

Expand Down
9 changes: 5 additions & 4 deletions cirq-core/cirq/optimizers/eject_z.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import sympy

from cirq import circuits, ops, protocols
from cirq.optimizers import decompositions
from cirq.transformers.analytical_decompositions import single_qubit_decompositions


def _is_integer(n):
Expand Down Expand Up @@ -74,7 +74,7 @@ def dump_tracked_phase(qubits: Iterable[ops.Qid], index: int) -> None:
for q in qubits:
p = qubit_phase[q]
qubit_phase[q] = 0
if decompositions.is_negligible_turn(p, self.tolerance):
if single_qubit_decompositions.is_negligible_turn(p, self.tolerance):
continue
dumped = False
moment_index = circuit.prev_moment_operating_on([q], index)
Expand Down Expand Up @@ -111,7 +111,8 @@ def dump_tracked_phase(qubits: Iterable[ops.Qid], index: int) -> None:
# If there's no tracked phase, we can move on.
phases = [qubit_phase[q] for q in op.qubits]
if not isinstance(op.gate, ops.PhasedXZGate) and all(
decompositions.is_negligible_turn(p, self.tolerance) for p in phases
single_qubit_decompositions.is_negligible_turn(p, self.tolerance)
for p in phases
):
continue

Expand All @@ -123,7 +124,7 @@ def dump_tracked_phase(qubits: Iterable[ops.Qid], index: int) -> None:
# Try to move the tracked phasing over the operation.
phased_op = op
for i, p in enumerate(phases):
if not decompositions.is_negligible_turn(p, self.tolerance):
if not single_qubit_decompositions.is_negligible_turn(p, self.tolerance):
phased_op = protocols.phase_by(phased_op, -p, i, default=None)
if phased_op is not None:
gate = phased_op.gate
Expand Down
6 changes: 3 additions & 3 deletions cirq-core/cirq/optimizers/merge_single_qubit_gates.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import numpy as np

from cirq import ops, linalg, protocols, circuits
from cirq.optimizers import decompositions
from cirq.transformers.analytical_decompositions import single_qubit_decompositions

if TYPE_CHECKING:
import cirq
Expand Down Expand Up @@ -115,7 +115,7 @@ def merge_single_qubit_gates_into_phased_x_z(circuit: circuits.Circuit, atol: fl
"""

def synth(qubit: 'cirq.Qid', matrix: np.ndarray) -> List[ops.Operation]:
out_gates = decompositions.single_qubit_matrix_to_phased_x_z(matrix, atol)
out_gates = single_qubit_decompositions.single_qubit_matrix_to_phased_x_z(matrix, atol)
return [gate(qubit) for gate in out_gates]

MergeSingleQubitGates(synthesizer=synth).optimize_circuit(circuit)
Expand All @@ -137,7 +137,7 @@ def merge_single_qubit_gates_into_phxz(
"""

def synth(qubit: 'cirq.Qid', matrix: np.ndarray) -> List[ops.Operation]:
gate = decompositions.single_qubit_matrix_to_phxz(matrix, atol)
gate = single_qubit_decompositions.single_qubit_matrix_to_phxz(matrix, atol)
return [gate(qubit)] if gate else []

MergeSingleQubitGates(synthesizer=synth).optimize_circuit(circuit)
4 changes: 2 additions & 2 deletions cirq-core/cirq/optimizers/two_qubit_decompositions.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
from cirq.linalg.decompositions import num_cnots_required, extract_right_diag

from cirq import ops, linalg, protocols, circuits
from cirq.transformers.analytical_decompositions import single_qubit_decompositions
from cirq.optimizers import (
decompositions,
eject_z,
eject_phased_paulis,
merge_single_qubit_gates,
Expand Down Expand Up @@ -236,7 +236,7 @@ def _parity_interaction(


def _do_single_on(u: np.ndarray, q: 'cirq.Qid', atol: float = 1e-8):
for gate in decompositions.single_qubit_matrix_to_gates(u, atol):
for gate in single_qubit_decompositions.single_qubit_matrix_to_gates(u, atol):
yield gate(q)


Expand Down
6 changes: 3 additions & 3 deletions cirq-core/cirq/optimizers/two_qubit_to_sqrt_iswap.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import numpy as np

from cirq import ops, linalg, protocols
from cirq.optimizers import decompositions
from cirq.transformers.analytical_decompositions import single_qubit_decompositions

if TYPE_CHECKING:
import cirq
Expand Down Expand Up @@ -144,7 +144,7 @@ def append(matrix0, matrix1, final_layer=False):
nonlocal prev_commute
# Commute previous Z(q0)**a, Z(q1)**a through earlier sqrt-iSWAP
rots1 = list(
decompositions.single_qubit_matrix_to_pauli_rotations(
single_qubit_decompositions.single_qubit_matrix_to_pauli_rotations(
np.dot(matrix1, prev_commute), atol=atol
)
)
Expand All @@ -163,7 +163,7 @@ def append(matrix0, matrix1, final_layer=False):
new_commute = new_commute @ p_unitary
matrix0 = p_unitary.T.conj() @ matrix0
rots0 = list(
decompositions.single_qubit_matrix_to_pauli_rotations(
single_qubit_decompositions.single_qubit_matrix_to_pauli_rotations(
np.dot(matrix0, prev_commute), atol=atol
)
)
Expand Down
6 changes: 6 additions & 0 deletions cirq-core/cirq/transformers/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,14 @@
decompose_clifford_tableau_to_operations,
decompose_multi_controlled_x,
decompose_multi_controlled_rotation,
is_negligible_turn,
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_sqrt_iswap,
single_qubit_matrix_to_gates,
single_qubit_matrix_to_pauli_rotations,
single_qubit_matrix_to_phased_x_z,
single_qubit_matrix_to_phxz,
single_qubit_op_to_framed_phase_form,
)

from cirq.transformers.transformer_primitives import (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,15 @@
decompose_cphase_into_two_fsim,
)

from cirq.transformers.analytical_decompositions.single_qubit_decompositions import (
is_negligible_turn,
single_qubit_matrix_to_gates,
single_qubit_matrix_to_pauli_rotations,
single_qubit_matrix_to_phased_x_z,
single_qubit_matrix_to_phxz,
single_qubit_op_to_framed_phase_form,
)

from cirq.transformers.analytical_decompositions.two_qubit_state_preparation import (
prepare_two_qubit_state_using_cz,
prepare_two_qubit_state_using_sqrt_iswap,
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@

import cirq

ALLOW_DEPRECATION_IN_TEST = 'ALLOW_DEPRECATION_IN_TEST'


def test_deprecated_submodule():
with cirq.testing.assert_deprecated(
"Use cirq.transformers.analytical_decompositions.single_qubit_decompositions instead",
deadline="v0.16",
):
_ = cirq.optimizers.decompositions.single_qubit_matrix_to_phxz


def assert_gates_implement_unitary(
gates: Sequence[cirq.SingleQubitGate], intended_effect: np.ndarray, atol: float
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@
import numpy as np

from cirq import ops, qis, circuits
from cirq.optimizers import decompositions
from cirq.transformers.analytical_decompositions import single_qubit_decompositions

if TYPE_CHECKING:
import cirq


def _1q_matrices_to_ops(g0, g1, q0, q1, include_identity=False):
ret = []
for g, q in zip(map(decompositions.single_qubit_matrix_to_phxz, [g0, g1]), [q0, q1]):
for g, q in zip(
map(single_qubit_decompositions.single_qubit_matrix_to_phxz, [g0, g1]), [q0, q1]
):
if g is not None:
ret.append(g.on(q))
elif include_identity:
Expand Down

0 comments on commit 4db207e

Please sign in to comment.