예제 #1
0
def test_sampler_expectation_value() -> None:
    c = Circuit(2)
    c.H(0)
    c.CX(0, 1)
    op = QubitPauliOperator({
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Z
        }):
        1.0,
        QubitPauliString({
            Qubit(0): Pauli.X,
            Qubit(1): Pauli.X
        }):
        0.3,
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Y
        }):
        0.8j,
        QubitPauliString({Qubit(0): Pauli.Y}):
        -0.4j,
    })
    b = MySampler()
    b.compile_circuit(c)
    expectation = get_operator_expectation_value(c,
                                                 op,
                                                 b,
                                                 n_shots=2000,
                                                 seed=0)
    assert (np.real(expectation), np.imag(expectation)) == pytest.approx(
        (1.3, 0.0), abs=0.1)
예제 #2
0
def test_expectation_value() -> None:
    c = Circuit(2)
    c.H(0)
    c.CX(0, 1)
    op = QubitPauliOperator({
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Z
        }):
        1.0,
        QubitPauliString({
            Qubit(0): Pauli.X,
            Qubit(1): Pauli.X
        }):
        0.3,
        QubitPauliString({
            Qubit(0): Pauli.Z,
            Qubit(1): Pauli.Y
        }):
        0.8j,
        QubitPauliString({Qubit(0): Pauli.Y}):
        -0.4j,
    })
    b = MyBackend()
    b.compile_circuit(c)
    assert get_operator_expectation_value(c, op, b) == pytest.approx(1.3)
예제 #3
0
def test_aer_placed_expectation() -> None:
    # bug TKET-695
    n_qbs = 3
    c = Circuit(n_qbs, n_qbs)
    c.X(0)
    c.CX(0, 2)
    c.CX(1, 2)
    c.H(1)
    # c.measure_all()
    b = AerBackend()
    operator = QubitPauliOperator({
        QubitPauliString(Qubit(0), Pauli.Z): 1.0,
        QubitPauliString(Qubit(1), Pauli.X): 0.5,
    })
    assert b.get_operator_expectation_value(c, operator) == (-0.5 + 0j)
    with open(os.path.join(sys.path[0], "ibmqx2_properties.pickle"),
              "rb") as f:
        properties = pickle.load(f)

    noise_model = NoiseModel.from_backend(properties)

    noise_b = AerBackend(noise_model)

    with pytest.raises(RuntimeError) as errorinfo:
        noise_b.get_operator_expectation_value(c, operator)
        assert "not supported with noise model" in str(errorinfo.value)

    c.rename_units({Qubit(1): Qubit("node", 1)})
    with pytest.raises(ValueError) as errorinfoCirc:
        b.get_operator_expectation_value(c, operator)
        assert "default register Qubits" in str(errorinfoCirc.value)
예제 #4
0
def tk_to_mycircuit(tkc: Circuit) -> MyCircuit:
    """Convert a pytket Circuit to a MyCircuit object.
    Supports Rz, Rx, Ry, and ZZMax gates.

    :param tkc: The Circuit to convert
    :type tkc: Circuit
    :return: An equivalent MyCircuit object
    :rtype: MyCircuit
    """
    circ = MyCircuit(tkc.qubits)
    for command in tkc:
        optype = command.op.type
        if optype == OpType.Rx:
            circ.add_gate(QubitPauliString(command.args[0], Pauli.X),
                          np.pi * command.op.params[0])
        elif optype == OpType.Ry:
            circ.add_gate(QubitPauliString(command.args[0], Pauli.Y),
                          np.pi * command.op.params[0])
        elif optype == OpType.Rz:
            circ.add_gate(QubitPauliString(command.args[0], Pauli.Z),
                          np.pi * command.op.params[0])
        elif optype == OpType.ZZMax:
            circ.add_gate(QubitPauliString(command.args, [Pauli.Z, Pauli.Z]),
                          np.pi * 0.5)
        else:
            raise ValueError("Cannot convert optype to MyCircuit: ", optype)
    return circ
def test_hadamard() -> None:
    c = MyCircuit([Qubit(0), Qubit(1)], [Bit(0), Bit(1)])
    c.add_gate(QubitPauliString(Qubit(0), Pauli.Z), np.pi / 2)
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_gate(QubitPauliString(Qubit(0), Pauli.Z), np.pi / 2)
    c.add_measure(Qubit(0), Bit(0))
    counts = get_counts(c, n_shots=100, seed=11)
    assert counts == {(0, 0): 50, (0, 1): 50}
예제 #6
0
def test_operator_statevector(qvm: None, quilc: None) -> None:
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    b = ForestStateBackend()
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    iz = QubitPauliString(Qubit(1), Pauli.Z)
    op = QubitPauliOperator({zi: 0.3, iz: -0.1})
    assert get_operator_expectation_value(c, op, b) == pytest.approx(0.2)
    c.X(0)
    assert get_operator_expectation_value(c, op, b) == pytest.approx(-0.4)
def test_basic_ordering() -> None:
    # Test that final bit readouts are in the intended order (DLO)
    c = MyCircuit([Qubit(0)], [Bit(0), Bit(1), Bit(2)])
    c.add_measure(Qubit(0), Bit(0))
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi)
    c.add_measure(Qubit(0), Bit(2))
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_measure(Qubit(0), Bit(1))
    counts = get_counts(c, n_shots=100, seed=11)
    assert counts == {(1, 0, 0): 50, (1, 1, 0): 50}
def test_overwrite() -> None:
    # Test that classical data is overwritten by later measurements appropriately
    c = MyCircuit([Qubit(0)], [Bit(0), Bit(1)])
    c.add_measure(Qubit(0), Bit(0))
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi)
    c.add_measure(Qubit(0), Bit(0))
    c.add_measure(Qubit(0), Bit(1))
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_measure(Qubit(0), Bit(1))
    counts = get_counts(c, n_shots=100, seed=11)
    assert counts == {(0, 1): 50, (1, 1): 50}
예제 #9
0
def test_operator_sim(qvm: None, quilc: None) -> None:
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    b = ForestBackend("9q-square")
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    iz = QubitPauliString(Qubit(1), Pauli.Z)
    op = QubitPauliOperator({zi: 0.3, iz: -0.1})
    assert get_operator_expectation_value(c, op, b,
                                          10) == pytest.approx(0.2, rel=0.001)
    c.X(0)
    assert get_operator_expectation_value(c, op, b,
                                          10) == pytest.approx(-0.4, rel=0.001)
def test_conditional_rotation() -> None:
    c = MyCircuit([Qubit(0)], [Bit(0), Bit(1)])
    # Randomise qubit state
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_measure(Qubit(0), Bit(0))
    # Correct qubit state to |1> - this should only happen when the measurement was 0
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi, {Bit(0): 0, Bit(1): 0})
    # Randomise final measurement - this should never happen
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2, {Bit(0): 0, Bit(1): 1})
    c.add_measure(Qubit(0), Bit(1))
    counts = get_counts(c, n_shots=100, seed=11)
    assert counts == {(1, 0): 50, (1, 1): 50}
예제 #11
0
def test_expectation() -> None:
    b = BraketBackend(local=True)
    assert b.supports_expectation
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    iz = QubitPauliString(Qubit(1), Pauli.Z)
    op = QubitPauliOperator({zi: 0.3, iz: -0.1})
    assert get_pauli_expectation_value(c, zi, b) == 1
    assert get_operator_expectation_value(c, op, b) == pytest.approx(0.2)
    c.X(0)
    assert get_pauli_expectation_value(c, zi, b) == -1
    assert get_operator_expectation_value(c, op, b) == pytest.approx(-0.4)
예제 #12
0
def test_simulator() -> None:
    b = BraketBackend(
        s3_bucket=S3_BUCKET,
        s3_folder=S3_FOLDER,
        device_type="quantum-simulator",
        provider="amazon",
        device="sv1",
    )
    assert b.supports_shots
    c = Circuit(2).H(0).CX(0, 1)
    b.compile_circuit(c)
    n_shots = 100
    h0, h1 = b.process_circuits([c, c], n_shots)
    res0 = b.get_result(h0)
    readouts = res0.get_shots()
    assert all(readouts[i][0] == readouts[i][1] for i in range(n_shots))
    res1 = b.get_result(h1)
    counts = res1.get_counts()
    assert len(counts) <= 2
    assert sum(counts.values()) == n_shots
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    assert b.get_pauli_expectation_value(
        c, zi, poll_timeout_seconds=60, poll_interval_seconds=1
    ) == pytest.approx(0)

    # Circuit with unused qubits
    c = Circuit(3).H(1).CX(1, 2)
    b.compile_circuit(c)
    h = b.process_circuit(c, 1)
    res = b.get_result(h)
    readout = res.get_shots()[0]
    assert readout[1] == readout[2]
    def get_pauli_expectation_value(
        self,
        state_circuit: Circuit,
        pauli: QubitPauliString,
        valid_check: bool = True,
    ) -> complex:
        """Calculates the expectation value of the given circuit using the built-in
        ProjectQ functionality

        :param state_circuit: Circuit that generates the desired state
            :math:`\\left|\\psi\\right>`.
        :type state_circuit: Circuit
        :param pauli: Pauli operator
        :type pauli: QubitPauliString
        :param valid_check: Explicitly check that the circuit satisfies all required
            predicates to run on the backend. Defaults to True
        :type valid_check: bool, optional
        :return: :math:`\\left<\\psi | P | \\psi \\right>`
        :rtype: complex
        """
        pauli_tuple = tuple(
            (_default_q_index(q), p.name) for q, p in pauli.to_dict().items())
        return self._expectation_value(state_circuit,
                                       projectq.ops.QubitOperator(pauli_tuple),
                                       valid_check)
예제 #14
0
 def _gen_PauliTerm(self,
                    term: QubitPauliString,
                    coeff: complex = 1.0) -> PauliTerm:
     pauli_term = ID() * coeff
     for q, p in term.to_dict().items():
         pauli_term *= PauliTerm(p.name, _default_q_index(q))
     return pauli_term  # type: ignore
def test_operator() -> None:
    c = circuit_gen()
    b = ProjectQBackend()
    zz = QubitPauliOperator(
        {QubitPauliString([Qubit(0), Qubit(1)], [Pauli.Z, Pauli.Z]): 1.0})
    assert np.isclose(get_operator_expectation_value(c, zz, b), complex(1.0))
    c.X(0)
    assert np.isclose(get_operator_expectation_value(c, zz, b), complex(-1.0))
def qps_from_openfermion(paulis: QubitOperator) -> QubitPauliString:
    """ Utility function to translate from openfermion format to a QubitPauliString """
    qlist = []
    plist = []
    for q, p in paulis:
        qlist.append(Qubit(q))
        plist.append(pauli_sym[p])
    return QubitPauliString(qlist, plist)
def test_pauli() -> None:
    c = Circuit(2)
    c.Rz(0.5, 0)
    b = ProjectQBackend()
    zi = QubitPauliString({Qubit(0): Pauli.Z})
    assert np.isclose(get_pauli_expectation_value(c, zi, b), complex(1))
    c.X(0)
    assert np.isclose(get_pauli_expectation_value(c, zi, b), complex(-1))
예제 #18
0
def test_pauli_statevector(qvm: None, quilc: None) -> None:
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    b = ForestStateBackend()
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    assert get_pauli_expectation_value(c, zi, b) == 1
    c.X(0)
    assert get_pauli_expectation_value(c, zi, b) == -1
예제 #19
0
def qps_from_openfermion(paulis):
    # translate from openfermion format to a QubitPauliString
    qlist = []
    plist = []
    for q, p in paulis:
        qlist.append(Qubit(q))
        plist.append(pauli_sym[p])
    return QubitPauliString(qlist, plist)
예제 #20
0
def test_operator() -> None:
    for b in [AerBackend(), AerStateBackend()]:
        c = circuit_gen()
        zz = QubitPauliOperator(
            {QubitPauliString([Qubit(0), Qubit(1)], [Pauli.Z, Pauli.Z]): 1.0})
        assert cmath.isclose(get_operator_expectation_value(c, zz, b), 1.0)
        c.X(0)
        assert cmath.isclose(get_operator_expectation_value(c, zz, b), -1.0)
예제 #21
0
def test_device() -> None:
    c = circuit_gen(False)
    b = IBMQBackend("ibmq_santiago", hub="ibm-q", group="open", project="main")
    assert b._max_per_job == 75
    operator = QubitPauliOperator({
        QubitPauliString(Qubit(0), Pauli.Z): 1.0,
        QubitPauliString(Qubit(0), Pauli.X): 0.5,
    })
    val = get_operator_expectation_value(c, operator, b, 8000)
    print(val)
    c1 = circuit_gen(True)
    c2 = circuit_gen(True)
    b.compile_circuit(c1)
    b.compile_circuit(c2)

    print(b.get_shots(c1, n_shots=10))
    print(b.get_shots(c2, n_shots=10))
예제 #22
0
def test_pauli() -> None:
    for b in [AerBackend(), AerStateBackend()]:
        c = Circuit(2)
        c.Rz(0.5, 0)
        b.compile_circuit(c)
        zi = QubitPauliString(Qubit(0), Pauli.Z)
        assert cmath.isclose(get_pauli_expectation_value(c, zi, b), 1)
        c.X(0)
        assert cmath.isclose(get_pauli_expectation_value(c, zi, b), -1)
예제 #23
0
def test_pauli_statevector() -> None:
    c = Circuit(2)
    c.Rz(0.5, 0)
    Transform.OptimisePostRouting().apply(c)
    b = AerStateBackend()
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    assert get_pauli_expectation_value(c, zi, b) == 1
    c.X(0)
    assert get_pauli_expectation_value(c, zi, b) == -1
예제 #24
0
def _sparse_to_qiskit_pauli(pauli: QubitPauliString,
                            n_qubits: int) -> qk_Pauli:
    x = [False] * n_qubits
    z = [False] * n_qubits
    for q, p in pauli.to_dict().items():
        i = _default_q_index(q)
        z[i] = p in (Pauli.Z, Pauli.Y)
        x[i] = p in (Pauli.X, Pauli.Y)
    return qk_Pauli((z, x))
예제 #25
0
def add_operator_term(circuit: Circuit, term: QubitPauliString, angle: float):
    qubits = []
    for q, p in term.to_dict().items():
        if p != Pauli.I:
            qubits.append(q)
            if p == Pauli.X:
                circuit.H(q)
            elif p == Pauli.Y:
                circuit.V(q)
    for i in range(len(qubits) - 1):
        circuit.CX(i, i + 1)
    circuit.Rz(angle, len(qubits) - 1)
    for i in reversed(range(len(qubits) - 1)):
        circuit.CX(i, i + 1)
    for q, p in term.to_dict().items():
        if p == Pauli.X:
            circuit.H(q)
        elif p == Pauli.Y:
            circuit.Vdg(q)
예제 #26
0
def test_pauli_sim(qvm: None, quilc: None) -> None:
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    b = ForestBackend("9q-square")
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    energy = get_pauli_expectation_value(c, zi, b, 10)
    assert abs(energy - 1) < 0.001
    c.X(0)
    energy = get_pauli_expectation_value(c, zi, b, 10)
    assert abs(energy + 1) < 0.001
예제 #27
0
def _sparse_to_qiskit_pauli(pauli: QubitPauliString,
                            n_qubits: int) -> qk_Pauli:
    empty = np.zeros(n_qubits)
    q_pauli = qk_Pauli(empty, empty)
    for q, p in pauli.to_dict().items():
        i = _default_q_index(q)
        if p in (Pauli.X, Pauli.Y):
            q_pauli._x[i] = True
        if p in (Pauli.Z, Pauli.Y):
            q_pauli._z[i] = True
    return q_pauli
예제 #28
0
def test_pauli_sim() -> None:
    c = Circuit(2, 2)
    c.Rz(0.5, 0)
    Transform.OptimisePostRouting().apply(c)
    b = AerBackend()
    zi = QubitPauliString(Qubit(0), Pauli.Z)
    energy = get_pauli_expectation_value(c, zi, b, 8000)
    assert abs(energy - 1) < 0.001
    c.X(0)
    energy = get_pauli_expectation_value(c, zi, b, 8000)
    assert abs(energy + 1) < 0.001
def test_conditional_measurement() -> None:
    c = MyCircuit([Qubit(0), Qubit(1)], [Bit(0), Bit(1), Bit(2), Bit(3)])
    # Get a random number
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_measure(Qubit(0), Bit(0))
    # If random number is 0 then flip to give |1>
    # Otherwise, randomly generate |+i> or |-i>
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    c.add_measure(Qubit(0), Bit(1), {Bit(0): 1})
    c.add_gate(QubitPauliString(Qubit(0), Pauli.X), np.pi / 2)
    # Deterministic if Bit(0) == 0, random if Bit(0) == 1
    c.add_measure(Qubit(0), Bit(2))
    # Test end-of-circuit conditions by copying Bit(2) to Bit(3)
    c.add_gate(QubitPauliString(Qubit(1), Pauli.X), np.pi)
    c.add_measure(Qubit(1), Bit(3), {Bit(2): 1})
    counts = get_counts(c, n_shots=10000, seed=11)
    assert counts[(1, 1, 0, 0)] == pytest.approx(5000, rel=0.02)
    assert counts[(0, 0, 0, 1)] == pytest.approx(1250, rel=0.02)
    assert counts[(1, 1, 0, 1)] == pytest.approx(1250, rel=0.02)
    assert counts[(0, 0, 1, 1)] == pytest.approx(1250, rel=0.02)
    assert counts[(1, 1, 1, 1)] == pytest.approx(1250, rel=0.02)
예제 #30
0
    def apply_Pauli_rot(self, qps: QubitPauliString, angle: float):
        """Applies e^{-0.5i * qps * angle} to the state

        :param qps: Pauli to rotate around
        :type qps: QubitPauliString
        :param angle: Angle of rotation in radians
        :type angle: float
        """
        pauli_tensor = qps.to_sparse_matrix(self._qubits)
        exponent = -0.5 * angle
        self._qstate = np.cos(exponent) * self._qstate + 1j * np.sin(
            exponent) * pauli_tensor.dot(self._qstate)