def test_marginal_counts(self): """Test that counts are marginalized correctly.""" raw_counts = { "0x0": 4, "0x1": 7, "0x2": 10, "0x6": 5, "0x9": 11, "0xD": 9, "0xE": 8 } data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result_header = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result = models.ExperimentResult(shots=54, success=True, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) expected_marginal_counts = {"00": 4, "01": 27, "10": 23} self.assertEqual(marginal_counts(result.get_counts(), [0, 1]), expected_marginal_counts) self.assertEqual(marginal_counts(result.get_counts(), [1, 0]), expected_marginal_counts)
def test_marginal_counts(self): """Test that counts are marginalized correctly.""" raw_counts = { '0x0': 4, '0x1': 7, '0x2': 10, '0x6': 5, '0x9': 11, '0xD': 9, '0xE': 8 } data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result_header = QobjExperimentHeader(creg_sizes=[['c0', 4]], memory_slots=4) exp_result = models.ExperimentResult(shots=54, success=True, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) expected_marginal_counts = {'00': 4, '01': 27, '10': 23} self.assertEqual(marginal_counts(result.get_counts(), [0, 1]), expected_marginal_counts) self.assertEqual(marginal_counts(result.get_counts(), [1, 0]), expected_marginal_counts)
def test_counts_duplicate_name(self): """Test results containing multiple entries of a single name will warn.""" data = models.ExperimentResultData(counts=dict()) exp_result_header = QobjExperimentHeader(name='foo') exp_result = models.ExperimentResult(shots=14, success=True, data=data, header=exp_result_header) result = Result(results=[exp_result] * 2, **self.base_result_args) with self.assertWarnsRegex(UserWarning, r'multiple.*foo'): result.get_counts('foo')
def test_counts_int_out(self): """Test that fails when get_count is called with a nonexistent int.""" raw_counts = {'0x0': 4, '0x2': 10} data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data) result = Result(results=[exp_result], **self.base_result_args) with self.assertRaises(Exception) as context: result.get_counts(99) self.assertEqual('Result for experiment "99" could not be found.', context.exception.message)
def test_counts_name_out(self): """Test that fails when get_count is called with a nonexistent name.""" raw_counts = {'0x0': 4, '0x2': 10} data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result_header = QobjExperimentHeader( creg_sizes=[['c0', 2], ['c0', 1], ['c1', 1]], memory_slots=4, name='a_name') exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) with self.assertRaises(Exception) as context: result.get_counts('another_name') self.assertEqual('Data for experiment "another_name" could not be found.', context.exception.message)
def _parse_result(self, result: Result, name: str) -> List[int]: output = list(result.get_counts(name).keys()) self.test_case.assertEqual(len(output), 1) values_as_str = output[0].split(' ') values = [int(value, 2) for value in values_as_str] return values[::-1]
def test_marginal_counts_result_format(self): """Test that marginal_counts with format_marginal true properly formats output.""" raw_counts_1 = { "0x0": 4, "0x1": 7, "0x2": 10, "0x6": 5, "0x9": 11, "0xD": 9, "0x12": 8 } data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[["c0", 2], ["c1", 3]], memory_slots=5) exp_result_1 = models.ExperimentResult(shots=54, success=True, data=data_1, header=exp_result_header_1) result = Result(results=[exp_result_1], **self.base_result_args) expected_marginal_counts_1 = { "0_0 _0": 14, "0_0 _1": 18, "0_1 _0": 5, "0_1 _1": 9, "1_0 _0": 8, } marginal_counts_result = marginal_counts(result.get_counts(), [0, 2, 4], format_marginal=True) self.assertEqual(marginal_counts_result, expected_marginal_counts_1)
def calibration_data( result: Result, metadata: List[Dict[str, any]]) -> Tuple[Dict[int, Dict[int, int]], int]: """Return FullMeasureErrorMitigator from result data. Args: result: Qiskit result object. metadata: mitigation generator metadata. Returns: Calibration data dictionary {label: Counts} and number of qubits. """ # Filter mitigation calibration data cal_data = {} num_qubits = None method = None for i, meta in enumerate(metadata): if meta.get('experiment') == 'meas_mit': if num_qubits is None: num_qubits = len(meta['cal']) if method is None: method = meta.get('method', None) key = int(meta['cal'], 2) counts = result.get_counts(i).int_outcomes() if key not in cal_data: cal_data[key] = counts else: cal_data[key] = combine_counts(cal_data[key], counts) return cal_data, num_qubits, method
def test_counts_no_header(self): """Test that counts are extracted properly without header.""" raw_counts = {'0x0': 4, '0x2': 10} no_header_processed_counts = {bin(int(bs[2:], 16))[2:]: counts for (bs, counts) in raw_counts.items()} data = models.ExperimentResultData(counts=base.Obj(**raw_counts)) exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data) result = Result(results=[exp_result], **self.base_result_args) self.assertEqual(result.get_counts(0), no_header_processed_counts)
def ks_div_sum(circuits: List[QuantumCircuit], simulation_result: Result, reference_result: Result) -> float: """Given a set of test circuits and a Qiskit Result object for a simulation and hardware, the sum of K-S distance between circuit result distributions for each circuit is computed :param circuits: a list of QuantumCircuit objects :param simulation_result: a Qiskit Result object :param reference_result: a Qiskit Result object :return: a float representing the total K-S distance between distributions of all circuits """ total_ks_div = 0 for circuit in circuits: simulation_counts = np.array(counts_to_list(simulation_result.get_counts(circuit))) simulation_dist = simulation_counts / simulation_counts.sum() # normalize if using counts simulator reference_counts = np.array(counts_to_list(reference_result.get_counts(circuit))) reference_dist = reference_counts / reference_counts.sum() # normalize if using counts simulator total_ks_div += discrete_one_samp_ks(reference_dist, simulation_dist, 8000)[0] return total_ks_div
def angle_div_sum(circuits: List[QuantumCircuit], simulation_result: Result, reference_result: Result) -> float: """Given a set of test circuits and a Qiskit Result object for a simulation and hardware, the sum of angle distance between circuit result distributions for each circuit is computed :param circuits: a list of QuantumCircuit objects :param simulation_result: a Qiskit Result object :param reference_result: a Qiskit Result object :return: a float representing the total angle distance between distributions of all circuits """ total_angle_div = 0 for ind, circuit in enumerate(circuits): simulation_counts = np.array(counts_to_list(simulation_result.get_counts(circuit))) simulation_dist = simulation_counts / simulation_counts.sum() # normalize if using counts simulator reference_counts = np.array(counts_to_list(reference_result.get_counts(circuit))) reference_dist = reference_counts / reference_counts.sum() # normalize if using counts simulator total_angle_div += get_vec_angle(reference_dist, simulation_dist) return total_angle_div
def _parse_result(self, result: Result) -> List[str]: measurements: List[str] = [] if self._requires_memory: for e in range(self._experiments): measurements += result.get_memory(e) else: cts = result.get_counts() counts: List[Counts] = [cts] if isinstance(cts, list) else cts for c in counts: measurements += [k for k, v in c.items() if v == 1] return [reverse_endian(m) for m in measurements]
def _add_result_data(self, result: Result): """Add data from qiskit Result object""" num_data = len(result.results) for i in range(num_data): metadata = result.results[i].header.metadata if metadata.get("experiment_type") == self._experiment._type: data = result.data(i) data["metadata"] = metadata if "counts" in data: # Format to Counts object rather than hex dict data["counts"] = result.get_counts(i) self._add_single_data(data)
def test_counts_header(self): """Test that counts are extracted properly with header.""" raw_counts = {'0x0': 4, '0x2': 10} processed_counts = {'0 0 00': 4, '0 0 10': 10} data = models.ExperimentResultData(counts=base.Obj(**raw_counts)) exp_result_header = base.Obj(creg_sizes=[['c0', 2], ['c0', 1], ['c1', 1]], memory_slots=4) exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) self.assertEqual(result.get_counts(0), processed_counts)
def test_counts_by_name(self): """Test that counts are extracted properly by name.""" raw_counts = {'0x0': 4, '0x2': 10} processed_counts = {'0 0 00': 4, '0 0 10': 10} data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result_header = QobjExperimentHeader( creg_sizes=[['c0', 2], ['c0', 1], ['c1', 1]], memory_slots=4, name='a_name') exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) self.assertEqual(result.get_counts('a_name'), processed_counts)
def test_marginal_distribution(self): """Test that counts are marginalized correctly.""" raw_counts = { "0x0": 4, "0x1": 7, "0x2": 10, "0x6": 5, "0x9": 11, "0xD": 9, "0xE": 8 } data = models.ExperimentResultData(counts=raw_counts) exp_result_header = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result = models.ExperimentResult(shots=54, success=True, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) expected_marginal_counts = {"00": 4, "01": 27, "10": 23} expected_reverse = {"00": 4, "10": 27, "01": 23} self.assertEqual(marginal_distribution(result.get_counts(), [0, 1]), expected_marginal_counts) self.assertEqual(marginal_distribution(result.get_counts(), [1, 0]), expected_reverse) # test with register spacing, bitstrings are in form of "00 00" for register split data = models.ExperimentResultData(counts=raw_counts) exp_result_header = QobjExperimentHeader(creg_sizes=[["c0", 2], ["c1", 2]], memory_slots=4) exp_result = models.ExperimentResult(shots=54, success=True, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) self.assertEqual(marginal_distribution(result.get_counts(), [0, 1]), expected_marginal_counts) self.assertEqual(marginal_distribution(result.get_counts(), [1, 0]), expected_reverse)
def _parse_result(self, result: Result) -> str: measurements: List[str] = [] if self._memory: for e in range(self._experiments): measurements += result.get_memory(e) else: cts = result.get_counts() counts: List[Counts] = [cts] if type(cts) != list else cts for c in counts: measurements += [k for k, v in c.items() if v == 1] bitstring: str = "" for m in measurements: bitstring += m return bitstring
def test_multiple_circuits_counts(self): """" Test that counts are returned either as a list or a single item. Counts are returned as a list when multiple experiments are executed and get_counts() is called with no arguments. In all the other cases get_counts() returns a single item containing the counts for a single experiment. """ raw_counts_1 = {'0x0': 5, '0x3': 12, '0x5': 9, '0xD': 6, '0xE': 2} processed_counts_1 = {'0000': 5, '0011': 12, '0101': 9, '1101': 6, '1110': 2} data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[['c0', 4]], memory_slots=4) exp_result_1 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_1, header=exp_result_header_1) raw_counts_2 = {'0x1': 0, '0x4': 3, '0x6': 6, '0xA': 1, '0xB': 2} processed_counts_2 = {'0001': 0, '0100': 3, '0110': 6, '1010': 1, '1011': 2} data_2 = models.ExperimentResultData(counts=dict(**raw_counts_2)) exp_result_header_2 = QobjExperimentHeader(creg_sizes=[['c0', 4]], memory_slots=4) exp_result_2 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_2, header=exp_result_header_2) raw_counts_3 = {'0xC': 27, '0xF': 20} processed_counts_3 = {'1100': 27, '1111': 20} data_3 = models.ExperimentResultData(counts=dict(**raw_counts_3)) exp_result_header_3 = QobjExperimentHeader(creg_sizes=[['c0', 4]], memory_slots=4) exp_result_3 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_3, header=exp_result_header_3) mult_result = Result(results=[exp_result_1, exp_result_2, exp_result_3], **self.base_result_args) sing_result = Result(results=[exp_result_1], **self.base_result_args) self.assertEqual(mult_result.get_counts(), [processed_counts_1, processed_counts_2, processed_counts_3]) self.assertEqual(sing_result.get_counts(), processed_counts_1)
def _compute_phases( self, num_unitary_qubits: int, circuit_result: Result ) -> Union[numpy.ndarray, qiskit.result.Counts]: """Compute frequencies/counts of phases from the result of running the QPE circuit. How the frequencies are computed depends on whether the backend computes amplitude or samples outcomes. 1) If the backend is a statevector simulator, then the reduced density matrix of the phase-reading register is computed from the combined phase-reading- and input-state registers. The elements of the diagonal :math:`(i, i)` give the probability to measure the each of the states `i`. The index `i` expressed as a binary integer with the LSB rightmost gives the state of the phase-reading register with the LSB leftmost when interpreted as a phase. In order to maintain the compact representation, the phases are maintained as decimal integers. They may be converted to other forms via the results object, `PhaseEstimationResult` or `HamiltonianPhaseEstimationResult`. 2) If the backend samples bitstrings, then the counts are first retrieved as a dict. The binary strings (the keys) are then reversed so that the LSB is rightmost and the counts are converted to frequencies. Then the keys are sorted according to increasing phase, so that they can be easily understood when displaying or plotting a histogram. Args: num_unitary_qubits: The number of qubits in the unitary. circuit_result: the result object returned by the backend that ran the QPE circuit. Returns: Either a dict or numpy.ndarray representing the frequencies of the phases. """ if self._quantum_instance.is_statevector: state_vec = circuit_result.get_statevector() evaluation_density_matrix = qiskit.quantum_info.partial_trace( state_vec, range(self._num_evaluation_qubits, self._num_evaluation_qubits + num_unitary_qubits), ) phases = evaluation_density_matrix.probabilities() else: # return counts with keys sorted numerically num_shots = circuit_result.results[0].shots counts = circuit_result.get_counts() phases = {k[::-1]: counts[k] / num_shots for k in counts.keys()} phases = _sort_phases(phases) phases = qiskit.result.Counts(phases, memory_slots=counts.memory_slots, creg_sizes=counts.creg_sizes) return phases
def test_marginal_counts_result_format(self): """Test that marginal_counts with format_marginal true properly formats output.""" raw_counts_1 = {'0x0': 4, '0x1': 7, '0x2': 10, '0x6': 5, '0x9': 11, '0xD': 9, '0x12': 8} data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[['c0', 2], ['c1', 3]], memory_slots=5) exp_result_1 = models.ExperimentResult(shots=54, success=True, data=data_1, header=exp_result_header_1) result = Result(results=[exp_result_1], **self.base_result_args) expected_marginal_counts_1 = {'0_0 _0': 14, '0_0 _1': 18, '0_1 _0': 5, '0_1 _1': 9, '1_0 _0': 8} marginal_counts_result = marginal_counts(result.get_counts(), [0, 2, 4], format_marginal=True) self.assertEqual(marginal_counts_result, expected_marginal_counts_1)
def test_counts_header(self): """Test that counts are extracted properly with header.""" raw_counts = {"0x0": 4, "0x2": 10} processed_counts = {"0 0 00": 4, "0 0 10": 10} data = models.ExperimentResultData(counts=dict(**raw_counts)) exp_result_header = QobjExperimentHeader(creg_sizes=[["c0", 2], ["c0", 1], ["c1", 1]], memory_slots=4) exp_result = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data, header=exp_result_header) result = Result(results=[exp_result], **self.base_result_args) self.assertEqual(result.get_counts(0), processed_counts)
def expectation_val(result: Result, qubit_ind: int, exp_name: str) \ -> float: """ Calculate expectation value of measurement basis. Args: result: result of experiment with meas_level=2. qubit_ind: index of target qubit. exp_name: name of target experiment. """ count_dict = result.get_counts(exp_name) expv = 0 for key, val in count_dict.items(): if key[::-1][qubit_ind] == '1': expv -= val else: expv += val return expv / sum(count_dict.values())
def test_marginal_counts_inplace_false(self): """Test marginal_counts(Result, inplace=False) """ raw_counts_1 = {'0x0': 4, '0x1': 7, '0x2': 10, '0x6': 5, '0x9': 11, '0xD': 9, '0xE': 8} data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[['c0', 4]], memory_slots=4) exp_result_1 = models.ExperimentResult(shots=54, success=True, data=data_1, header=exp_result_header_1) raw_counts_2 = {'0x2': 5, '0x3': 8} data_2 = models.ExperimentResultData(counts=dict(**raw_counts_2)) exp_result_header_2 = QobjExperimentHeader(creg_sizes=[['c0', 2]], memory_slots=2) exp_result_2 = models.ExperimentResult(shots=13, success=True, data=data_2, header=exp_result_header_2) result = Result(results=[exp_result_1, exp_result_2], **self.base_result_args) expected_marginal_counts = {'0': 27, '1': 27} self.assertEqual(marginal_counts(result, [0], inplace=False).get_counts(0), expected_marginal_counts) self.assertNotEqual(result.get_counts(0), expected_marginal_counts)
def test_marginal_counts_inplace_false(self): """Test marginal_counts(Result, inplace=False)""" raw_counts_1 = { "0x0": 4, "0x1": 7, "0x2": 10, "0x6": 5, "0x9": 11, "0xD": 9, "0xE": 8 } data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result_1 = models.ExperimentResult(shots=54, success=True, data=data_1, header=exp_result_header_1) raw_counts_2 = {"0x2": 5, "0x3": 8} data_2 = models.ExperimentResultData(counts=dict(**raw_counts_2)) exp_result_header_2 = QobjExperimentHeader(creg_sizes=[["c0", 2]], memory_slots=2) exp_result_2 = models.ExperimentResult(shots=13, success=True, data=data_2, header=exp_result_header_2) result = Result(results=[exp_result_1, exp_result_2], **self.base_result_args) expected_marginal_counts = {"0": 27, "1": 27} self.assertEqual( marginal_counts(result, [0], inplace=False).get_counts(0), expected_marginal_counts) self.assertNotEqual(result.get_counts(0), expected_marginal_counts)
def get_all_fidelities(circuit_results: qres.Result): r"""Get all contrasts. Gets the fidelity values which are calculated via :func:`calculate_fidelities` and saves these in an array. For more about fidelities, see :meth:`calculate_fidelities`. Args: circuit_results (qiskit.result.Result): the results from a QkNN circuit build using ``QKNeighborsClassifier``. Returns: array: all fidelities corresponding to the QkNN. """ logger.info("Getting fidelity values.") # get all counts from the circuit results all_counts = circuit_results.get_counts() # determine the length of the computational basis register by checking # the length of the count result # the -2 is there to compensate for the ' 0' or ' 1' at the end of # the key. num_qubits = len(list(all_counts[0].keys())[0]) - 2 # initialize the array which will hold the contrast values n_occurrences = len(all_counts) # number of occurring states n_datapoints = 2**num_qubits # number of data points all_fidelities = np.empty(shape=(n_occurrences, n_datapoints), ) # loop over all counted states for i, counts in enumerate(all_counts): # calculate the contrast values q(i) for this set of counts all_fidelities[i] = \ QKNeighborsClassifier.calculate_fidelities(counts) logger.info("Done.") return all_fidelities
def test_multiple_circuits_counts(self): """ " Test that counts are returned either as a list or a single item. Counts are returned as a list when multiple experiments are executed and get_counts() is called with no arguments. In all the other cases get_counts() returns a single item containing the counts for a single experiment. """ raw_counts_1 = {"0x0": 5, "0x3": 12, "0x5": 9, "0xD": 6, "0xE": 2} processed_counts_1 = { "0000": 5, "0011": 12, "0101": 9, "1101": 6, "1110": 2 } data_1 = models.ExperimentResultData(counts=dict(**raw_counts_1)) exp_result_header_1 = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result_1 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_1, header=exp_result_header_1) raw_counts_2 = {"0x1": 0, "0x4": 3, "0x6": 6, "0xA": 1, "0xB": 2} processed_counts_2 = { "0001": 0, "0100": 3, "0110": 6, "1010": 1, "1011": 2 } data_2 = models.ExperimentResultData(counts=dict(**raw_counts_2)) exp_result_header_2 = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result_2 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_2, header=exp_result_header_2) raw_counts_3 = {"0xC": 27, "0xF": 20} processed_counts_3 = {"1100": 27, "1111": 20} data_3 = models.ExperimentResultData(counts=dict(**raw_counts_3)) exp_result_header_3 = QobjExperimentHeader(creg_sizes=[["c0", 4]], memory_slots=4) exp_result_3 = models.ExperimentResult(shots=14, success=True, meas_level=2, data=data_3, header=exp_result_header_3) mult_result = Result( results=[exp_result_1, exp_result_2, exp_result_3], **self.base_result_args) sing_result = Result(results=[exp_result_1], **self.base_result_args) self.assertEqual( mult_result.get_counts(), [processed_counts_1, processed_counts_2, processed_counts_3]) self.assertEqual(sing_result.get_counts(), processed_counts_1)