Results#

Utilities for handling results returned by a gate-model simulator or QPU.

class Result(*, num_shots: int, start_time: datetime | None = None, end_time: datetime | None = None, seconds_per_shot: float | None = None, num_qubits: int | None = None, simulated_qcdl: str | None = None, record_format: RecordFormat | None = None, measurements: dict[str, list[str | list[int | str] | ndarray]] | None = None, records: dict[str, dict[str, Any]] | str | None = None, executed_qcdl: QCDLProgram | None = None, **extra_data: Any)[source]#

Bases: BaseModel

Result returned by a gate-model simulator or QPU.

num_shots[source]#

Total number of times the circuit was executed.

Type:

int

start_time[source]#

Timestamp for when execution began.

Type:

datetime.datetime | None

end_time[source]#

Timestamp for when execution ended.

Type:

datetime.datetime | None

seconds_per_shot[source]#

Total time, in seconds, divided by the number of shots.

Type:

float | None

num_qubits[source]#

Number of qubits used in the circuit.

Type:

int | None

simulated_qcdl[source]#

Label describing the simulated QCDL.

Type:

str | None

record_format[source]#

Serialization format used for records.

Type:

dwave.gate.qcdl.records.RecordFormat | None

measurements[source]#

Raw measurement data, keyed by tag.

records[source]#

Table data or raw QIR log output.

executed_qcdl[source]#

QCDL payload representing the executed program.

Type:

dwave.gate.qcdl.models.QCDLProgram | None

get_counts(tag: str | None = None, register: list[str | None] | None = None, post_select: bool = False, unmeasured_value: int | str = '_', shots: int | None = None) list[dict[int | str, int]][source]#

A counts dict is a summation over all the shots.

This returns a list of dicts, one for each “measurement per shot”.

Parameters:
Returns:

A summation of the memory.

get_measurements_register(tag: str | None = None, descending: bool = True) list[str][source]#

Return the register inferred from the measurements data for the tag.

This method includes a qubit in the register if and only if it has measurements in the log data. It determines the name of the qubit from its index in the measurements array.

Parameters:
  • tag – The data set to load. Defaults to default_tag.

  • descending – Whether qubits are in descending order. Defaults to True.

Returns:

List of qubit names.

get_memory(tag: str | None = None, register: list[str | None] | None = None, unmeasured_value: int | str = '_', shots: int | None = None) ndarray[source]#

Memory is the 3D array of measurements per shot, shots, qubits.

The raw bits returned from a statement such as q0.measure().

Parameters:
  • tag – The data set to load. Defaults to default_tag.

  • register – List of qubit names to include in the register; determines the inner dimension of the returned value.

  • unmeasured_value – Value to put in the register if a requested qubit is not measured.

  • shots – Overrides the shots in the result object.

Returns:

Memory array.

property default_tag: str[source]#

The default tag, if defined.

If there is only one tag, this method returns it. This is sufficient for many experiments which only have one measurement per qubit.

If there are multiple tags present in the data or no tag, there is no default tag, and the method raises a ValueError.

Returns:

The default tag.

property measurements: dict[str, list[ndarray]] | None[source]#

Data generated by log=True.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'frozen': True}[source]#

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property records: dict | str | None[source]#

Data generated by the append_table_row() method.

property run_time: float | None[source]#

The time the simulation or QPU ran.

Returns:

Run time in seconds, if available.

property tags: tuple[str, ...][source]#

The tags available in the measurements.

NOTE: tags is not currently supported with real-time-measurements.

Returns:

The tags.

class YieldHandling(*values)[source]#

Bases: StrEnum

Handling of erasure measurement.

Errors detected during an end-of-line measurement are marked with a "*" (splat) instead of a \(0\) or \(1\), as described in the Measurements section. You might need to remove these splats, for example, to work with Qiskit, which does not accept splats in a counts dict. This class enumerates some removal techniques.

apply(distribution: dict[Any, int]) tuple[dict[Any, float | int], float][source]#

Apply this yield handling to a counts dict.

Parameters:

distribution – Counts, as returned by the count_measurements() function or the Result.get_counts() method. Keys may be in any of the formats that function produces.

Raises:
Returns:

The handled distribution and the observed yield.

ignore_splats = 'ignore_splats'[source]#

Do not alter the distribution.

only_post_selected_counts = 'only_post_selected_counts'[source]#

Return only post-selected shots; i.e., only results of \(0\) and \(1\).

The number of returned shots may be lower than the number of requested shots.

renormalize_distribution = 'renormalize_distribution'[source]#

Renormalize the post-selected distribution.

After post selecting the distribution, normalize it so that the sum of values equals the number of shots requested (by dividing by the yield).

This approach may be necessary for code that can not handle a number of returned shots different from requested. The counts become floats.

Warning

This approach misrepresents the statistical errors, and in the case of low yield, significantly.

Warning

Raises an exception if no shots are returned.

renormalize_distribution_or_raise = 'renormalize_distribution_or_raise'[source]#

Renormalize the post-selected distribution for yield greater than 10%.

Similar to the renormalize_distribution technique, but raises an exception if the yield is below 10%.

count_measurements(memory: list | ndarray, key_format: str | None = 'bin', post_select: bool = True) dict[int | str, int][source]#

Convert memory to a dict of observation counts.

Raw data (memory) contains values \(0, 1\) or "*" (“splat”) for each qubit, for each shot. This method converts that into a count of each set of measurements. The key for the dict is customizable.

When converting to int/bin, the qubit register is treated as big endian; i.e., the least-significant bit is last in the array for each shot.

key_format values:
  • "bin": keys are binary numbers with width taken from the memory.

  • "hex": keys are hexadecimal strings (e.g., '0x3').

  • None: keys are integers.

Parameters:
  • memory – 2D array of size shots x qubits sorted with the least-significant bit last (on the right).

  • key_format – Formats the ints used as dict keys. Ignored if the memory consists of strings.

  • post_select – If True, any bitstrings that have "*" in them are excluded.

Examples

>>> from dwave.gate.results import count_measurements
...
>>> count_measurements([[0,1,0,0]]*10, key_format='bin')
{'0100': 10}
>>> count_measurements([[0,1,0,0]]*10, key_format='hex')
{'0x4': 10}
>>> count_measurements([[0,1,0,0]]*10, key_format=None)
{4: 10}
Returns:

A dict counting occurrences of each value of formatted shots.

format_memory(measurements: list[Any] | dict[str, list[int | str] | ndarray], shots: int, register: list[str | None] | None = None, unmeasured_value: int | str = '_') ndarray[source]#

Shape results.

The measurement input is a flat array of all the measurements on each qubit over the entire circuit execution (i.e., for all shots), and does not indicate how many measurements occurred per shot. If you specify a tag for the measure() operations, this method is called once for each tag.

This method handles results where each qubit may have been measured multiple times per shot with the number of measurements varying among qubits. The method adds padding to the measurements if those numbers differ to enable the formation of a dict of bitstrings from the data.

Note

After converting individual measurement arrays to a NumPy array of type str, it updates the input-measurements data structure in-place.

Parameters:
  • measurements – Measurements, as a 2D array or dict of arrays, from either the simulator or QPU. If a 2D array is passed, the qubit name is inferred from the index in the array.

  • shots – Number of shots to produce this data.

  • register – List of qubit names (or None) to go into the register. A None in the list fills in the value to set through the unmeasured_value argument. If a register is not provided, the get_default_register() creates one.

  • unmeasured_value – Value to put in the register if a requested qubit is not measured. Defaults to “_”.

Raises:

ValueError – Register mismatch with results.

Returns:

A 3D array of str with shape (measurements per shot, shots, qubits).

get_default_register(qubits: Iterable[str]) list[str | None][source]#

Return the register used when none is specified.

This register includes all qubits in the circuit, regardless of which have measurements. Specifying a register is preferable.

Sorts qubits from highest to lowest index; e.g., [q2, q1, q0]

Parameters:

qubits – List of qubits in the QPU.

Returns:

Qubits sorted from highest index to lowest.