Skip to content

Commit

Permalink
Fix sign error in EjectFullW and silent merge error in eject_z_test.py (
Browse files Browse the repository at this point in the history
#691)

- Slipped by because of a silent merge conflict overwriting updated methods with old ones
- The old methods were calling the new "canonicalize_up_to_measurement_phase" with the wrong number of arguments, triggering a type error, triggering a path expecting a type error for a *different reason* (i.e. non-unitary operations in the circuit)
- Removed the non-unitary fallback path and renamed the method to make it clear only measurement-implies-terminal circuits were expected
- Simplified the W-over-partial-W derivation
- Fixed false-positive assertions that were now correctly failing
- Added a test that fails for the old behavior but not for the new behavior

Fixes #684
  • Loading branch information
Strilanc authored Jul 17, 2018
1 parent 2beb783 commit 342bcc3
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 24 deletions.
27 changes: 11 additions & 16 deletions cirq/google/eject_full_w.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@

from typing import Optional, cast, TYPE_CHECKING, Iterable

from cirq import circuits, ops, extension
from cirq import circuits, ops, extension, value
from cirq.google import decompositions
from cirq.google.xmon_gates import ExpZGate, ExpWGate, Exp11Gate
from cirq.value import Symbol

if TYPE_CHECKING:
# pylint: disable=unused-import
Expand Down Expand Up @@ -205,15 +204,11 @@ def _potential_cross_partial_w(moment_index: int,
Uses the following identity:
───W(a)───W(b)^t───
≡ ───Z^-a───X───Z^a───Z^-b───X^t───Z^b─── (expand Ws)
≡ ───Z^-a───Z^-a───Z^b───X^t───Z^-b───X─── (move X right flipping Zs)
≡ ───Z^(b-2a)───X^t───Z^-b───X─── (merge Zs)
≡ ───Z^(b-2a)───X^t───Z^-(b-2a)───Z^(b-2a)───Z^-b───X─── (match left Z)
≡ ───W(b-2a)^t───Z^(b-2a)───Z^-b───X─── (merge into W)
≡ ───W(b-2a)^t───Z^-2a───X─── (cancel Z^b)
≡ ───W(b-2a)^t───Z^-a───Z^-a───X─── (split Z^-2a)
≡ ───W(b-2a)^t───Z^-a───X───Z^a─── (flip Z^-a across)
≡ ───W(b-2a)^t───W(a)─── (merge W)
≡ ───Z^-a───X───Z^a───W(b)^t────── (expand W(a))
≡ ───Z^-a───X───W(b-a)^t───Z^a──── (move Z^a across, phasing axis)
≡ ───Z^-a───W(a-b)^t───X───Z^a──── (move X across, negating axis angle)
≡ ───W(2a-b)^t───Z^-a───X───Z^a─── (move Z^-a across, phasing axis)
≡ ───W(2a-b)^t───W(a)───
"""
a = state.held_w_phases.get(op.qubits[0])
if a is None:
Expand All @@ -222,7 +217,7 @@ def _potential_cross_partial_w(moment_index: int,
b = cast(float, w.axis_half_turns)
t = cast(float, w.half_turns)
new_op = ExpWGate(half_turns=t,
axis_half_turns=b-2*a).on(op.qubits[0])
axis_half_turns=2*a-b).on(op.qubits[0])
state.deletions.append((moment_index, op))
state.inline_intos.append((moment_index, new_op))

Expand Down Expand Up @@ -314,16 +309,16 @@ def _try_get_known_cz_half_turns(op: ops.Operation) -> Optional[float]:
not isinstance(op.gate, (Exp11Gate, ops.Rot11Gate))):
return None
h = op.gate.half_turns
if isinstance(h, Symbol):
if isinstance(h, value.Symbol):
return None
return h


def _try_get_known_w(op: ops.Operation) -> Optional[ExpWGate]:
if (not isinstance(op, ops.GateOperation) or
not isinstance(op.gate, ExpWGate) or
isinstance(op.gate.half_turns, Symbol) or
isinstance(op.gate.axis_half_turns, Symbol)):
isinstance(op.gate.half_turns, value.Symbol) or
isinstance(op.gate.axis_half_turns, value.Symbol)):
return None
return op.gate

Expand All @@ -333,6 +328,6 @@ def _try_get_known_z_half_turns(op: ops.Operation) -> Optional[float]:
not isinstance(op.gate, (ExpZGate, ops.RotZGate))):
return None
h = op.gate.half_turns
if isinstance(h, Symbol):
if isinstance(h, value.Symbol):
return None
return h
15 changes: 13 additions & 2 deletions cirq/google/eject_full_w_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ def test_phases_partial_ws():
),
expected=quick_circuit(
[],
[cg.ExpWGate(axis_half_turns=0.25, half_turns=0.5).on(q)],
[cg.ExpWGate(axis_half_turns=-0.25, half_turns=0.5).on(q)],
[cg.ExpWGate().on(q)],
))

Expand All @@ -258,7 +258,7 @@ def test_phases_partial_ws():
),
expected=quick_circuit(
[],
[cg.ExpWGate(axis_half_turns=-0.5, half_turns=0.5).on(q)],
[cg.ExpWGate(axis_half_turns=0.5, half_turns=0.5).on(q)],
[cg.ExpWGate(axis_half_turns=0.25).on(q)],
))

Expand All @@ -273,6 +273,17 @@ def test_phases_partial_ws():
[cg.ExpWGate(axis_half_turns=0.25).on(q)],
))

assert_optimizes(
before=quick_circuit(
[cg.ExpWGate().on(q)],
[cg.ExpWGate(half_turns=-0.25, axis_half_turns=0.5).on(q)]
),
expected=quick_circuit(
[],
[cg.ExpWGate(half_turns=-0.25, axis_half_turns=-0.5).on(q)],
[cg.ExpWGate().on(q)],
))


def test_blocked_by_unknown_and_symbols():
a = cirq.NamedQubit('a')
Expand Down
10 changes: 4 additions & 6 deletions cirq/google/eject_z.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,16 @@

from collections import defaultdict

from cirq import ops, extension
from cirq.circuits import Circuit, OptimizationPass
from cirq import circuits, ops, extension, value
from cirq.google.decompositions import is_negligible_turn
from cirq.google.xmon_gates import ExpZGate
from cirq.value import Symbol

if TYPE_CHECKING:
# pylint: disable=unused-import
from typing import Dict, List, Tuple


class EjectZ(OptimizationPass):
class EjectZ(circuits.OptimizationPass):
"""Pushes Z gates towards the end of the circuit.
As the Z gates get pushed they may absorb other Z gates, get absorbed into
Expand All @@ -50,7 +48,7 @@ def __init__(self,
self.tolerance = tolerance
self.ext = ext or extension.Extensions()

def optimize_circuit(self, circuit: Circuit):
def optimize_circuit(self, circuit: circuits.Circuit):
turns_state = defaultdict(lambda: 0) # type: Dict[ops.QubitId, float]

def dump_phases(qubits, index):
Expand Down Expand Up @@ -105,6 +103,6 @@ def _try_get_known_z_half_turns(op: ops.Operation) -> Optional[float]:
if not isinstance(op.gate, (ExpZGate, ops.RotZGate)):
return None
h = op.gate.half_turns
if isinstance(h, Symbol):
if isinstance(h, value.Symbol):
return None
return h

0 comments on commit 342bcc3

Please sign in to comment.