Execution Outcomes#

Qibo circuits return different objects when executed depending on what the circuit contains and on the settings of the simulation. The following table summarizes which outcomes to expect depending on whether:

  • the circuit contains noise channels

  • the qubits are measured at the end of the execution

  • some collapse measurement is present in the circuit

  • density_matrix is set to True in simulation

Noise

Measurements

Collapse

Density Matrix

Outcome

❌

❌

❌

❌ / ✅

qibo.result.QuantumState

❌

✅

❌

❌ / ✅

qibo.result.CircuitResult

❌ / ✅

❌

❌ / ✅

✅

qibo.result.QuantumState

❌ / ✅

✅

❌ / ✅

❌

qibo.result.MeasurementOutcomes

❌ / ✅

✅

❌ / ✅

✅

qibo.result.CircuitResult

Therefore, one of the three objects qibo.result.QuantumState, qibo.result.MeasurementOutcomes or qibo.result.CircuitResult is going to be returned by the circuit execution. The first gives acces to the final state and probabilities via the qibo.result.QuantumState.state() and qibo.result.QuantumState.probabilities() methods, whereas the second allows to retrieve the final samples, the frequencies and the probabilities (calculated as frequencies/nshots) with the qibo.result.MeasurementOutcomes.samples(), qibo.result.MeasurementOutcomes.frequencies() and qibo.result.MeasurementOutcomes.probabilities() methods respectively. The qibo.result.CircuitResult object includes all the above instead.

Every time some measurement is performed at the end of the execution, the result will be a CircuitResult unless the final state could not be represented with the current simulation settings, i.e. if some stochasticity is present in the ciruit (via noise channels or collapse measurements) and density_matrix=False. In that case a simple MeasurementOutcomes object is returned.

If no measurement is appended at the end of the circuit, the final QuantumState is going to be provided as output. However, if the circuit is stochastic, density_matrix should be set to True in order to recover the final state, otherwise an error is raised.

The final result of the circuit execution can also be saved to disk and loaded back:

circuit = Circuit(2)
circuit.add(gates.M(0,1))
# this will be a CircuitResult object
result = circuit()
# save it to final_result.npy
result.dump('final_result.npy')
# can be loaded back
from qibo.result import load_result

loaded_result = load_result('final_result.npy')
class qibo.result.QuantumState(state, backend=None)[source]#

Data structure to represent the final state after circuit execution.

Parameters:
  • state (ndarray) – Input quantum state as ndarray.

  • backend (qibo.backends.abstract.Backend) – Backend used for the calculations. If not provided, the global backend is going to be used.

symbolic(decimals=5, cutoff=1e-10, max_terms=20)[source]#

Dirac notation representation of the state in the computational basis.

Parameters:
  • decimals (int, optional) – Number of decimals for the amplitudes. Defaults to \(5\).

  • cutoff (float, optional) – Amplitudes with absolute value smaller than the cutoff are ignored from the representation. Defaults to 1e-10.

  • max_terms (int, optional) – Maximum number of terms to print. If the state contains more terms they will be ignored. Defaults to \(20\).

Returns:

String representing the state in the computational basis.

Return type:

str

state(numpy=False)[source]#

State’s tensor representation as a backend tensor.

Note

If the state has Hamming weight \(k\) and is computed using the HammingWeightBackend, its dimension is \(d = \binom{n}{k}\), where \(n\) is the number of qubits.

Parameters:

numpy (bool, optional) – If True the returned tensor will be a numpy array, otherwise it will follow the backend tensor type. Defaults to False.

Returns:

The state in the computational basis.

probabilities(qubits=None)[source]#

Calculates measurement probabilities by tracing out qubits.

When noisy model is applied to a circuit and circuit.density_matrix=False, this method returns the average probability resulting from repeated execution. This probability distribution approximates the exact probability distribution obtained when circuit.density_matrix=True.

Parameters:

qubits (list or set, optional) – Set of qubits that are measured. If None, qubits equates the total number of qubits. Defauts to None.

Returns:

Probabilities over the input qubits.

Return type:

(np.ndarray)

to_dict()[source]#

Returns a dictonary containinig all the information needed to rebuild the QuantumState

dump(filename)[source]#

Writes to file the QuantumState for future reloading.

Parameters:

filename (str) – Path to the file to write to.

classmethod from_dict(payload)[source]#

Builds a QuantumState object starting from a dictionary.

Parameters:

payload (dict) – Dictionary containing all the information to load the QuantumState object.

Returns:

Quantum state object..

Return type:

qibo.result.QuantumState

classmethod load(filename)[source]#

Builds the QuantumState object stored in a file.

Parameters:

filename (str) – Path to the file containing the QuantumState.

Returns:

Quantum state object.

Return type:

qibo.result.QuantumState

class qibo.result.MeasurementOutcomes(measurements, backend=None, probabilities=None, samples=None, nshots=1000, nqubits=None)[source]#

Object to store the outcomes of measurements after circuit execution.

Parameters:
  • measurements (qibo.gates.M) – Measurement gates.

  • backend (qibo.backends.abstract.Backend) – Backend used for the calculations. If None, then the current backend is used. Defaults to None.

  • probabilities (np.ndarray) – Use these probabilities to generate samples and frequencies.

  • samples (np.darray) – Use these samples to generate probabilities and frequencies.

  • nshots (int) – Number of shots used for samples, probabilities and frequencies generation.

  • nqubits (int, optional) – Total number of qubits in the circuit. When set, probabilities() with qubits=None returns probabilities over all circuit qubits (not just the measured ones). If None, defaults to the number of measured qubits. Defaults to None.

frequencies(binary=True, registers=False)[source]#

Returns the frequencies of measured samples.

Parameters:
  • binary (bool, optional) – If True, returns frequency keys in binary form. If False, returns them in decimal form. Defaults to True.

  • registers (bool, optional) – Group frequencies according to registers. Defaults to False.

Returns:

A collections.Counter where the keys are the observed values and the values the corresponding frequencies, that is the number of times each measured value/bitstring appears.

If binary is True

the keys of the collections.Counter are in binary form, as strings of \(0\) and :math`1`.

If binary is False

the keys of the collections.Counter are integers.

If registers is True

a dict of collections.Counter is returned where keys are the name of each register.

If registers is False

a single collections.Counter is returned which contains samples from all the measured qubits, independently of their registers.

probabilities(qubits=None)[source]#

Calculate the probabilities as frequencies / nshots

Parameters:

qubits (list or set, optional) – Set of qubits for which to compute probabilities. If None and nqubits was provided at construction, probabilities are returned over all circuit qubits; otherwise only over the measured qubits. Defaults to None.

Returns:

The array containing the probabilities of the requested qubits.

Return type:

ArrayLike

has_samples()[source]#

Check whether the samples are available already.

Returns:

True if the samples are available, False otherwise.

Return type:

(bool)

samples(binary=True, registers=False)[source]#

Returns raw measurement samples.

Parameters:
  • binary (bool, optional) – Return samples in binary or decimal form.

  • registers (bool, optional) – Group samples according to registers.

Returns:

If binary is True

samples are returned in binary form as a tensor of shape (nshots, n_measured_qubits).

If binary is False

samples are returned in decimal form as a tensor of shape (nshots,).

If registers is True

samples are returned in a dict where the keys are the register names and the values are the samples tensors for each register.

If registers is False

a single tensor is returned which contains samples from all the measured qubits, independently of their registers.

property measurement_gate#

Single measurement gate containing all measured qubits.

Useful for sampling all measured qubits at once when simulating.

apply_bitflips(p0, p1=None)[source]#

Apply bitflips to the measurements with probabilities p0 and p1

Parameters:
  • p0 (float) – Probability of the 0->1 flip.

  • p1 (float) – Probability of the 1->0 flip.

expectation_from_samples(observable)[source]#

Computes the real expectation value of a diagonal observable from frequencies.

Parameters:

observable (Hamiltonian/SymbolicHamiltonian) – diagonal observable in the computational basis.

Returns:

expectation value from samples.

Return type:

(float)

to_dict()[source]#

Returns a dictonary containinig all the information needed to rebuild the qibo.result.MeasurementOutcomes.

dump(filename)[source]#

Writes to file the qibo.result.MeasurementOutcomes for future reloading.

Parameters:

filename (str) – Path to the file to write to.

classmethod from_dict(payload)[source]#

Builds a qibo.result.MeasurementOutcomes object starting from a dictionary.

Parameters:

payload (dict) – Dictionary containing all the information to load the qibo.result.MeasurementOutcomes object.

Returns:

Object storing the measurement outcomes.

Return type:

qibo.result.MeasurementOutcomes

classmethod load(filename)[source]#

Builds the qibo.result.MeasurementOutcomes object stored in a file.

Parameters:

filename (str) – Path to the file containing the qibo.result.MeasurementOutcomes.

Returns:

instance of the MeasurementOutcomes class.

Return type:

qibo.result.MeasurementOutcomes

classmethod from_samples(samples, qubits=None, backend=None)[source]#

Constructs a qibo.result.MeasurementOutcomes directly from a binary samples array.

This is useful when building measurement outcomes from experimental data without needing to manually construct measurement gates.

Parameters:
  • samples (ArrayLike) – Binary array of shape (nshots, nqubits). where each row is a measurement outcome with 0/1 values.

  • qubits (tuple or list, optional) – Qubit indices for the measured qubits. If None, defaults to (0, 1, ..., nqubits - 1). Defaults to None.

  • backend (qibo.backends.abstract.Backend, optional) – Backend used for calculations. If None, the current default backend is used. Defaults to None.

Returns:

Object storing the measurement outcomes.

Return type:

qibo.result.MeasurementOutcomes

Example

import numpy as np
from qibo.result import MeasurementOutcomes

samples = np.array([[0, 1], [1, 0], [1, 1]])
result = MeasurementOutcomes.from_samples(samples)
print(result.frequencies())  # Counter({'01': 1, '10': 1, '11': 1})
classmethod from_frequencies(frequencies, nqubits=None, qubits=None, seed=None, backend=None)[source]#

Constructs a qibo.result.MeasurementOutcomes from a frequencies dictionary.

The frequencies are expanded into a binary samples array, shuffled to avoid ordering artifacts, and passed through the standard construction path so that all methods (samples(), frequencies(), probabilities()) work correctly.

Parameters:
  • frequencies (dict or Counter) – Mapping from measurement outcomes to their counts. Keys can be binary strings (e.g. "010") or integers (e.g. 2). Values are non-negative integer counts.

  • nqubits (int, optional) – Total number of qubits in the circuit. When binary-string keys are used, the number of measured qubits is inferred from the key length; nqubits may be larger than or equal to that length, and the extra qubits are treated as unmeasured. When integer keys are used without qubits, nqubits is required and is interpreted as the number of measured qubits (backward-compatible behaviour). Defaults to None.

  • qubits (tuple or list, optional) – Qubit indices for the measured qubits. If None, defaults to (0, 1, ..., n_measured - 1) where n_measured is the number of measured qubits. Defaults to None.

  • seed (int, optional) – Seed for sampling generation.

  • backend (qibo.backends.abstract.Backend, optional) – Backend used for calculations. If None, the current default backend is used. Defaults to None.

Returns:

Object storing the measurement outcomes.

Return type:

qibo.result.MeasurementOutcomes

Raises:

ValueError – If the number of measured qubits cannot be determined from the inputs.

Example

from qibo.result import MeasurementOutcomes

freq = {"00": 50, "11": 50}
result = MeasurementOutcomes.from_frequencies(freq)
print(result.frequencies())  # Counter({'00': 50, '11': 50})
class qibo.result.CircuitResult(final_state, measurements, backend=None, samples=None, nshots=1000)[source]#

Object to store both the outcomes of measurements and the final state after circuit execution.

Parameters:
  • final_state (ndarray) – Input quantum state as np.ndarray.

  • measurements (qibo.gates.M) – The measurement gates containing the measurements.

  • backend (qibo.backends.abstract.Backend) – Backend used for the calculations. If not provided, then the current backend is going to be used.

  • probabilities (ndarray) – Use these probabilities to generate samples and frequencies.

  • samples (ndarray) – Use these samples to generate probabilities and frequencies.

  • nshots (int) – Number of shots used for samples, probabilities and frequencies generation.

probabilities(qubits=None)[source]#

Calculates measurement probabilities by tracing out qubits.

When noisy model is applied to a circuit and circuit.density_matrix=False, this method returns the average probability resulting from repeated execution. This probability distribution approximates the exact probability distribution obtained when circuit.density_matrix=True.

Parameters:

qubits (list or set, optional) – Set of qubits that are measured. If None, qubits equates the total number of qubits. Defauts to None.

Returns:

Probabilities over the input qubits.

Return type:

(np.ndarray)

to_dict()[source]#

Returns a dictonary containinig all the information needed to rebuild the CircuitResult.

classmethod from_dict(payload)[source]#

Builds a CircuitResult object starting from a dictionary.

Parameters:

payload (dict) – Dictionary containing all the information to load the CircuitResult object.

Returns:

circuit result object.

Return type:

qibo.result.CircuitResult