def assert_decompose_is_consistent_with_unitary(
        val: Any, ignoring_global_phase: bool = False):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""
    # pylint: disable=unused-variable
    __tracebackhide__ = True
    # pylint: enable=unused-variable

    expected = protocols.unitary(val, None)
    if expected is None:
        # If there's no unitary, it's vacuously consistent.
        return
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val, default=None)
    else:
        qubits = tuple(devices.LineQid.for_gate(val))
        dec = protocols.decompose_once_with_qubits(val, qubits, default=None)
    if dec is None:
        # If there's no decomposition, it's vacuously consistent.
        return

    actual = circuits.Circuit(dec).unitary(qubit_order=qubits)

    if ignoring_global_phase:
        lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                         expected,
                                                         atol=1e-8)
    else:
        # coverage: ignore
        np.testing.assert_allclose(actual, expected, atol=1e-8)
示例#2
0
def assert_decompose_is_consistent_with_unitary(
        val: Any, ignoring_global_phase: bool = False):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    expected = protocols.unitary(val, None)
    if expected is None:
        # If there's no unitary, it's vacuously consistent.
        return
    qubit_count = len(expected).bit_length() - 1
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val, default=None)
    else:
        qubits = tuple(line.LineQubit.range(qubit_count))
        dec = protocols.decompose_once_with_qubits(val, qubits, default=None)
    if dec is None:
        # If there's no decomposition, it's vacuously consistent.
        return

    actual = circuits.Circuit.from_ops(dec).unitary(qubit_order=qubits)

    if ignoring_global_phase:
        lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                         expected,
                                                         atol=1e-8)
    else:
        # coverage: ignore
        np.testing.assert_allclose(actual, expected, atol=1e-8)
示例#3
0
def assert_phase_by_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    original = protocols.unitary(val, None)
    if original is None:
        # If there's no unitary, it's vacuously consistent.
        return
    qubit_count = len(original).bit_length() - 1
    original = original.reshape((2, 2) * qubit_count)

    for t in [0.125, -0.25, 1]:
        p = 1j**(t * 4)
        for i in range(qubit_count):
            phased = protocols.phase_by(val, t, i, default=None)
            if phased is None:
                # If not phaseable, then phase_by is vacuously consistent.
                continue

            actual = protocols.unitary(phased).reshape((2, 2) * qubit_count)

            expected = np.array(original)
            s = linalg.slice_for_qubits_equal_to([i], 1)
            expected[s] *= p
            s = linalg.slice_for_qubits_equal_to([qubit_count + i], 1)
            expected[s] *= np.conj(p)

            lin_alg_utils.assert_allclose_up_to_global_phase(
                actual,
                expected,
                atol=1e-8,
                err_msg='Phased unitary was incorrect for index #{}'.format(i))
示例#4
0
def assert_phase_by_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    original = protocols.unitary(val, None)
    if original is None:
        # If there's no unitary, it's vacuously consistent.
        return
    qid_shape = protocols.qid_shape(val,
                                    default=(2,) *
                                    (len(original).bit_length() - 1))
    original = original.reshape(qid_shape * 2)

    for t in [0.125, -0.25, 1, sympy.Symbol('a'), sympy.Symbol('a') + 1]:
        p = 1j**(t*4)
        p = protocols.resolve_parameters(p, {'a': -0.125})
        for i in range(len(qid_shape)):
            phased = protocols.phase_by(val, t, i, default=None)
            if phased is None:
                # If not phaseable, then phase_by is vacuously consistent.
                continue

            phased = protocols.resolve_parameters(phased, {'a': -0.125})
            actual = protocols.unitary(phased).reshape(qid_shape * 2)

            expected = np.array(original)
            s = linalg.slice_for_qubits_equal_to([i], 1)
            expected[s] *= p
            s = linalg.slice_for_qubits_equal_to([len(qid_shape) + i], 1)
            expected[s] *= np.conj(p)

            lin_alg_utils.assert_allclose_up_to_global_phase(
                actual,
                expected,
                atol=1e-8,
                err_msg='Phased unitary was incorrect for index #{}'.format(i))
示例#5
0
def assert_phase_by_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    original = protocols.unitary(val)
    qubit_count = len(original).bit_length() - 1
    original.shape = (2, 2) * qubit_count

    at_least_one_qubit_is_phaseable = False
    for t in [0.125, -0.25, 1]:
        p = 1j**(t * 4)
        for i in range(qubit_count):
            phased = protocols.phase_by(val, t, i, default=None)
            if phased is None:
                continue
            at_least_one_qubit_is_phaseable = True

            actual = protocols.unitary(phased)
            actual.shape = (2, 2) * qubit_count

            expected = np.array(original)
            s = linalg.slice_for_qubits_equal_to([i], 1)
            expected[s] *= p
            s = linalg.slice_for_qubits_equal_to([qubit_count + i], 1)
            expected[s] *= np.conj(p)

            lin_alg_utils.assert_allclose_up_to_global_phase(
                actual,
                expected,
                atol=1e-8,
                err_msg='Phased unitary was incorrect for index #{}'.format(i))

    assert at_least_one_qubit_is_phaseable, (
        '_phase_by_ is consistent with _unitary_, but only because the given '
        'value was not phaseable.')
示例#6
0
def assert_decompose_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._phase_by_`'s behavior."""

    expected = protocols.unitary(val)
    qubit_count = len(expected).bit_length() - 1
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        dec = protocols.decompose_once(val)
    else:
        qubits = tuple(line.LineQubit.range(qubit_count))
        dec = protocols.decompose_once_with_qubits(val, qubits)
    actual = circuits.Circuit.from_ops(dec).to_unitary_matrix(
        qubit_order=qubits)

    lin_alg_utils.assert_allclose_up_to_global_phase(actual,
                                                     expected,
                                                     atol=1e-8)
示例#7
0
def assert_qiskit_parsed_qasm_consistent_with_unitary(qasm, unitary):
    # coverage: ignore
    try:
        # We don't want to require qiskit as a dependency but
        # if Qiskit is installed, test QASM output against it.
        import qiskit  # type: ignore
    except ImportError:
        return

    num_qubits = int(np.log2(len(unitary)))
    result = qiskit.execute(
        qiskit.QuantumCircuit.from_qasm_str(qasm),
        backend=qiskit.Aer.get_backend('unitary_simulator'))
    qiskit_unitary = result.result().get_unitary()
    qiskit_unitary = _reorder_indices_of_matrix(
        qiskit_unitary, list(reversed(range(num_qubits))))

    lin_alg_utils.assert_allclose_up_to_global_phase(unitary,
                                                     qiskit_unitary,
                                                     rtol=1e-8,
                                                     atol=1e-8)
示例#8
0
def assert_qasm_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._qasm_`'s behavior."""

    # Only test if qiskit is installed.
    try:
        import qiskit
    except ImportError:
        # coverage: ignore
        warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
                      "qiskit isn't installed to verify against.")
        return

    unitary = protocols.unitary(val, None)
    if unitary is None:
        # Vacuous consistency.
        return

    controls = getattr(val, 'control_qubits', None)
    if controls is None:
        qubit_count = len(unitary).bit_length() - 1
    else:
        qubit_count = len(unitary).bit_length() - 1 - (len(controls) -
                                                       controls.count(None))
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        op = val
    elif isinstance(val, ops.Gate):
        qubits = tuple(line.LineQubit.range(qubit_count))
        op = val.on(*qubits)
    else:
        raise NotImplementedError("Don't know how to test {!r}".format(val))

    args = protocols.QasmArgs(
        qubit_id_map={q: 'q[{}]'.format(i)
                      for i, q in enumerate(qubits)})
    qasm = protocols.qasm(op, args=args, default=None)
    if qasm is None:
        return

    header = """
OPENQASM 2.0;
include "qelib1.inc";
qreg q[{}];
""".format(len(qubits))
    qasm = header + qasm

    qasm_unitary = None
    try:
        result = qiskit.execute(
            qiskit.load_qasm_string(qasm),
            backend=qiskit.Aer.get_backend('unitary_simulator'))
        qasm_unitary = result.result().get_unitary()
        qasm_unitary = _reorder_indices_of_matrix(
            qasm_unitary, list(reversed(range(len(qubits)))))

        lin_alg_utils.assert_allclose_up_to_global_phase(qasm_unitary,
                                                         unitary,
                                                         rtol=1e-8,
                                                         atol=1e-8)
    except Exception as ex:
        if qasm_unitary is not None:
            p_unitary, p_qasm_unitary = linalg.match_global_phase(
                unitary, qasm_unitary)
        else:
            p_unitary = None
            p_qasm_unitary = None
        raise AssertionError(
            'QASM be consistent with cirq.unitary(op) up to global phase.\n\n'
            'op:\n{}\n\n'
            'cirq.unitary(op):\n{}\n\n'
            'Generated QASM:\n\n{}\n\n'
            'Unitary of generated QASM:\n{}\n\n'
            'Phased matched cirq.unitary(op):\n{}\n\n'
            'Phased matched unitary of generated QASM:\n{}\n\n'
            'Underlying error:\n{}'.format(_indent(repr(op)),
                                           _indent(repr(unitary)),
                                           _indent(qasm),
                                           _indent(repr(qasm_unitary)),
                                           _indent(repr(p_unitary)),
                                           _indent(repr(p_qasm_unitary)),
                                           _indent(str(ex))))
示例#9
0
def assert_qasm_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._qasm_`'s behavior."""

    # Only test if qiskit is installed.
    try:
        import qiskit
    except ImportError:
        # coverage: ignore
        warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
                      "qiskit isn't installed to verify against.")
        return

    unitary = protocols.unitary(val, None)
    if unitary is None:
        # Vacuous consistency.
        return

    qubit_count = len(unitary).bit_length() - 1
    if isinstance(val, ops.Operation):
        qubits = val.qubits
        op = val
    elif isinstance(val, ops.Gate):
        qubits = tuple(line.LineQubit.range(qubit_count))
        op = val.on(*qubits)
    else:
        raise NotImplementedError("Don't know how to test {!r}".format(val))

    qasm = str(circuits.QasmOutput(op, qubits[::-1], precision=10))

    qasm_unitary = None
    try:
        result = qiskit.execute(
            qiskit.load_qasm_string(qasm),
            backend=qiskit.Aer.get_backend('unitary_simulator'))
        qasm_unitary = result.result().get_unitary()

        lin_alg_utils.assert_allclose_up_to_global_phase(
            qasm_unitary,
            unitary,
            rtol=1e-8,
            atol=1e-8)
    except Exception as ex:
        if qasm_unitary is not None:
            p_unitary, p_qasm_unitary = linalg.match_global_phase(
                unitary, qasm_unitary)
        else:
            p_unitary = None
            p_qasm_unitary = None
        raise AssertionError(
            'QASM be consistent with cirq.unitary(op) up to global phase.\n\n'
            'op:\n{}\n\n'
            'cirq.unitary(op):\n{}\n\n'
            'Generated QASM:\n\n{}\n\n'
            'Unitary of generated QASM:\n{}\n\n'
            'Phased matched cirq.unitary(op):\n{}\n\n'
            'Phased matched unitary of generated QASM:\n{}\n\n'
            'Underlying error:\n{}'.format(
                _indent(repr(op)),
                _indent(repr(unitary)),
                _indent(qasm),
                _indent(repr(qasm_unitary)),
                _indent(repr(p_unitary)),
                _indent(repr(p_qasm_unitary)),
                _indent(str(ex))))
示例#10
0
def assert_qasm_is_consistent_with_unitary(val: Any):
    """Uses `val._unitary_` to check `val._qasm_`'s behavior."""

    # Only test if qiskit is installed.
    try:
        import qiskit
    except ImportError:
        # coverage: ignore
        warnings.warn("Skipped assert_qasm_is_consistent_with_unitary because "
                      "qiskit isn't installed to verify against.")
        return

    unitary = protocols.unitary(val, None)
    if unitary is None:
        # Vacuous consistency.
        return

    if isinstance(val, ops.Operation):
        qubits: Sequence[ops.Qid] = val.qubits
        op = val
    elif isinstance(val, ops.Gate):
        qid_shape = protocols.qid_shape(val)
        remaining_shape = list(qid_shape)
        controls = getattr(val, 'control_qubits', None)
        if controls is not None:
            for i, q in zip(reversed(range(len(controls))),
                            reversed(controls)):
                if q is not None:
                    remaining_shape.pop(i)
        qubits = devices.LineQid.for_qid_shape(remaining_shape)
        op = val.on(*qubits)
    else:
        raise NotImplementedError(f"Don't know how to test {val!r}")

    args = protocols.QasmArgs(
        qubit_id_map={q: f'q[{i}]'
                      for i, q in enumerate(qubits)})
    qasm = protocols.qasm(op, args=args, default=None)
    if qasm is None:
        return

    num_qubits = len(qubits)
    header = f"""
OPENQASM 2.0;
include "qelib1.inc";
qreg q[{num_qubits}];
"""
    qasm = header + qasm

    qasm_unitary = None
    try:
        result = qiskit.execute(
            qiskit.QuantumCircuit.from_qasm_str(qasm),
            backend=qiskit.Aer.get_backend('unitary_simulator'),
        )
        qasm_unitary = result.result().get_unitary()
        qasm_unitary = _reorder_indices_of_matrix(
            qasm_unitary, list(reversed(range(num_qubits))))

        lin_alg_utils.assert_allclose_up_to_global_phase(qasm_unitary,
                                                         unitary,
                                                         rtol=1e-8,
                                                         atol=1e-8)
    except Exception as ex:
        if qasm_unitary is not None:
            p_unitary, p_qasm_unitary = linalg.match_global_phase(
                unitary, qasm_unitary)
        else:
            p_unitary = None
            p_qasm_unitary = None
        raise AssertionError(
            'QASM not consistent with cirq.unitary(op) up to global phase.\n\n'
            'op:\n{}\n\n'
            'cirq.unitary(op):\n{}\n\n'
            'Generated QASM:\n\n{}\n\n'
            'Unitary of generated QASM:\n{}\n\n'
            'Phased matched cirq.unitary(op):\n{}\n\n'
            'Phased matched unitary of generated QASM:\n{}\n\n'
            'Underlying error:\n{}'.format(
                _indent(repr(op)),
                _indent(repr(unitary)),
                _indent(qasm),
                _indent(repr(qasm_unitary)),
                _indent(repr(p_unitary)),
                _indent(repr(p_qasm_unitary)),
                _indent(str(ex)),
            ))