Basic Example

This notebook demonstrates the basic usage of qTPU for quantum circuit processing.

[1]:
import numpy as np
from qiskit.circuit.library import TwoLocal


def simple_circuit(n: int):
    circuit = TwoLocal(n, ["u"], "rzz", entanglement="linear", reps=2).decompose()
    circuit = circuit.assign_parameters(
        {param: np.random.rand() * np.pi / 2 for param in circuit.parameters}
    )
    circuit.measure_all()
    return circuit

circuit = simple_circuit(6)

circuit.draw(output="mpl", fold=-1)
/tmp/ipykernel_3436/719864217.py:6: DeprecationWarning: The class ``qiskit.circuit.library.n_local.two_local.TwoLocal`` is deprecated as of Qiskit 2.1. It will be removed in Qiskit 3.0. Use the function qiskit.circuit.library.n_local instead.
  circuit = TwoLocal(n, ["u"], "rzz", entanglement="linear", reps=2).decompose()
[1]:
../_images/notebooks_basic_example_1_1.svg
[2]:
import qtpu

# cut the circuit into two halves
cut_circ = qtpu.cut(circuit, num_qubits=circuit.num_qubits // 2)

cut_circ.draw(output="mpl", fold=-1)
[2]:
../_images/notebooks_basic_example_2_0.svg
[3]:
# convert the circuit into a hybrid tensor network
hybrid_tn = qtpu.circuit_to_hybrid_tn(cut_circ)

for i, subcirc in enumerate(hybrid_tn.subcircuits):
    print(f"Subcircuit {i}:")
    print(subcirc)
    print("--------------------")
Subcircuit 0:
        ┌─────────────────────────┐               ┌──────────────────────────┐»
 q_0: ──┤ U(1.2287,1.385,0.04084) ├───■───────────┤ U(0.60597,1.2127,1.2916) ├»
       ┌┴─────────────────────────┴─┐ │ZZ(1.4867) └──────────────────────────┘»
 q_1: ─┤ U(1.4814,0.94981,0.056746) ├─■───────────────────■───────────────────»
      ┌┴────────────────────────────┤                     │ZZ(0.34031)        »
 q_2: ┤ U(0.88569,0.070235,0.63864) ├─────────────────────■───────────────────»
      └─────────────────────────────┘                                         »
c0: 1/════════════════════════════════════════════════════════════════════════»
                                                                              »
c1: 1/════════════════════════════════════════════════════════════════════════»
                                                                              »
c2: 1/════════════════════════════════════════════════════════════════════════»
                                                                              »
«                                                                  »
« q_0: ──────────────────────────────────────■─────────────────────»
«      ┌───────────────────────────┐         │ZZ(0.084044)         »
« q_1: ┤ U(1.0322,0.71946,0.26776) ├─────────■─────────────────────»
«      └────────┬──────────┬───────┘┌─────────────────────────────┐»
« q_2: ─────────┤ Vec(i_0) ├────────┤ U(0.041932,0.16983,0.97966) ├»
«               └──────────┘        └─────────────────────────────┘»
«c0: 1/════════════════════════════════════════════════════════════»
«                                                                  »
«c1: 1/════════════════════════════════════════════════════════════»
«                                                                  »
«c2: 1/════════════════════════════════════════════════════════════»
«                                                                  »
«      ┌────────────────────────┐                            ┌─┐»
« q_0: ┤ U(1.11,1.2229,0.86582) ├────────────────────────────┤M├»
«      └────────────────────────┘┌──────────────────────────┐└╥┘»
« q_1: ───────■──────────────────┤ U(0.41513,1.2743,1.0967) ├─╫─»
«             │ZZ(0.85665)       └───────┬──────────┬───────┘ ║ »
« q_2: ───────■──────────────────────────┤ Vec(i_1) ├─────────╫─»
«                                        └──────────┘         ║ »
«c0: 1/═══════════════════════════════════════════════════════╩═»
«                                                             0 »
«c1: 1/═════════════════════════════════════════════════════════»
«                                                               »
«c2: 1/═════════════════════════════════════════════════════════»
«                                                               »
«
« q_0: ──────────────────────────────────
«                                  ┌─┐
« q_1: ────────────────────────────┤M├───
«      ┌──────────────────────────┐└╥┘┌─┐
« q_2: ┤ U(0.33563,1.1255,1.3834) ├─╫─┤M├
«      └──────────────────────────┘ ║ └╥┘
«c0: 1/═════════════════════════════╬══╬═
«                                   ║  ║
«c1: 1/═════════════════════════════╩══╬═
«                                   0  ║
«c2: 1/════════════════════════════════╩═
«                                      0
--------------------
Subcircuit 1:
      ┌───────────────────────────┐ ┌──────────┐             »
 q_0: ┤ U(1.4973,0.24524,0.90054) ├─┤ Vec(i_0) ├─■───────────»
      ├───────────────────────────┤ └──────────┘ │ZZ(1.0936) »
 q_1: ┤ U(0.60545,0.86304,1.2455) ├──────────────■───────────»
      ├───────────────────────────┴┐                         »
 q_2: ┤ U(0.29003,0.28238,0.52261) ├─────────────────────────»
      └────────────────────────────┘                         »
c3: 1/═══════════════════════════════════════════════════════»
                                                             »
c4: 1/═══════════════════════════════════════════════════════»
                                                             »
c5: 1/═══════════════════════════════════════════════════════»
                                                             »
«      ┌───────────────────────────┐         ┌──────────┐                      »
« q_0: ┤ U(1.0966,0.88711,0.37093) ├─────────┤ Vec(i_1) ├─────────■────────────»
«      └───────────────────────────┘┌────────┴──────────┴───────┐ │ZZ(0.68047) »
« q_1: ─────────■───────────────────┤ U(1.3449,0.53094,0.13781) ├─■────────────»
«               │ZZ(0.45398)        └┬──────────────────────────┤              »
« q_2: ─────────■────────────────────┤ U(0.36136,0.52691,1.211) ├──────────────»
«                                    └──────────────────────────┘              »
«c3: 1/════════════════════════════════════════════════════════════════════════»
«                                                                              »
«c4: 1/════════════════════════════════════════════════════════════════════════»
«                                                                              »
«c5: 1/════════════════════════════════════════════════════════════════════════»
«                                                                              »
«      ┌────────────────────────┐                             ┌─┐
« q_0: ┤ U(1.3996,1.0289,1.544) ├─────────────────────────────┤M├──────
«      └────────────────────────┘ ┌─────────────────────────┐ └╥┘┌─┐
« q_1: ───────■───────────────────┤ U(0.753,1.3078,0.86319) ├──╫─┤M├───
«             │ZZ(0.55997)       ┌┴─────────────────────────┴┐ ║ └╥┘┌─┐
« q_2: ───────■──────────────────┤ U(0.91239,0.85419,0.1439) ├─╫──╫─┤M├
«                                └───────────────────────────┘ ║  ║ └╥┘
«c3: 1/════════════════════════════════════════════════════════╩══╬══╬═
«                                                              0  ║  ║
«c4: 1/═══════════════════════════════════════════════════════════╩══╬═
«                                                                 0  ║
«c5: 1/══════════════════════════════════════════════════════════════╩═
«                                                                    0
--------------------
[4]:
# evaluate the hybrid tensor network to a classical tensor network
tn = qtpu.evaluate(hybrid_tn)

# contract the classical tensor network
qtpu_res = tn.contract(all, optimize="auto-hq", output_inds=[])
[5]:
from qiskit.circuit import QuantumCircuit
from qiskit_aer.primitives import EstimatorV2


def run_comparison(circuit: QuantumCircuit):
    circuit = circuit.remove_final_measurements(inplace=False)
    return (
        EstimatorV2()
        .run([(circuit, "Z" * circuit.num_qubits)], precision=0.0000)
        .result()[0]
        .data.evs
    )

qiskit_res = run_comparison(circuit)
[6]:
print(f"QTPU result: {qtpu_res}")
print(f"Qiskit result: {qiskit_res}")
print(f"Error: {round(abs(qtpu_res - qiskit_res), 5)}")
QTPU result: 0.012268686234791753
Qiskit result: 0.012268686234791597
Error: 0.0