Example #1
0
def assert_has_consistent_trace_distance_bound(val: Any) -> None:
    u = protocols.unitary(val, default=None)
    val_from_trace = protocols.trace_distance_bound(val)
    assert 0.0 <= val_from_trace <= 1.0
    if u is not None:

        class Unitary:
            def _unitary_(self):
                return u

        val_from_unitary = protocols.trace_distance_bound(Unitary())

        assert val_from_trace >= val_from_unitary or np.isclose(
            val_from_trace, val_from_unitary)
Example #2
0
def single_qubit_matrix_to_phased_x_z(mat: np.ndarray,
                                      atol: float = 0
                                      ) -> List[ops.SingleQubitGate]:
    """Implements a single-qubit operation with a PhasedX and Z gate.

    If one of the gates isn't needed, it will be omitted.

    Args:
        mat: The 2x2 unitary matrix of the operation to implement.
        atol: A limit on the amount of error introduced by the
            construction.

    Returns:
        A list of gates that, when applied in order, perform the desired
            operation.
    """

    xy_turn, xy_phase_turn, total_z_turn = (
        _deconstruct_single_qubit_matrix_into_gate_turns(mat))

    # Build the intended operation out of non-negligible XY and Z rotations.
    result = [
        ops.PhasedXPowGate(exponent=2 * xy_turn,
                           phase_exponent=2 * xy_phase_turn),
        ops.Z**(2 * total_z_turn)
    ]
    result = [g for g in result if protocols.trace_distance_bound(g) > atol]

    # Special case: XY half-turns can absorb Z rotations.
    if len(result) == 2 and abs(xy_turn) >= 0.5 - atol:
        return [
            ops.PhasedXPowGate(phase_exponent=2 * xy_phase_turn + total_z_turn)
        ]

    return result
def single_qubit_matrix_to_phxz(mat: np.ndarray, atol: float = 0) -> Optional[ops.PhasedXZGate]:
    """Implements a single-qubit operation with a PhasedXZ gate.

    Under the hood, this uses deconstruct_single_qubit_matrix_into_angles which
    converts the given matrix to a series of three rotations around the Z, Y, Z
    axes. This is then converted to a phased X rotation followed by a Z, in the
    form of a single PhasedXZ gate.

    Args:
        mat: The 2x2 unitary matrix of the operation to implement.
        atol: A limit on the amount of error introduced by the
            construction.

    Returns:
        A PhasedXZ gate that implements the given matrix, or None if it is
        close to identity (trace distance <= atol).
    """

    xy_turn, xy_phase_turn, total_z_turn = _deconstruct_single_qubit_matrix_into_gate_turns(mat)

    # Build the intended operation out of non-negligible XY and Z rotations.
    g = ops.PhasedXZGate(
        axis_phase_exponent=2 * xy_phase_turn, x_exponent=2 * xy_turn, z_exponent=2 * total_z_turn
    )

    if protocols.trace_distance_bound(g) <= atol:
        return None

    # Special case: XY half-turns can absorb Z rotations.
    if math.isclose(abs(xy_turn), 0.5, abs_tol=atol):
        g = ops.PhasedXZGate(
            axis_phase_exponent=2 * xy_phase_turn + total_z_turn, x_exponent=1, z_exponent=0
        )

    return g
Example #4
0
def assert_has_consistent_trace_distance_bound(val: Any) -> None:
    # pylint: disable=unused-variable
    __tracebackhide__ = True
    # pylint: enable=unused-variable
    u = protocols.unitary(val, default=None)
    val_from_trace = protocols.trace_distance_bound(val)
    assert 0.0 <= val_from_trace <= 1.0
    if u is not None:

        class Unitary:
            def _unitary_(self):
                return u

        val_from_unitary = protocols.trace_distance_bound(Unitary())

        assert val_from_trace >= val_from_unitary or np.isclose(val_from_trace, val_from_unitary)
 def optimize_circuit(self, circuit: _circuit.Circuit) -> None:
     deletions: List[Tuple[int, ops.Operation]] = []
     for moment_index, moment in enumerate(circuit):
         for op in moment.operations:
             if op is not None and protocols.trace_distance_bound(op) <= self.tolerance:
                 deletions.append((moment_index, op))
     circuit.batch_remove(deletions)
Example #6
0
def single_qubit_matrix_to_native_gates(mat: np.ndarray,
                                        tolerance: float = 0
                                        ) -> List[ops.SingleQubitGate]:
    """Implements a single-qubit operation with few native gates.

    Args:
        mat: The 2x2 unitary matrix of the operation to implement.
        tolerance: A limit on the amount of error introduced by the
            construction.

    Returns:
        A list of gates that, when applied in order, perform the desired
            operation.
    """

    xy_turn, xy_phase_turn, total_z_turn = (
        _deconstruct_single_qubit_matrix_into_gate_turns(mat))

    # Build the intended operation out of non-negligible XY and Z rotations.
    result = [
        ExpWGate(half_turns=2 * xy_turn, axis_half_turns=2 * xy_phase_turn),
        ops.RotZGate(half_turns=2 * total_z_turn)
    ]
    result = [
        g for g in result if protocols.trace_distance_bound(g) > tolerance
    ]

    # Special case: XY half-turns can absorb Z rotations.
    if len(result) == 2 and abs(xy_turn) >= 0.5 - tolerance:
        return [ExpWGate(axis_half_turns=2 * xy_phase_turn + total_z_turn)]

    return result
Example #7
0
 def _trace_distance_bound_(self) -> Optional[float]:
     if protocols.is_parameterized(self.sub_gate):
         return None
     angle = self._num_copies * np.arcsin(protocols.trace_distance_bound(self.sub_gate))
     if angle >= np.pi * 0.5:
         return 1.0
     return np.sin(angle)
Example #8
0
 def _trace_distance_bound_(self) -> float:
     return protocols.trace_distance_bound(self.sub_operation)
Example #9
0
 def _trace_distance_bound_(self) -> float:
     result = protocols.trace_distance_bound(self.sub_gate)
     if not self._is_parameterized_():
         result *= float(self.probability)
     return result
Example #10
0
 def _trace_distance_bound_(self) -> float:
     return protocols.trace_distance_bound(
         ops.RotZGate(half_turns=self.half_turns))
Example #11
0
 def _trace_distance_bound_(self):
     """See `cirq.SupportsTraceDistanceBound`."""
     return protocols.trace_distance_bound(cirq.X**self._exponent)
Example #12
0
 def _trace_distance_bound_(self) -> Optional[float]:
     angle = (len(self.qubits) *
              np.arcsin(protocols.trace_distance_bound(self._gate)))
     if angle >= np.pi * 0.5:
         return 1.0
     return np.sin(angle)
Example #13
0
 def _trace_distance_bound_(self):
     return protocols.trace_distance_bound(self.sub_gate)
Example #14
0
 def map_func(op: 'cirq.Operation', _: int) -> 'cirq.OP_TREE':
     return (
         op if protocols.is_measurement(op) or protocols.trace_distance_bound(op) > atol else []
     )
Example #15
0
 def _trace_distance_bound_(self) -> float:
     return protocols.trace_distance_bound(
         pauli_gates.Z**self.exponent_relative)
Example #16
0
 def _trace_distance_bound_(self) -> float:
     return protocols.trace_distance_bound(ops.Z**self.half_turns)
Example #17
0
 def _trace_distance_bound_(self) -> float:
     if len(self.qubits) == 0:
         return 0.0
     return protocols.trace_distance_bound(
         pauli_gates.Z**self.exponent_relative)
Example #18
0
 def _trace_distance_bound_(self) -> float:
     return protocols.trace_distance_bound(self.gate)