Exemple #1
0
    def construct_circuit(self, parameter, statevector_mode=False,
                          use_simulator_snapshot_mode=False,
                          circuit_name_prefix=''):
        """
        Generate the circuits.
        Args:
            parameter (numpy.ndarray): parameters for variational form.
            statevector_mode (bool, optional): indicate which type of simulator are going to use.
            use_simulator_snapshot_mode (bool, optional): is backend from AerProvider,
                            if True and mode is paulis, single circuit is generated.
            circuit_name_prefix (str, optional): a prefix of circuit name
        Returns:
            list[QuantumCircuit]: the generated circuits with Hamiltonian.
        Raises:
            AquaError: Circuit cannot be created if an operator has not been provided
        """
        if self._initial_state is None:
            raise AquaError("Initial state was never provided")

        circuits = []
        dip_test = self._dip_test(parameter, circuit_name_prefix=circuit_name_prefix)
        num_working_qubits = self._num_working_qubits

        if not statevector_mode:
            creg = ClassicalRegister(dip_test.width(), name="dip_creg")
            qreg = find_regs_by_name(dip_test, 'dip_qreg')
            dip_test.add_register(creg)
            dip_test.barrier(qreg)
            dip_test.measure(qreg[:num_working_qubits],
                             creg[:num_working_qubits])
        circuits.append(dip_test)

        for i in range(self._num_working_qubits):
            # get relevant qubit indices
            dip_qubit_idx = [i]
            swap_qubit_idx = list(set(range(num_working_qubits)) -
                                  set(dip_qubit_idx))
            swap_qubit_idx += [i + num_working_qubits for i in swap_qubit_idx]
            dip_qubit_idx += [i + num_working_qubits for i in dip_qubit_idx]
            pdip_test = self._pdip_test(parameter,
                                        dip_qubit_idx, swap_qubit_idx,
                                        circuit_name_prefix=circuit_name_prefix)

            if not statevector_mode:
                creg = ClassicalRegister(pdip_test.width(), name="dip_creg")
                qreg = find_regs_by_name(pdip_test, 'pdip_qreg')
                pdip_test.add_register(creg)
                pdip_test.barrier(qreg)
                pdip_test.measure(qreg[swap_qubit_idx + dip_qubit_idx],
                                  creg[swap_qubit_idx + dip_qubit_idx])
            circuits.append(pdip_test)
        return circuits
    def calc_expectataion(self, pauli_str, sub_circuit):
        qubit_op = WeightedPauliOperator([[1, Pauli.from_label(pauli_str)]])
        sv_mode = False

        qi = QuantumInstance(backend=Aer.get_backend('qasm_simulator'),
                             shots=1000,
                             seed_simulator=100,
                             seed_transpiler=2)

        if qi.is_statevector:
            sv_mode = True

        # Make sure that the eval quantum/ classical registers in the circuit are named 'q'/'c'
        qc = qubit_op.construct_evaluation_circuit(
            statevector_mode=sv_mode,
            wave_function=sub_circuit,
            qr=find_regs_by_name(sub_circuit, 'q'),
            use_simulator_operator_mode=True)

        result = qi.execute(qc)
        avg, std = qubit_op.evaluate_with_result(
            statevector_mode=sv_mode,
            result=result,
            use_simulator_operator_mode=True)

        return avg
Exemple #3
0
    def get_optimal_vector(self):
        from qiskit.aqua.utils.run_circuits import find_regs_by_name

        if 'opt_params' not in self._ret:
            raise AquaError("Cannot find optimal vector before running the "
                            "algorithm to find optimal params.")
        qc = self.get_optimal_circuit()
        if self._quantum_instance.is_statevector:
            ret = self._quantum_instance.execute(qc)
            self._ret['min_vector'] = ret.get_statevector(qc)
        else:
            c = ClassicalRegister(qc.width(), name='c')
            q = find_regs_by_name(qc, 'q')
            qc.add_register(c)
            qc.barrier(q)
            qc.measure(q, c)
            ret = self._quantum_instance.execute(qc)
            self._ret['min_vector'] = ret.get_counts(qc)
        return self._ret['min_vector']
Exemple #4
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]
Exemple #5
0
    def get_optimal_vector(self) -> Union[List[float], Dict[str, int]]:
        """Get the simulation outcome of the optimal circuit. """
        # pylint: disable=import-outside-toplevel
        from qiskit.aqua.utils.run_circuits import find_regs_by_name

        if 'opt_params' not in self._ret:
            raise AquaError("Cannot find optimal vector before running the "
                            "algorithm to find optimal params.")
        qc = self.get_optimal_circuit()
        if self._quantum_instance.is_statevector:
            ret = self._quantum_instance.execute(qc)
            self._ret['min_vector'] = ret.get_statevector(qc)
        else:
            c = ClassicalRegister(qc.width(), name='c')
            q = find_regs_by_name(qc, 'q')
            qc.add_register(c)
            qc.barrier(q)
            qc.measure(q, c)
            ret = self._quantum_instance.execute(qc)
            self._ret['min_vector'] = ret.get_counts(qc)
        return self._ret['min_vector']
    def construct_evaluation_circuit(self, wave_function, statevector_mode,
                                     qr=None, cr=None, use_simulator_snapshot_mode=False,
                                     circuit_name_prefix=''):
        r"""
        Construct the circuits for evaluation, which calculating the expectation <psi\|H\|psi>.

        At statevector mode: to simplify the computation, we do not build the whole
        circuit for <psi|H|psi>, instead of
        that we construct an individual circuit <psi\|, and a bundle circuit for H\|psi>

        Args:
            wave_function (QuantumCircuit): the quantum circuit.
            statevector_mode (bool): indicate which type of simulator are going to use.
            qr (QuantumRegister, optional): the quantum register associated with the input_circuit
            cr (ClassicalRegister, optional): the classical register associated
                                              with the input_circuit
            use_simulator_snapshot_mode (bool, optional): if aer_provider is used, we can do faster
                                                          evaluation for pauli mode on
                                                          statevector simulation
            circuit_name_prefix (str, optional): a prefix of circuit name

        Returns:
            list[QuantumCircuit]: a list of quantum circuits and each circuit with a unique name:
                                  circuit_name_prefix + Pauli string

        Raises:
            AquaError: if Operator is empty
            AquaError: if quantum register is not provided explicitly and
                       cannot find quantum register with `q` as the name
            AquaError: The provided qr is not in the wave_function
        """
        if self.is_empty():
            raise AquaError("Operator is empty, check the operator.")
        # pylint: disable=import-outside-toplevel
        from qiskit.aqua.utils.run_circuits import find_regs_by_name

        if qr is None:
            qr = find_regs_by_name(wave_function, 'q')
            if qr is None:
                raise AquaError("Either provide the quantum register (qr) explicitly or use"
                                " `q` as the name of the quantum register in the input circuit.")
        else:
            if not wave_function.has_register(qr):
                raise AquaError("The provided QuantumRegister (qr) is not in the circuit.")

        n_qubits = self.num_qubits
        instructions = self.evaluation_instruction(statevector_mode, use_simulator_snapshot_mode)
        circuits = []
        if use_simulator_snapshot_mode:
            circuit = wave_function.copy(name=circuit_name_prefix + 'snapshot_mode')
            # Add expectation value snapshot instruction
            instr = instructions.get('expval_snapshot', None)
            if instr is not None:
                circuit.append(instr, qr)
            circuits.append(circuit)
        elif statevector_mode:
            circuits.append(wave_function.copy(name=circuit_name_prefix + 'psi'))
            for _, pauli in self._paulis:
                inst = instructions.get(pauli.to_label(), None)
                if inst is not None:
                    circuit = wave_function.copy(name=circuit_name_prefix + pauli.to_label())
                    circuit.append(inst, qr)
                    circuits.append(circuit)
        else:
            base_circuit = wave_function.copy()
            if cr is not None:
                if not base_circuit.has_register(cr):
                    base_circuit.add_register(cr)
            else:
                cr = find_regs_by_name(base_circuit, 'c', qreg=False)
                if cr is None:
                    cr = ClassicalRegister(n_qubits, name='c')
                    base_circuit.add_register(cr)

            for basis, _ in self._basis:
                circuit = base_circuit.copy(name=circuit_name_prefix + basis.to_label())
                circuit.append(instructions[basis.to_label()], qargs=qr, cargs=cr)
                circuits.append(circuit)

        return circuits