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 #2
0
def generate_library_of_2q_circuits(
    n_library_circuits: int,
    two_qubit_gate: 'cirq.Gate',
    *,
    max_cycle_depth: int = 100,
    q0: 'cirq.Qid' = devices.LineQubit(0),
    q1: 'cirq.Qid' = devices.LineQubit(1),
    random_state: 'cirq.RANDOM_STATE_OR_SEED_LIKE' = None,
) -> List['cirq.Circuit']:
    """Generate a library of two-qubit Circuits.

    For single-qubit gates, this uses PhasedXZGates where the axis-in-XY-plane is one
    of eight eighth turns and the Z rotation angle is one of eight eighth turns. This
    provides 8*8=64 total choices, each implementable with one PhasedXZGate. This is
    appropriate for architectures with microwave single-qubit control.

    Args:
        n_library_circuits: The number of circuits to generate.
        two_qubit_gate: The two qubit gate to use in the circuits.
        max_cycle_depth: The maximum cycle_depth in the circuits to generate. If you are using XEB,
            this must be greater than or equal to the maximum value in `cycle_depths`.
        q0: The first qubit to use when constructing the circuits.
        q1: The second qubit to use when constructing the circuits
        random_state: A random state or seed used to deterministically sample the random circuits.
    """
    rs = value.parse_random_state(random_state)
    exponents = np.linspace(0, 7 / 4, 8)
    single_qubit_gates = [
        ops.PhasedXZGate(x_exponent=0.5, z_exponent=z, axis_phase_exponent=a)
        for a, z in itertools.product(exponents, repeat=2)
    ]
    return [
        random_rotations_between_two_qubit_circuit(
            q0,
            q1,
            depth=max_cycle_depth,
            two_qubit_op_factory=lambda a, b, _: two_qubit_gate(a, b),
            single_qubit_gates=single_qubit_gates,
            seed=rs,
        )
        for _ in range(n_library_circuits)
    ]
Example #3
0
    random_rotations_between_grid_interaction_layers_circuit,
)

if TYPE_CHECKING:
    import cirq

DEFAULT_BASE_DIR = os.path.expanduser(
    os.path.join('~', 'cirq-results', 'grid-parallel-two-qubit-xeb'))

LAYER_A = GridInteractionLayer(col_offset=0, vertical=True, stagger=True)
LAYER_B = GridInteractionLayer(col_offset=1, vertical=True, stagger=True)
LAYER_C = GridInteractionLayer(col_offset=1, vertical=False, stagger=True)
LAYER_D = GridInteractionLayer(col_offset=0, vertical=False, stagger=True)

SINGLE_QUBIT_GATES = [
    ops.PhasedXZGate(x_exponent=0.5, z_exponent=z, axis_phase_exponent=a)
    for a, z in itertools.product(np.linspace(0, 7 / 4, 8), repeat=2)
]

GridQubitPair = Tuple['cirq.GridQubit', 'cirq.GridQubit']


def save(params: Any, obj: Any, base_dir: str, mode: str = 'x') -> str:
    """Save an object to filesystem as a JSON file.

    Arguments:
        params: Parameters describing the object. This should have an `filename`
            attribute containing the filename with which to save the object.
        obj: The object to save.
        base_dir: The directory in which to save the object.
        mode: The mode with which to open the file to write. Defaults to 'x',