def test_circuit_statevector_repr_decimal(self):
     """Test postprocessing of statevector giving decimals arg."""
     raw_statevector = np.array(
         [
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
             0.35355339 + 0.0j,
         ],
         dtype=np.complex_,
     )
     processed_sv = np.array(
         [
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
             0.354 + 0.0j,
         ],
         dtype=np.complex_,
     )
     data = models.ExperimentResultData(statevector=raw_statevector)
     exp_result = models.ExperimentResult(shots=1, success=True, data=data)
     result = Result(results=[exp_result], **self.base_result_args)
     statevector = result.get_statevector(decimals=3)
     self.assertEqual(statevector.shape, (8, ))
     self.assertEqual(statevector.dtype, np.complex_)
     np.testing.assert_almost_equal(statevector, processed_sv)
Beispiel #2
0
    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