Qiskit integration¶
The optional tensorweaver.qiskit module runs
Qiskit circuits on the MPS engine. A
QuantumCircuit is converted to a mimiq circuit and evolved, so your Qiskit
code stays unchanged.
Install the extra:
Bit ordering
Qiskit's own convention applies to Qiskit objects: counts keys come back with the highest-indexed qubit on the left, the reverse of the little-endian ordering TensorWeaver uses natively. The conversion handles this, so read Qiskit results as Qiskit results.
Sampling¶
TensorWeaverBackend is a Qiskit BackendV2. Simulator options (bonddim,
seed, algorithm, and the rest of the
TwSimulator configuration) are fixed when the
backend is built; run forwards only shots and seed.
from qiskit import QuantumCircuit
from tensorweaver.qiskit import TensorWeaverBackend
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
backend = TensorWeaverBackend(bonddim=64, seed=1)
counts = backend.run(qc, shots=4000).result().get_counts()
It also works under Qiskit's V2 primitives:
from qiskit.primitives import BackendSamplerV2
sampler = BackendSamplerV2(backend=backend)
result = sampler.run([qc], shots=4000).result()[0]
counts = result.data.meas.get_counts()
Expectation values¶
TensorWeaverEstimator is an EstimatorV2. Pauli terms on one or two qubits
are read exactly from the MPS, with no shot noise. Terms on three or more
qubits are estimated by sampling in the rotated basis, with the shot count
derived from the requested precision (roughly 1/precision²); those terms
carry a non-zero standard error.
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp
from tensorweaver.qiskit import TensorWeaverEstimator
qc = QuantumCircuit(3)
qc.h(0)
qc.cx(0, 1)
qc.ry(0.7, 2)
obs = SparsePauliOp.from_list([("ZZI", 1.0), ("IIZ", 0.5), ("ZZZ", 0.25)])
estimator = TensorWeaverEstimator(bonddim=64, seed=1)
result = estimator.run([(qc, obs)], precision=0.005).result()[0]
print(result.data.evs, result.data.stds)
precision=0.0 makes the estimator fully exact, and is the default when run
is called without one. Every observable must then consist only of one- and
two-qubit Pauli terms: a longer term has no shot budget and raises
ValueError.
To reuse a configured simulator across both interfaces, pass it in rather than repeating the options:
from tensorweaver import TwSimulator
from tensorweaver.qiskit import TensorWeaverEstimator
sim = TwSimulator(bonddim=128, algorithm="vmpoa")
estimator = TensorWeaverEstimator(simulator=sim, default_precision=0.01)
Gate coverage¶
Conversion covers the standard Qiskit gate set. Custom gates and gates with
unbound parameters raise mimiq_qiskit.converter.UnsupportedGateError: bind
the parameters and decompose custom gates before running.