Results

class trueq.Results(value=None, n_measurements=None, dim=None)

A dictionary-like class which keeps track of measurement results for a single circuit that was run on quantum hardware or a simulator. This is stored as a map from bitstrings to corresponding counts.

Here are some examples:

from trueq import Results

# here we have 3 total measurements in the circuit, meaning we
# have to have a bitstring of length 3
res = Results()
res['000'] = 1000
res['100'] = 5

# unary addition with another (compatible) Results-like object is supported
res += {'100': 5, '110': 100}

res
Results({'000': 1000, '100': 10, '110': 100})
from trueq import Results

# here we have 2 total measurements in the circuit
res = Results(n_measurements=2)

# we can also index this using the decimal representation of the number
# so in the case of 2 total measurements, we can index, 0, 1, 2, 3.
# This only works if either measurements are already present, or
# n_measurements is specified on instantiation.
res[0] = 30
res[3] += 30

res
Results({'00': 30, '11': 30})

Note

This class works for ditstrings as well as bitstrings, for \(d<10\). However, for simplicity, this documentation refers to bitstrings throughout.

Dimension can be specified at instantiation, but this dimension will be silently increased if bitstrings with larger numbers get inserted. For example, putting a bitstring of '002' in will mean the dimension will be at least 3, even if it was only 2 previously.

Parameters
  • value (dict or similar) – A dictionary like object containing bitstrings and counts, see above examples.

  • n_measurements – The number of measurements present, this is inferred if None provided. If not provided, the first measurement added sets this value. Using integer based indexing of the results will not work unless either this number is specified, or has been inferred through another means.

  • dim (int) – The dimension of the systems, 2 for qubits (Default: 2), this number will automatically increase if bitstrings with larger values are put in.

get(bitstring)

Gets the value associated with a given bitstring, if none is found, returns 0.

Bitstrings must match the number of measurements in the Results, this can be checked with n_measurements

Parameters

bitstring (int | str) – A valid bitstring or int, such as '101' or 5.

reset()

Resets all counts to 0, but leaves measurement positions intact. Resets last_modified to None.

property last_modified

The timestamp of the last modification to these results, which is automatically set whenever the results are modified. The automatically set value is the current UTC time in the ISO string format. This timestamp can also be set manually, in which case any subsequent changes to the results will _not_ cause this timestamp to automatically change. Results that have never had counts added will have a value of None.

from trueq import Results

r = Results()
print(r.last_modified is None)

# automatically update the timestamp
r["00"] = 5
print(r.last_modified)

# manually update the timestamp
r.last_modified = "2019-10-02T00:00:00.0"
print(r.last_modified)

# we've adjusted it manually, so it is no longer automatically updated
r["01"] = 2
print(r.last_modified)
True
2020-08-07T20:27:04.566719
2019-10-02T00:00:00.0
2019-10-02T00:00:00.0
Type

str | None

property dim

The system dimension; 2 for qubits, 3 for qutrits, etc.

Type

int

property vec

Returns a vector representation of the results.

from trueq import Results

res = Results(n_measurements=2)
res[0] = 10
res[3] = 30

res.vec
array([10,  0,  0, 30])
Type

numpy.ndarray

property n_measurements

Returns the total number of measurements, i.e. the length of each bitstring.

Type

int

property n_shots

Returns the total number of shots present.

This is useful in the normalization of the results.

from trueq import Results

res = Results(n_measurements=2)
res[0] = 10
res[3] = 30

res.n_shots
40
Type

int

sort(by_value=True)

Sorts the keys of the results in-place, either by value or by bitstring.

Parameters

by_value (bool) – If this is true, sort the results with the largest number of counts at the beginning of the results. If this is false, sort the results by the bitstring value, i.e. '00', '01', '10', '11'.

marginal(positions)

Returns a new Results object obtained by marginalizing this results object over the specified positions. The order of positions is respected, so this method can also be used to create a copy with reordered bitstrings.

from trueq import Results

res = Results({"0110": 15, "0111": 35})

print(res.marginal([1, 2]))
print(res.marginal([0, 3]))
Results({'11': 50})
Results({'00': 15, '01': 35})
Parameters

positions (Iterable) – A list of bitstring position indexes to keep in the new results object.

Return type

Results

from_vec(vec)

Sets the bitstring counts from a given vector which has a length with is a power of the system dimension.

from trueq import Results

Results().from_vec([0.5, 0, 0, 0.5])
Results({'00': 0.5, '11': 0.5})
Parameters

vec (list or numpy.ndarray etc.) – A vector which has a length which is a power of the system dim.

Returns

This instance.

Return type

Results

subsample(n_shots, copy=True)

Randomly chooses a subset of shots. This is done uniformly and without replacement.

Parameters
  • n_shots (int) – The number of shots to subsample, must be no bigger than the number of shots present.

  • copy (bool) – If True, a new copy of the results will be made and returned, otherwise, the operation will happen in-place.

Return type

Results

tvd(other, multinomial=None)

Computes the total variational distance (TVD) between these results and another Results object. Each result object is treated as an empirical probability distribution by dividing each value by the sum of all values. The TVD between two probabality vectors \(p\) and \(q\) is given by

\[\operatorname{tvd}(p,q) = \sum_i |p_i - q_i| / 2.\]

If these results (and/or the other results) have a total value sum other than 1, it is assumed that these results represent a multinomial sample, and this information is used to estimate the standard deviation of the TVD using multinomial sampling error. This default behaviour can be overridden with the multinomial option.

from trueq import Results

r1 = Results({"00": 50, "11": 50})
r2 = Results({"00": 498, "11": 492, "01": 1, "10": 9})
print(r1.tvd(r2))

# here, both results sum to 1 so there is assumed to be no multinomial
# sampling error, and hence the variance is reported at 0.
r1 = Results({"00": 0.5, "11": 0.5})
r2 = Results({"00": 0.498, "11": 0.492, "01": 0.001, "10": 0.009})
print(r1.tvd(r2))
(0.010000000000000009, 0.003146426544510458)
(0.010000000000000009, 0.0)
Parameters
  • other (Results) – Another results object to compute the TVD with.

  • multinomial (Iterable) – A pair of boolean values (self_multi, other_multi) which specify whether these results and/or the other results should be treated as multinomial samples, thereby contributing to estimated standard deviation. The default value of None results in the behaviour explained above.

Returns

A pair (tvd, std) where tvd is the TVD and std is an estimate of its standard deviation.

Return type

tuple

Raises

ValueError – If the result objects are not compatible with one another, where either the dimension or number of measurements do not match.

decompiled_results(pauli)

Returns a new results object where the outcomes are flipped for each qubit where the given pauli is 'X' or 'Y'.

Parameters

pauli (str) – A pauli string that specifies which bits to flip.

Return type

Results

to_dict()

Returns a dictionary representation of a Results object. This dictionary representation contains only base Python classes.

Return type

dict

static from_dict(dic)

Returns a Results constructed from a dictionary representation.

Parameters

dic (dict) – A dictionary used to construct a new Results.

Return type

Results

plot(sparse=None, axis=None)

Plots a bar graph of these results.

from numpy.random import randint
from trueq import Results

Results().from_vec(randint(0, 100, 32)).plot()
../_images/results_8_0.png
Parameters
  • sparse (bool | None) – Whether to only plot values bigger than \(1/s^2\), where \(s\) is the number of possible ditstrings. By default, this is True for \(s>256\) and False otherwise.

  • axis (matplotlib.Axis | None) – An existing axis to plot on, or None to create a new one.