示例#1
0
 def test_purity_mixed_state(self):
     state_1 = 0.5 * (projector(basis_state('0', 1)) +
                      projector(basis_state('1', 1)))
     state_2 = (1 / 3.0) * (projector(basis_state('00', 2)) + projector(
         basis_state('01', 2)) + projector(basis_state('10', 2)))
     self.assertEqual(purity(state_1), 0.5)
     self.assertEqual(purity(state_2), 1.0 / 3)
示例#2
0
 def test_purity_list_input(self):
     rho1 = [[1, 0], [0, 0]]
     rho2 = [[0.5, 0], [0, 0.5]]
     rho3 = 0.7 * np.array(rho1) + 0.3 * np.array(rho2)
     test_pass = (purity(rho1) == 1.0 and purity(rho2) == 0.5
                  and round(purity(rho3), 10) == 0.745)
     self.assertTrue(test_pass)
示例#3
0
 def test_purity_basis_state_input(self):
     state_1 = basis_state('0', 1)
     state_2 = basis_state('11', 2)
     state_3 = basis_state('010', 3)
     self.assertEqual(purity(state_1), 1.0)
     self.assertEqual(purity(state_2), 1.0)
     self.assertEqual(purity(state_3), 1.0)
示例#4
0
 def test_purity_equivalence(self):
     """Test purity is same for equivalent inputs"""
     for alpha, beta in [(0, 0), (0, 0.25), (0.25, 0), (0.33, 0.33),
                         (0.5, 0.5), (0.75, 0.25), (0, 0.75)]:
         psi = Statevector(
             [alpha, beta, 0, 1j * np.sqrt(1 - alpha**2 - beta**2)])
         rho = DensityMatrix(psi)
         self.assertAlmostEqual(purity(psi), purity(rho))
示例#5
0
 def test_purity_pure_state(self):
     state_1 = (1/np.sqrt(2))*(basis_state('0', 1) + basis_state('1', 1))
     state_2 = (1/np.sqrt(3))*(basis_state('00', 2)
                               + basis_state('01', 2) + basis_state('11', 2))
     state_3 = 0.5*(basis_state('000', 3) + basis_state('001', 3)
                    + basis_state('010', 3) + basis_state('100', 3))
     self.assertEqual(purity(state_1), 1.0)
     self.assertEqual(purity(state_2), 1.0)
     self.assertEqual(purity(state_3), 1.0)
示例#6
0
 def test_purity_pure_matrix_state(self):
     state_1 = (1/np.sqrt(2))*(basis_state('0', 1) + basis_state('1', 1))
     state_1 = projector(state_1)
     state_2 = (1/np.sqrt(3))*(basis_state('00', 2)
                               + basis_state('01', 2) + basis_state('11', 2))
     state_2 = projector(state_2)
     state_3 = 0.5*(basis_state('000', 3) + basis_state('001', 3)
                    + basis_state('010', 3) + basis_state('100', 3))
     state_3 = projector(state_3)
     self.assertAlmostEqual(purity(state_1), 1.0, places=10)
     self.assertAlmostEqual(purity(state_2), 1.0, places=10)
     self.assertEqual(purity(state_3), 1.0)
示例#7
0
    def test_purity_density_matrix(self):
        """Test purity function on density matrix inputs"""
        rho = DensityMatrix(np.diag([1, 0, 0, 0]))
        self.assertEqual(purity(rho), 1)
        self.assertEqual(purity(rho, validate=True), 1)
        self.assertEqual(purity(rho, validate=False), 1)

        rho = np.diag([0.25, 0.25, 0.25, 0.25])
        self.assertEqual(purity(rho), 0.25)
        self.assertEqual(purity(rho, validate=True), 0.25)
        self.assertEqual(purity(rho, validate=False), 0.25)

        rho = [[0.5, 0, 0, 0.5], [0, 0, 0, 0], [0, 0, 0, 0], [0.5, 0, 0, 0.5]]
        self.assertEqual(purity(rho), 1)
        self.assertEqual(purity(rho, validate=True), 1)
        self.assertEqual(purity(rho, validate=False), 1)

        rho = np.diag([1, 0, 0, 1])
        self.assertRaises(QiskitError, purity, rho)
        self.assertRaises(QiskitError, purity, rho, validate=True)
        self.assertEqual(purity(rho, validate=False), 2)
示例#8
0
    def test_purity_statevector(self):
        """Test purity function on statevector inputs"""
        psi = Statevector([1, 0, 0, 0])
        self.assertEqual(purity(psi), 1)
        self.assertEqual(purity(psi, validate=True), 1)
        self.assertEqual(purity(psi, validate=False), 1)

        psi = [0.70710678118654746, 0.70710678118654746]
        self.assertAlmostEqual(purity(psi), 1)
        self.assertAlmostEqual(purity(psi, validate=True), 1)
        self.assertAlmostEqual(purity(psi, validate=False), 1)

        psi = np.array([0.5, 0.5j, -0.5j, -0.5])
        self.assertAlmostEqual(purity(psi), 1)
        self.assertAlmostEqual(purity(psi, validate=True), 1)
        self.assertAlmostEqual(purity(psi, validate=False), 1)

        psi = Statevector([1, 0, 0, 1])
        self.assertRaises(QiskitError, purity, psi)
        self.assertRaises(QiskitError, purity, psi, validate=True)
        self.assertEqual(purity(psi, validate=False), 4)
示例#9
0
    def test_purity_statevector_density_matrix(self):
        """Test purity is same for equivalent statevector and density matrix inputs"""
        psi = Statevector([0.5, -0.5, 0.5j, -0.5j])
        rho = DensityMatrix(psi)
        self.assertAlmostEqual(purity(psi), purity(rho))

        psi = Statevector([0.5, 0, 0, -0.5j])
        rho = DensityMatrix(psi)
        self.assertAlmostEqual(purity(psi, validate=False), purity(rho, validate=False))

        psi = Statevector([1, 1])
        rho = DensityMatrix(psi)
        self.assertAlmostEqual(purity(psi, validate=False), purity(rho, validate=False))
示例#10
0
 def test_purity_1d_list_input(self):
     input_state = [1, 0]
     res = purity(input_state)
     self.assertEqual(1, res)
示例#11
0
    def __init__(self,
                 initial_state: InitialState,
                 operator: Optional[BaseOperator] = None,
                 q: Optional[float] = 0.5,
                 num_ancillae: Optional[int] = 0,
                 var_form: Optional[VariationalForm] = None,
                 optimizer: Optional[Optimizer] = None,
                 initial_point: Optional[np.ndarray] = None,
                 max_evals_grouped: int = 1,
                 callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None,
                 quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None:
        """
        Constructor.

        Args:
            initial_state (InitialState): The state to be diagonalized
            operator (BaseOperator): The density matrix of the
            initial state
            q (int): Free parameter that ones to tailer the VQSD method
            num_ancillae (int): The number of ancillae qubits if the initial
            state is a mixed state
            var_form: A parameterized variational form (ansatz).
            optimizer: A classical optimizer.
            initial_point: An optional initial point (i.e. initial parameter values)
                for the optimizer. If ``None`` then VQE will look to the variational form for a
                preferred point and if not will simply compute a random one.
            max_evals_grouped: Max number of evaluations performed simultaneously. Signals the
                given optimizer that more than one set of parameters can be supplied so that
                potentially the expectation values can be computed in parallel. Typically this is
                possible when a finite difference gradient is used by the optimizer such that
                multiple points to compute the gradient can be passed and if computed in parallel
                improve overall execution time.
            callback: a callback that can access the intermediate data during the optimization.
                Four parameter values are passed to the callback as follows during each evaluation
                by the optimizer for its current set of parameters as it works towards the minimum.
                These are: the evaluation count, the optimizer parameters for the
                variational form, the evaluated global cost, local cost and
                weighted cost
            quantum_instance: Quantum Instance or Backend
        """

        validate_min('max_evals_grouped', max_evals_grouped, 1)
        validate_range('num_ancillae', num_ancillae, 0, initial_state._num_qubits - 1)
        validate_range('q', q, 0.0, 1.0)

        if var_form is None:
            # TODO after ansatz refactor num qubits can be set later so we do not have to have
            #      an operator to create a default
            if initial_state is not None:
                var_form = RY(initial_state._num_qubits -
                              num_ancillae)

        if optimizer is None:
            optimizer = SLSQP()

        if operator is None:
            initial_state_vector = initial_state.construct_circuit(mode='vector')
            mat = np.outer(initial_state_vector, np.conj(initial_state_vector))
            operator = DensityMatrix(mat)

        # TODO after ansatz refactor we may still not be able to do this
        # if num qubits is not set on var form
        if initial_point is None and var_form is not None:
            initial_point = var_form.preferred_init_points

        self._max_evals_grouped = max_evals_grouped

        super().__init__(var_form=var_form,
                         optimizer=optimizer,
                         cost_fn=self._cost_evaluation,
                         initial_point=initial_point,
                         quantum_instance=quantum_instance)

        self._callback = callback
        self._use_simulator_snapshot_mode = None
        self._ret = None
        self._eval_time = None
        self._eval_count = 0

        logger.info(self.print_settings())
        self._var_form_params = None
        if self.var_form is not None:
            self._var_form_params = ParameterVector('θ', self.var_form.num_parameters)
        self._parameterized_circuits = None

        self._initial_state = initial_state
        self._q = q
        self._num_ancillae = num_ancillae
        self._num_working_qubits = initial_state._num_qubits - num_ancillae
        self._operator = operator
        self.initial_state = initial_state

        # TODO : Verify that if the ancillae qubits form an orthonormal basis

        # Compute state purity
        if self._num_ancillae > 0:
            # pylint: disable=import-outside-toplevel
            from qiskit.quantum_info import purity, partial_trace

            rho = self._operator.data
            ancillae_idx = list(set(range(self._initial_state._num_qubits)) -
                                set(range(self._num_ancillae)))
            self._operator = partial_trace(rho, ancillae_idx)
            self._purity = purity(self._operator)
        else:
            self._purity = 1.0