Пример #1
0
    def get_optimal_value(self):
        """
        Computes the eigenvalue estimates of the initial state
        Returns:
            numpy.ndarray: array of eigenvalues estimates
        """
        if 'opt_params' not in self._ret:
            raise AquaError("Cannot find optimal vector before running the "
                            "algorithm to find optimal params.")

        # TODO : Find better way to do this
        num_working_qubits = self._num_working_qubits
        circuit = self.get_optimal_circuit()
        counts = None

        if self._quantum_instance.is_statevector:
            ret = self._quantum_instance.execute(circuit)
            state_vec = Statevector(ret.get_statevector(circuit))
            counts = state_vec.probabilities_dict()
        else:
            c = ClassicalRegister(circuit.width(), name='c')
            q = find_regs_by_name(circuit, 'q')
            circuit.add_register(c)
            circuit.barrier(q)
            circuit.measure(q[:num_working_qubits], c[:num_working_qubits])
            ret = self._quantum_instance.execute(circuit)
            counts = ret.get_counts(circuit)

        keys = list(map(''.join, product(['0', '1'],
                                         repeat=num_working_qubits)))
        num_shots = sum(counts.values())
        probs = dict.fromkeys(keys, 0.0)

        for i, (k, v) in enumerate(counts.items()):
            probs[k[-num_working_qubits:]] += v / num_shots

        print({k: v for k, v in sorted(probs.items(), key=lambda item:
            -item[1])})

        eigvals = np.array(list(probs.values()))
        idx = np.argsort(-eigvals)
        return eigvals[idx]
Пример #2
0
    def _cost_evaluation(self, parameters):
        """
        Evaluate cost function at given parameters for the variational form.
        Args:
            parameters (numpy.ndarray): parameters for variational form.
        Returns:
            Union(float, list[float]): cost objective function value of each parameter.
        """
        num_parameter_sets = len(parameters) // self._var_form.num_parameters
        parameter_sets = np.split(parameters, num_parameter_sets)
        global_objs = []
        local_objs = []
        weighted_objs = []

        def _build_parameterized_circuits():
            if self._var_form.support_parameterized_circuit and \
                    self._parameterized_circuits is not None:
                parameterized_circuits = self.construct_circuit(
                    self._var_form_params,
                    statevector_mode=self._quantum_instance.is_statevector,
                    use_simulator_snapshot_mode=self._use_simulator_snapshot_mode)

                self._parameterized_circuits = \
                    self._quantum_instance.transpile(parameterized_circuits)

        _build_parameterized_circuits()
        circuits = []
        # binding parameters here since the circuits had been transpiled
        if self._parameterized_circuits is not None:
            for idx, parameter in enumerate(parameter_sets):
                curr_param = {self._var_form_params: parameter}
                for qc in self._parameterized_circuits:
                    tmp = qc.bind_parameters(curr_param)
                    tmp.name = str(idx) + '_' + tmp.name
                    circuits.append(tmp)
            to_be_simulated_circuits = circuits
        else:
            for idx, parameter in enumerate(parameter_sets):
                circuit = self.construct_circuit(
                    parameter,
                    statevector_mode=self._quantum_instance.is_statevector,
                    use_simulator_snapshot_mode=self._use_simulator_snapshot_mode,
                    circuit_name_prefix=str(idx))
                circuits.append(circuit)
            to_be_simulated_circuits = functools.reduce(lambda x, y:
                                                        x + y, circuits)

        start_time = time()
        result = self._quantum_instance.execute(to_be_simulated_circuits,
                                                self._parameterized_circuits
                                                is not None)

        for idx, _ in enumerate(parameter_sets):
            # Evaluate with result
            circuits = list(filter(lambda circ:
                                   circ.name.startswith('{}_'.format(idx)),
                                   to_be_simulated_circuits))

            # DIP test circuits
            dip_test_circuit = circuits[0]

            # PDIP circuits
            pdip_test_circuits = circuits[1:]

            # evaluate with results
            dip_test_counts = None
            pdip_test_counts = None
            if self._quantum_instance.is_statevector:
                np_state_vec = result.get_statevector(dip_test_circuit)
                dip_test_state_vec = Statevector(np_state_vec)
                dip_test_counts = dip_test_state_vec.probabilities_dict()
                pdip_test_counts = \
                    [Statevector(result.get_statevector(circ)).probabilities_dict()
                     for circ in pdip_test_circuits]
            else:
                dip_test_counts = result.get_counts(dip_test_circuit)
                pdip_test_counts = [result.get_counts(circ) for circ in
                                    pdip_test_circuits]

            obj_global = self._dip_test_post_process(dip_test_counts)
            obj_local = self._pdip_test_post_process(pdip_test_counts)
            obj_weigthed = self._q * obj_global + (1.0 - self._q) * obj_local
            end_time = time()

            global_objs.append(np.real(obj_global))
            local_objs.append(np.real(obj_local))
            weighted_objs.append(np.real(obj_weigthed))

            self._eval_count += 1
            if self._callback is not None:
                self._callback(self._eval_count, parameter_sets[idx],
                               np.real(obj_global), np.real(obj_local),
                               np.real(obj_weigthed))

            # If there is more than one parameter set then the calculation
            # of the evaluation time has to be done more carefully,
            # therefore we do not calculate it
            if len(parameter_sets) == 1:
                logger.info('Cost function evaluation %s '
                            'returned %s - %.5f (ms)',
                            self._eval_count,
                            np.real(obj_weigthed),
                            (end_time - start_time) * 1000)
            else:
                logger.info('Cost function evaluation %s returned %s',
                            self._eval_count,
                            np.real(obj_weigthed))
            return weighted_objs if len(weighted_objs) > 1 \
                                    else weighted_objs[0]