Example: Expectation values with FiQCIEstimator#

For configuration options, mitigation levels, and result methods, see the FiQCIEstimator guide.

Import everything needed#

from fiqci.ems import FiQCIEstimator
from iqm.qiskit_iqm import IQMProvider, transpile_to_IQM
from qiskit import QuantumCircuit
from qiskit.quantum_info import SparsePauliOp

Initialise FiQCIEstimator#

url = None
quantum_computer = None

# Connect to an IQM quantum computer using the provider
if url is not None and quantum_computer is not None:
	provider = IQMProvider(url=url, quantum_computer=quantum_computer)
	backend = provider.get_backend()
else:
	# Or using a noisy simulator
	from iqm.qiskit_iqm import IQMFakeAdonis

	backend = IQMFakeAdonis()

# Initialise FiQCI estimator with mitigation level 1 (readout error mitigation)
estimator = FiQCIEstimator(backend=backend, mitigation_level=1)

# We can view the default settings enabled for mitigation level 1
estimator.mitigator_options
{'zne': {'enabled': False,
  'fold_gates': None,
  'scale_factors': [1, 3, 5],
  'folding_method': 'local',
  'extrapolation_method': 'exponential',
  'extrapolation_degree': None,
  'seed': None},
 'rem': {'enabled': True,
  'calibration_shots': 1000,
  'calibration_file': None,
  'mitigator': <fiqci.ems.mitigators.rem.M3IQM at 0x7fc5d112e840>},
 'dd': {'enabled': False, 'gate_sequences': []},
 'pauli_twirl': {'enabled': False,
  'num_twirls': 0,
  'gates_to_twirl': None,
  'seed': None}}

Bell State expectation values with REM#

# Create a Bell state circuit
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)

# Transpile for backend
tr_qc = transpile_to_IQM(qc, backend, remove_final_rzs=False, optimization_level=3)

tr_qc.draw("mpl")
../_images/e1f891031247d0ab7550cb4f1e8626008b2e106f50defdc143435396bf2a3245.png
# Define observables to calculate expectation values for
observables = SparsePauliOp.from_list([("ZZ", 1), ("IX", 1)])

# Map observables to the layout of the transpiled circuit
observables_device = observables.apply_layout(tr_qc.layout)

# Execute on FiQCI Estimator with specified observables and shots
job = estimator.run([tr_qc], observables=observables_device, shots=2**10)

# Retrieve mitigated expectation values
job.expectation_values()
[[0.9647749510763209, 0.03616813294232649]]

Access job metadata#

# Get the underlying backend job
backend_job = job.job()

# Access raw counts for the first circuit in the job
raw_counts = backend_job.result().results[0].header["fiqci_ems"]["raw_counts"]

print(raw_counts)
{'11': 459, '10': 46, '00': 470, '01': 49}

Manually configure mitigation options#

# Initialise FiQCI sampler
estimator = FiQCIEstimator(backend=backend, mitigation_level=0)

# Config rem
estimator.rem(enabled=True, calibration_shots=2**10)

# Print current mitigator options
estimator.mitigator_options
{'zne': {'enabled': False,
  'fold_gates': None,
  'scale_factors': [1, 3, 5],
  'folding_method': 'local',
  'extrapolation_method': 'exponential',
  'extrapolation_degree': None,
  'seed': None},
 'rem': {'enabled': True,
  'calibration_shots': 1024,
  'calibration_file': None,
  'mitigator': <fiqci.ems.mitigators.rem.M3IQM at 0x7fc5d3213770>},
 'dd': {'enabled': False, 'gate_sequences': []},
 'pauli_twirl': {'enabled': False,
  'num_twirls': 0,
  'gates_to_twirl': None,
  'seed': None}}

Access Job Information and Metadata#

# All measurement-basis subcircuits the estimator runs are flattened into a single backend job. Access it via job.job().
backend_job = job.job()

# Get the counts for every circuit in the job
print(backend_job.result().get_counts())

# Get raw counts for the first circuit in the job
print(backend_job.result().results[0].header)

raw_counts = backend_job.result().results[0].header["fiqci_ems"]["raw_counts"]

print(raw_counts)
[{'10': 5, '01': 13, '11': 496, '00': 508}, {'1': 493, '0': 530}]
{'creg_sizes': [['meas', 2]], 'global_phase': 0.0, 'memory_slots': 2, 'n_qubits': 5, 'name': 'circuit-13855', 'qreg_sizes': [['ancilla', 3], ['q', 2]], 'metadata': {}, 'fiqci_ems': {'mitigation_level': 1, 'mitigation_method': 'M3', 'calibration_shots': 1000, 'raw_counts': {'11': 459, '10': 46, '00': 470, '01': 49}}}
{'11': 459, '10': 46, '00': 470, '01': 49}