Ejemplo n.º 1
0
def test_lifted_state_operator_backwards_qubits():
    xz_state = plusX(5) * minusZ(6)
    plus = np.array([1, 1]) / np.sqrt(2)
    plus = plus[:, np.newaxis]
    proj_plus = plus @ plus.conj().T
    assert proj_plus.shape == (2, 2)

    one = np.array([0, 1])
    one = one[:, np.newaxis]
    proj_one = one @ one.conj().T
    assert proj_one.shape == (2, 2)

    np.testing.assert_allclose(np.kron(proj_plus, proj_one),
                               lifted_state_operator(xz_state, qubits=[6, 5]))
Ejemplo n.º 2
0
def _extract_from_results(results: List[ExperimentResult], qubits: List[int]):
    """
    Construct the matrix A such that the probabilities p_ij of outcomes n_ij given an estimate E
    can be cast in a vectorized form.

    Specifically::

        p = vec(p_ij) = A x vec(E)

    This yields convenient vectorized calculations of the cost and its gradient, in terms of A, n,
    and E.
    """
    A = []
    n = []
    grand_total_shots = 0

    for result in results:
        in_state_matrix = lifted_state_operator(result.setting.in_state,
                                                qubits=qubits)
        operator = lifted_pauli(result.setting.out_operator, qubits=qubits)
        proj_plus = (np.eye(2**len(qubits)) + operator) / 2
        proj_minus = (np.eye(2**len(qubits)) - operator) / 2

        # Constructing A per eq. (22)
        # TODO: figure out if we can avoid re-splitting into Pi+ and Pi- counts
        A += [
            # vec() turns into a column vector; transpose to a row vector; index into the
            # 1 row to avoid an extra tensor dimension when we call np.asarray(A).
            vec(np.kron(in_state_matrix, proj_plus.T)).T[0],
            vec(np.kron(in_state_matrix, proj_minus.T)).T[0],
        ]

        expected_plus_ones = (1 + result.expectation) / 2
        n += [
            result.total_counts * expected_plus_ones,
            result.total_counts * (1 - expected_plus_ones)
        ]
        grand_total_shots += result.total_counts

    n_qubits = len(qubits)
    dimension = 2**n_qubits
    A = np.asarray(A) / dimension**2
    n = np.asarray(n)[:, np.newaxis] / grand_total_shots
    return A, n