예제 #1
0
def reconstruct_multi_energy_expression(self, operator, op_list = None, tree = None):
		"""
			returns:
			ham_list: list of nonzero weighted pauli operators. is (typically) an exponentially (with ansatz length)
						sized list of separate terms. When measured and multiplied by sines and cosines, it can be used to evaluate the energy
			nonzero_term list: used to keep track of when terms in the ham_list correspond to which term in the overall energy expression, as empty
								or zero terms are not included in the ham_list.
		"""
		#can we take nonzero terms to tree list?
		ham = split_into_paulis(operator)
		term_list = [[ham, 1]]
		for num, op in enumerate(op_list):
			args = [op, num, self.zero_term]
			meta_term_list = parallel_map(create_new_term_list, term_list, args)
			new_term_list = []
			for term in meta_term_list:
				new_term_list = new_term_list + term
			if tree is not None:
				for term in new_term_list:
					i = 0
					if term[1] == 3*(term_list[i] - 1) + 1:
						tree[num + 1].append(0)
						i = i + 1
					if term[1] == 3*(term_list[i] - 1) + 2:
						tree[num + 1] = tree[num + 1] + [1,2]
						i = i+2

		if tree is not None:
			ham_list = parallel_map(return_first_entry, ham_list)
			return ham_list, tree
		else:
			return ham_list, nonzero_terms
예제 #2
0
 def get_next_op_param(self, result):
     """
     	method: get_energy_param_lists
     	args:
     		result- the data for the recently calculated result
     	returns:
     		dict with number of energy evaluations required, array of optimized energies for each operator in pool,
     		 array of optimized parameters for the energy values in energy array
     """
     if self.parameters_per_step == 1:
         args = tuple()
         kwargs = {'hp': self.ham_list, 'he': result['expec list']}
         Ha_list = list(parallel_map(get_Ha, self._operator_pool.pool, task_kwargs = kwargs, num_processes = len(psutil.Process().cpu_affinity())))
         Hc_list = list(parallel_map(get_Hc, self._operator_pool.pool, task_kwargs = kwargs, num_processes = len(psutil.Process().cpu_affinity())))
         grads, evals = multi_circuit_eval(
                         result['current_circuit'], 
                         self.commutators, 
                         qi=self.quantum_instance, 
                         drop_dups=self._drop_duplicate_circuits
                         )
         #ziplist = list(zip(Hc_list, Ha_list, grads))
         ziplist = list(zip(Hc_list, Ha_list, grads))
         energy_array = list(parallel_map(get_optimal_array, ziplist, num_processes = len(psutil.Process().cpu_affinity())))
         optimal_energy_index = np.argmin(energy_array)
         #optimal_energy_index = np.where(np.array(energy_array) == np.array(energy_array).min())
         #optimal_energy_index = optimal_energy_index[0]
         #print(optimal_energy_index)
         #if len(optimal_energy_index) > 1:
         #    entry = np.random.randint(0,len(optimal_energy_index) - 1)
         #    optimal_energy_index = optimal_energy_index[entry]
         #else:
         #    optimal_energy_index = optimal_energy_index[0]
         optimal_op = self._operator_pool.pool[optimal_energy_index]
         optimal_param = -np.arctan2(np.real(Ha_list[optimal_energy_index]),2*np.real(grads[optimal_energy_index][0]))
         return evals, optimal_op, optimal_param
    def mapping(self, map_type, threshold=0.00000001, idx=[None] * 4):
        self._map_type = map_type
        n = self._modes  # number of fermionic modes / qubits
        map_type = map_type.lower()
        if map_type == 'jordan_wigner':
            a_list = self._jordan_wigner_mode(n)
        elif map_type == 'parity':
            a_list = self._parity_mode(n)
        elif map_type == 'bravyi_kitaev':
            a_list = self._bravyi_kitaev_mode(n)
        elif map_type == 'bksf':
            return bksf_mapping(self)
        else:
            raise QiskitChemistryError(
                'Please specify the supported modes: '
                'jordan_wigner, parity, bravyi_kitaev, bksf')

        pauli_list = WeightedPauliOperator(paulis=[])

        for m, h in enumerate(self._hs):
            if (h is not None):
                if (idx[m] is None):
                    results = parallel_map(
                        FermionicOperatorNBody._n_body_mapping, [
                            FermionicOperatorNBody._prep_mapping(
                                h[indexes], a_list, indexes)
                            for indexes in list(
                                itertools.product(range(n),
                                                  repeat=len(h.shape)))
                            if h[indexes] != 0
                        ],
                        num_processes=aqua_globals.num_processes)
                else:
                    results = parallel_map(
                        FermionicOperatorNBody._n_body_mapping, [
                            FermionicOperatorNBody._prep_mapping(
                                h[indexes], a_list, indexes)
                            for indexes in idx[m]
                            if np.abs(h[indexes]) > threshold
                        ],
                        num_processes=aqua_globals.num_processes)
                for result in results:
                    pauli_list += result

        pauli_list.chop(threshold=threshold)

        if self._ph_trans_shift is not None:
            pauli_term = [
                self._ph_trans_shift,
                Pauli.from_label('I' * self._modes)
            ]
            pauli_list += WeightedPauliOperator(paulis=[pauli_term])

        return pauli_list
예제 #4
0
    def calculateEnergy(self, transpiledCircuit):

        if self.useNoiseModel == True:

            p_reset = 0.003
            p_meas = 0.01
            p_gate1 = 0.05

            # QuantumError objects
            error_reset = pauli_error([('X', p_reset), ('I', 1 - p_reset)])
            error_meas = pauli_error([('X', p_meas), ('I', 1 - p_meas)])
            error_gate1 = pauli_error([('X', p_gate1), ('I', 1 - p_gate1)])
            error_gate2 = error_gate1.tensor(error_gate1)

            noise_bit_flip = NoiseModel()
            noise_bit_flip.add_all_qubit_quantum_error(error_reset, "reset")
            noise_bit_flip.add_all_qubit_quantum_error(error_meas, "measure")
            noise_bit_flip.add_all_qubit_quantum_error(error_gate1, ["u1", "u2", "u3"])
            noise_bit_flip.add_all_qubit_quantum_error(error_gate2, ["cx"])

            simulator = QasmSimulator()

            job = execute(transpiledCircuit, backend=simulator, basis_gates=noise_bit_flip.basis_gates, noise_model=noise_bit_flip)
            results = job.result()
            counts = results.get_counts()

            _paulis, sgift = get_pauliList(self.ising, self.qubits)
            _basis = [(pauli[1], [i]) for i, pauli in enumerate(_paulis)]

            num_shots = sum(list(results.get_counts().values()))
            results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var,
                                   [([_paulis[idx] for idx in indices],
                                     results.get_counts())
                                    for basis, indices in _basis],
                                   num_processes=aqua_globals.num_processes)
            return results[0][0]

        else:
            _paulis, sgift = get_pauliList(self.ising, self.qubits)
            _basis = [(pauli[1], [i]) for i, pauli in enumerate(_paulis)]

            job = execute(transpiledCircuit, backend=self.backend)
            results = job.result()
            counts = results.get_counts()

            num_shots = sum(list(results.get_counts().values()))
            results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var,
                                   [([_paulis[idx] for idx in indices],
                                     results.get_counts())
                                    for basis, indices in _basis],
                                   num_processes=aqua_globals.num_processes)

            return results[0][0]
def multi_circuit_eval(circuit: QuantumCircuit,
                       op_list: List[BaseOperator],
                       qi: QuantumInstance,
                       drop_dups: bool = True):
    num_processes = 8
    kwargs = {'statevector_mode': qi.is_statevector}
    logger.info('Constructing evaluation circuits...')
    start = time.time()
    print('about to get eval circs')
    total_evaluation_circuits = list(
        parallel_map(_circ_eval,
                     op_list,
                     task_kwargs={
                         **kwargs, 'wave_function': circuit
                     },
                     num_processes=num_processes))
    total_evaluation_circuits = [
        item for sublist in total_evaluation_circuits for item in sublist
    ]
    logger.info('Removing duplicate circuits')
    start = time.time()
    print('about to drop dups')
    if drop_dups:
        final_circs = []
        for circ in total_evaluation_circuits:
            if not fast_circuit_inclusion(circ, final_circs):
                final_circs.append(circ)
        logger.info('Finished removing duplicate circuits')
    else:
        final_circs = deepcopy(total_evaluation_circuits)
    del total_evaluation_circuits
    evals = len(final_circs)  #will added
    logger.debug('Executing {} circuits for evaluation...'.format(
        len(final_circs)))
    start = time.time()
    #print('about to execute multi circuit evals')
    result = qi.execute(final_circs)
    #print('finished executing multi circuit evals')
    logger.debug('Computing {} expectations...'.format(len(op_list)))
    start = time.time()
    print('about to compute expecs')
    exp_vals = list(
        parallel_map(_compute_grad,
                     op_list,
                     task_kwargs={
                         **kwargs, 'result': result
                     },
                     num_processes=num_processes))
    logger.debug('Computed expectations: {}'.format(exp_vals))
    return exp_vals, evals  #will added
    def construct_circuits(data_to_predict,
                           training_data) -> qk.QuantumCircuit:
        """Constructs all quantum circuits for each datum to classify.

        Args:
            data_to_predict (array): data points, 2-D array, of shape
                ``(N, D)``, where ``N`` is the number of data points and ``D``
                is the dimensionality of the vector. ``D`` should coincide with
                the provided training data.
            training_data (array): data points which you want to know
                the distance of between :py:attr:`data_to_predict`.

        Returns:
            numpy.ndarray: The constructed circuits.

        Raises:
            AquaError: Quantum instance is not present.

        """
        measurement = True  # can be adjusted if statevector_sim
        oracle = qc.create_oracle(training_data)

        # parallel_map() creates QuantumCircuits in parallel to be executed by
        #  a QuantumInstance
        logger.info("Starting parallel map for constructing circuits.")
        circuits = qktools.parallel_map(
            QKNeighborsClassifier.construct_circuit,
            data_to_predict,
            task_args=[oracle, measurement])
        logger.info("Done.")

        return circuits
예제 #7
0
        def _build_one_sector(available_hopping_ops, untapered_op,
                              z2_symmetries):

            to_be_computed_list = []
            for idx, _ in enumerate(mus):
                m_u = mus[idx]
                n_u = nus[idx]
                left_op = available_hopping_ops.get('E_{}'.format(m_u))
                right_op_1 = available_hopping_ops.get('E_{}'.format(n_u))
                right_op_2 = available_hopping_ops.get('Edag_{}'.format(n_u))
                to_be_computed_list.append(
                    (m_u, n_u, left_op, right_op_1, right_op_2))

            if logger.isEnabledFor(logging.INFO):
                logger.info("Building all commutators:")
                TextProgressBar(sys.stderr)
            results = parallel_map(
                self._build_commutator_routine,
                to_be_computed_list,
                task_args=(untapered_op, z2_symmetries),
                num_processes=algorithm_globals.num_processes)
            for result in results:
                m_u, n_u, q_mat_op, w_mat_op, m_mat_op, v_mat_op = result

                if q_mat_op is not None:
                    all_matrix_operators['q_{}_{}'.format(m_u, n_u)] = q_mat_op
                if w_mat_op is not None:
                    all_matrix_operators['w_{}_{}'.format(m_u, n_u)] = w_mat_op
                if m_mat_op is not None:
                    all_matrix_operators['m_{}_{}'.format(m_u, n_u)] = m_mat_op
                if v_mat_op is not None:
                    all_matrix_operators['v_{}_{}'.format(m_u, n_u)] = v_mat_op
예제 #8
0
    def _build_hopping_operators(self):
        if logger.isEnabledFor(logging.DEBUG):
            TextProgressBar(sys.stderr)

        results = parallel_map(
            UCCSD._build_hopping_operator,
            self._single_excitations + self._double_excitations,
            task_args=(self._num_orbitals, self._num_particles,
                       self._qubit_mapping, self._two_qubit_reduction,
                       self._z2_symmetries, self._skip_commute_test),
            num_processes=aqua_globals.num_processes)
        hopping_ops = []
        s_e_list = []
        d_e_list = []
        for op, index in results:
            if op is not None and not op.is_empty():
                hopping_ops.append(op)
                if len(index) == 2:  # for double excitation
                    s_e_list.append(index)
                else:  # for double excitation
                    d_e_list.append(index)

        self._single_excitations = s_e_list
        self._double_excitations = d_e_list

        num_parameters = len(hopping_ops) * self._depth
        return hopping_ops, num_parameters
예제 #9
0
    def construct_circuit(
            self,
            parameters: Union[np.ndarray, List[Parameter], ParameterVector],
            q: Optional[QuantumRegister] = None) -> QuantumCircuit:
        """Construct the variational form, given its parameters.

        Args:
            parameters: circuit parameters
            q: Quantum Register for the circuit.

        Returns:
            Quantum Circuit a quantum circuit with given `parameters`

        Raises:
            ValueError: the number of parameters is incorrect.
            ValueError: if num_qubits has not been set and is still None
        """

        if len(parameters) != self._num_parameters:
            raise ValueError('The number of parameters has to be {}'.format(
                self._num_parameters))

        if self._num_qubits is None:
            raise ValueError(
                'The number of qubits is None and must be set before the circuit '
                'can be created.')

        if q is None:
            q = QuantumRegister(self._num_qubits, name='q')

        if isinstance(self._initial_state, QuantumCircuit):
            circuit = QuantumCircuit(q)
            circuit.append(self._initial_state.to_gate(),
                           range(self._initial_state.num_qubits))
        elif self._initial_state is not None:
            circuit = self._initial_state.construct_circuit('circuit', q)
        else:
            circuit = QuantumCircuit(q)

        if logger.isEnabledFor(
                logging.DEBUG) and self._logging_construct_circuit:
            logger.debug("Evolving hopping operators:")
            TextProgressBar(sys.stderr)
            self._logging_construct_circuit = False

        num_excitations = len(self._hopping_ops)

        results = parallel_map(
            UVCC._construct_circuit_for_one_excited_operator,
            [(self._hopping_ops[index % num_excitations], parameters[index])
             for index in range(self._reps * num_excitations)],
            task_args=(q, self._num_time_slices),
            num_processes=aqua_globals.num_processes)
        for qc in results:
            if self._shallow_circuit_concat:
                circuit.data += qc.data
            else:
                circuit += qc

        return circuit
예제 #10
0
        def _build_one_sector(available_hopping_ops):

            to_be_computed_list = []
            for idx, _ in enumerate(mus):
                m_u = mus[idx]
                n_u = nus[idx]
                left_op = available_hopping_ops.get(
                    '_'.join([str(x) for x in excitations_list[m_u]]), None)
                right_op_1 = available_hopping_ops.get(
                    '_'.join([str(x) for x in excitations_list[n_u]]), None)
                right_op_2 = available_hopping_ops.get(
                    '_'.join([str(x) for x in reversed(excitations_list[n_u])]), None)
                to_be_computed_list.append((m_u, n_u, left_op, right_op_1, right_op_2))

            if logger.isEnabledFor(logging.INFO):
                logger.info("Building all commutators:")
                TextProgressBar(sys.stderr)
            results = parallel_map(QEquationOfMotion._build_commutator_rountine,
                                   to_be_computed_list,
                                   task_args=(self._untapered_op, self._z2_symmetries))
            for result in results:
                m_u, n_u, q_mat_op, w_mat_op, m_mat_op, v_mat_op = result
                q_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    q_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \
                    if q_mat_op is not None else q_commutators[m_u][n_u]
                w_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    w_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \
                    if w_mat_op is not None else w_commutators[m_u][n_u]
                m_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    m_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \
                    if m_mat_op is not None else m_commutators[m_u][n_u]
                v_commutators[m_u][n_u] = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    v_mat_op, TPBGroupedWeightedPauliOperator.sorted_grouping) \
                    if v_mat_op is not None else v_commutators[m_u][n_u]
    def _hessian(self, circuit: QuantumCircuit):
        kwargs = {'statevector_mode': self.quantum_instance.is_statevector}
        logger.info('Constructing evaluation circuits for Hessian...')
        dcoms = self.double_commutators.flatten().tolist()
        total_evaluation_circuits = list(
            parallel_map(_circ_eval,
                         dcoms,
                         task_kwargs={
                             **kwargs, 'wave_function': circuit
                         },
                         num_processes=len(psutil.Process().cpu_affinity())))
        total_evaluation_circuits = [
            item for sublist in total_evaluation_circuits for item in sublist
        ]
        logger.info('Removing duplicate circuits')
        if self._drop_duplicate_circuits:
            final_circs = []
            for circ in total_evaluation_circuits:
                if not fast_circuit_inclusion(circ, final_circs):
                    final_circs.append(circ)
            logger.info('Finished removing duplicate circuits')
        else:
            final_circs = total_evaluation_circuits
        logger.debug('Executing {} circuits for Hessian evaluation...'.format(
            len(final_circs)))
        result = self.quantum_instance.execute(final_circs)
        logger.debug('Computing Hessian...')

        n_ops = len(self._operator_pool.pool)
        hess = np.zeros((n_ops, n_ops))
        for i, j in product(range(n_ops), repeat=2):
            hess[i, j], _ = self.double_commutators[i, j].evaluate_with_result(
                result=result, **kwargs)
        logger.debug('Computed Hessian')
        return hess
예제 #12
0
    def test_binding_parameterized_circuits_built_in_multiproc(self):
        """Verify subcircuits built in a subprocess can still be bound."""
        # ref: https://github.com/Qiskit/qiskit-terra/issues/2429

        num_processes = 4

        qr = QuantumRegister(3)
        cr = ClassicalRegister(3)

        circuit = QuantumCircuit(qr, cr)
        parameters = [Parameter('x{}'.format(i)) for i in range(num_processes)]

        results = parallel_map(_construct_circuit,
                               parameters,
                               task_args=(qr, ),
                               num_processes=num_processes)

        for qc in results:
            circuit += qc

        parameter_values = [{x: 1 for x in parameters}]

        qobj = assemble(circuit,
                        backend=BasicAer.get_backend('qasm_simulator'),
                        parameter_binds=parameter_values)

        self.assertEqual(len(qobj.experiments), 1)
        self.assertEqual(len(qobj.experiments[0].instructions), 4)
        self.assertTrue(
            all(
                len(inst.params) == 1
                and isinstance(inst.params[0], ParameterExpression)
                and float(inst.params[0]) == 1
                for inst in qobj.experiments[0].instructions))
예제 #13
0
    def evaluate_with_result(self, result, statevector_mode, use_simulator_operator_mode=False,
                             circuit_name_prefix=''):
        """
        This method can be only used with the circuits generated by the
        `construct_evaluation_circuit` method with the same `circuit_name_prefix`
        since the circuit names are tied to some meanings.

        Calculate the evaluated value with the measurement results.

        Args:
            result (qiskit.Result): the result from the backend.
            statevector_mode (bool): indicate which type of simulator are used.
            use_simulator_operator_mode (bool): if aer_provider is used, we can do faster
                           evaluation for pauli mode on statevector simulation
            circuit_name_prefix (str): a prefix of circuit name

        Returns:
            float: the mean value
            float: the standard deviation

        Raises:
            AquaError: if Operator is empty
        """
        if self.is_empty():
            raise AquaError("Operator is empty, check the operator.")

        avg, std_dev, variance = 0.0, 0.0, 0.0
        if statevector_mode:
            if use_simulator_operator_mode:
                temp = \
                    result.data(
                        circuit_name_prefix + 'aer_mode')[
                            'snapshots']['expectation_value']['test'][0]['value']
                avg = temp[0] + 1j * temp[1]
            else:
                quantum_state = np.asarray(result.get_statevector(circuit_name_prefix + 'psi'))
                for weight, pauli in self._paulis:
                    # all I
                    if np.all(np.logical_not(pauli.z)) and np.all(np.logical_not(pauli.x)):
                        avg += weight
                    else:
                        quantum_state_i = \
                            result.get_statevector(circuit_name_prefix + pauli.to_label())
                        avg += (weight * (np.vdot(quantum_state, quantum_state_i)))
        else:
            if logger.isEnabledFor(logging.DEBUG):
                logger.debug("Computing the expectation from measurement results:")
                TextProgressBar(sys.stderr)
            # pick the first result to get the total number of shots
            num_shots = sum(list(result.get_counts(0).values()))
            results = parallel_map(WeightedPauliOperator._routine_compute_mean_and_var,
                                   [([self._paulis[idx] for idx in indices],
                                     result.get_counts(circuit_name_prefix + basis.to_label()))
                                    for basis, indices in self._basis],
                                   num_processes=aqua_globals.num_processes)
            for res in results:
                avg += res[0]
                variance += res[1]
            std_dev = np.sqrt(variance / num_shots)
        return avg, std_dev
예제 #14
0
    def build_hopping_operators(self, excitations: Union[str, List[List[int]]] = 'sd'
                                ) -> Tuple[Dict[str, WeightedPauliOperator],
                                           Dict[str, List[bool]],
                                           Dict[str, List[Any]]]:
        """Builds the product of raising and lowering operators (basic excitation operators)

        Args:
            excitations: The excitations to be included in the eom pseudo-eigenvalue problem.
                If a string ('s', 'd' or 'sd') then all excitations of the given type will be used.
                Otherwise a list of custom excitations can directly be provided.

        Returns:
            A tuple containing the hopping operators, the types of commutativities and the
            excitation indices.
        """

        num_alpha, num_beta = self._molecule_info['num_particles']
        num_orbitals = self._molecule_info['num_orbitals']

        if isinstance(excitations, str):
            se_list, de_list = UCCSD.compute_excitation_lists([num_alpha, num_beta], num_orbitals,
                                                              excitation_type=excitations)
            excitations_list = se_list+de_list
        else:
            excitations_list = excitations

        size = len(excitations_list)

        # # get all to-be-processed index
        # mus, nus = np.triu_indices(size)

        # build all hopping operators
        hopping_operators: Dict[str, WeightedPauliOperator] = {}
        type_of_commutativities: Dict[str, List[bool]] = {}
        excitation_indices = {}
        to_be_executed_list = []
        for idx in range(size):
            to_be_executed_list += [excitations_list[idx], list(reversed(excitations_list[idx]))]
            hopping_operators['E_{}'.format(idx)] = None
            hopping_operators['Edag_{}'.format(idx)] = None
            type_of_commutativities['E_{}'.format(idx)] = None
            type_of_commutativities['Edag_{}'.format(idx)] = None
            excitation_indices['E_{}'.format(idx)] = excitations_list[idx]
            excitation_indices['Edag_{}'.format(idx)] = list(reversed(excitations_list[idx]))

        result = parallel_map(self._build_single_hopping_operator,
                              to_be_executed_list,
                              task_args=(num_alpha + num_beta,
                                         num_orbitals,
                                         self._qubit_mapping,
                                         self._two_qubit_reduction,
                                         self._molecule_info['z2_symmetries']),
                              num_processes=aqua_globals.num_processes)

        for key, res in zip(hopping_operators.keys(), result):
            hopping_operators[key] = res[0]
            type_of_commutativities[key] = res[1]

        return hopping_operators, type_of_commutativities, excitation_indices
예제 #15
0
def reconstruct_single_energy_expression(self, op, ham = None, zero_term):
		"""
			H_c: a weighted pauli operator of the terms in the passed hamiltonian that commute with the passed operator
			H_a: a weighted pauli operator of the terms in the passed hamiltonian that anticommute with the passed operator
			comm: a weighted pauli operator of the commutator [H_a, op]
		"""
		kwargs = {'op_2': op}
		args = []
		H_c = parallel_map(commute_yes, ham, args, kwargs)
		H_a = parallel_map(commute_no, ham, args, kwargs)
		comm = parallel_map(find_commutator,H_a,args,kwargs)

		if not H_c:
			H_c.append(zero_term)
		if not H_a:
			H_a.append(zero_term)
		return H_c, H_a, comm
예제 #16
0
def build_vibrational_ops(
    num_modals: List[int],
    qubit_converter: QubitConverter,
    excitations: str
    | int
    | list[int]
    | Callable[[int, tuple[int, int]], list[tuple[tuple[int, ...],
                                                  tuple[int, ...]]], ] = "sd",
) -> Tuple[Dict[str, PauliSumOp], Dict[str, List[bool]], Dict[str, Tuple[Tuple[
        int, ...], Tuple[int, ...]]], ]:
    """
    Args:
        num_modals: the number of modals per mode.
        qubit_converter: the `QubitConverter` to use for mapping and symmetry reduction. The Z2
                         symmetries stored in this instance are the basis for the commutativity
                         information returned by this method.
        excitations: the types of excitations to consider. The simple cases for this input are:
            - a `str` containing any of the following characters: `s`, `d`, `t` or `q`.
            - a single, positive `int` denoting the excitation type (1 == `s`, etc.).
            - a list of positive integers.
            - and finally a callable which can be used to specify a custom list of excitations.
              For more details on how to write such a function refer to the default method,
              :meth:`generate_vibrational_excitations`.
    Returns:
        Dict of hopping operators, dict of commutativity types and dict of excitation indices
    """

    ansatz = UVCC(qubit_converter, num_modals, excitations)
    excitations_list = ansatz._get_excitation_list()
    size = len(excitations_list)

    hopping_operators: Dict[str, PauliSumOp] = {}
    excitation_indices: Dict[str, Tuple[Tuple[int, ...], Tuple[int, ...]]] = {}
    to_be_executed_list = []
    for idx in range(size):
        to_be_executed_list += [
            excitations_list[idx], excitations_list[idx][::-1]
        ]
        hopping_operators[f"E_{idx}"] = None
        hopping_operators[f"Edag_{idx}"] = None
        excitation_indices[f"E_{idx}"] = excitations_list[idx]
        excitation_indices[f"Edag_{idx}"] = excitations_list[idx][::-1]

    result = parallel_map(
        _build_single_hopping_operator,
        to_be_executed_list,
        task_args=(num_modals, qubit_converter),
        num_processes=algorithm_globals.num_processes,
    )

    for key, res in zip(hopping_operators.keys(), result):
        hopping_operators[key] = res

    # This variable is required for compatibility with the ElectronicStructureProblem
    # at the moment we do not have any type of commutativity in the bosonic case.
    type_of_commutativities: Dict[str, List[bool]] = {}

    return hopping_operators, type_of_commutativities, excitation_indices
예제 #17
0
    def build_hopping_operators(self, excitations: Union[str, List[List[int]]] = 'sd') \
            -> Tuple[Dict[str, WeightedPauliOperator],
                     Dict,
                     Dict[str, List[List[int]]]]:
        """
        Args:
            excitations:

        Returns:
            Dict of hopping operators, dict of commutativity types and dict of excitation indices
        """
        exctn_types = {'s': 0, 'd': 1}

        if isinstance(excitations, str):
            degrees = [exctn_types[letter] for letter in excitations]
            excitations_list = UVCC.compute_excitation_lists(
                self._basis_size, degrees)
        else:
            excitations_list = excitations

        size = len(excitations_list)

        def _dag_list(extn_lst):
            dag_lst = []
            for lst in extn_lst:
                dag_lst.append([lst[0], lst[2], lst[1]])
            return dag_lst

        hopping_operators: Dict[str, WeightedPauliOperator] = {}
        excitation_indices = {}
        to_be_executed_list = []
        for idx in range(size):
            to_be_executed_list += [
                excitations_list[idx],
                _dag_list(excitations_list[idx])
            ]
            hopping_operators['E_{}'.format(idx)] = None
            hopping_operators['Edag_{}'.format(idx)] = None
            excitation_indices['E_{}'.format(idx)] = excitations_list[idx]
            excitation_indices['Edag_{}'.format(idx)] = _dag_list(
                excitations_list[idx])

        result = parallel_map(self._build_single_hopping_operator,
                              to_be_executed_list,
                              task_args=(self._basis_size,
                                         self._qubit_mapping),
                              num_processes=aqua_globals.num_processes)

        for key, res in zip(hopping_operators.keys(), result):
            hopping_operators[key] = res

        # This variable is required for compatibility with the FermionicTransformation
        # at the moment we do not have any type of commutativity in the bosonic case.
        type_of_commutativities: Dict[str, List[bool]] = {}

        return hopping_operators, type_of_commutativities, excitation_indices
def split_into_paulis(ham):
    args = [ham.num_qubits]
    ham_list = ham.paulis
    separated_ham_list = list(
        parallel_map(convert_to_wpauli_list,
                     ham_list,
                     args,
                     num_processes=len(psutil.Process().cpu_affinity())))

    return separated_ham_list
    def mapping(self, map_type, threshold=0.00000001):

        self._map_type = map_type
        n = self._modes  # number of fermionic modes / qubits
        map_type = map_type.lower()
        if map_type == 'jordan_wigner':
            a_list = self._jordan_wigner_mode(n)
        elif map_type == 'parity':
            a_list = self._parity_mode(n)
        elif map_type == 'bravyi_kitaev':
            a_list = self._bravyi_kitaev_mode(n)
        elif map_type == 'bksf':
            return bksf_mapping(self)
        else:
            raise QiskitChemistryError('Please specify the supported modes: '
                                       'jordan_wigner, parity, bravyi_kitaev, bksf')

        pauli_list = WeightedPauliOperator(paulis=[])

        for h in self._hs:
            if(h is not None):
               results = parallel_map(FermionicOperatorNBody._n_body_mapping,
                                      [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes)
                                       for indexes in list(itertools.product(range(n), repeat=len(h.shape)))
                                       if h[indexes] != 0], num_processes=aqua_globals.num_processes)
               for result in results:
                   pauli_list += result

        '''
        for h in self._hs:
            if h is not None:
               indexes_list = np.argwhere(np.abs(h)>threshold)
               print(h.shape,len(indexes_list))
               for indexes in indexes_list:
                   h_a = [h[tuple(indexes)]]
                   for i in indexes:
                       h_a.append(a_list[i])
                   pauli_list += FermionicOperatorNBody._n_body_mapping(h_a)

        for h in self._hs:
            if(h is not None):
               results = parallel_map(FermionicOperatorNBody._n_body_mapping,
                                      [FermionicOperatorNBody._prep_mapping(h[indexes],a_list,indexes)
                                       for indexes in np.argwhere(np.abs(h)>threshold)], num_processes=aqua_globals.num_processes)
               for result in results:
                   pauli_list += result
        ''' 

        pauli_list.chop(threshold=threshold)

        if self._ph_trans_shift is not None:
            pauli_term = [self._ph_trans_shift, Pauli.from_label('I' * self._modes)]
            pauli_list += WeightedPauliOperator(paulis=[pauli_term])

        return pauli_list
예제 #20
0
    def build_hopping_operators(self, excitations_list):
        """Building all hopping operators defined in excitation list.

        Args:
            excitations_list (list): single excitations list + double excitation list

        Returns:
            dict: all hopping operators based on excitations_list, key is the string of single/double excitation;
                  value is corresponding operator.
        """
        size = len(excitations_list)

        # NOTE: build pairs of excitation operators (mu,nu of EOM!)

        # get all to-be-processed index
        if self._is_eom_matrix_symmetric:
            mus, nus = np.triu_indices(size)
        else:
            mus, nus = np.indices((size, size))
            mus = np.asarray(mus.flat)
            nus = np.asarray(nus.flat)

        # build all hopping operators
        hopping_operators = {}
        type_of_commutativities = {}
        to_be_executed_list = []
        for idx in range(len(mus)):
            mu = mus[idx]
            nu = nus[idx]
            for excitations in [
                    excitations_list[mu], excitations_list[nu],
                    list(reversed(excitations_list[nu]))
            ]:
                key = '_'.join([str(x) for x in excitations])
                if key not in hopping_operators:
                    to_be_executed_list.append(excitations)
                    hopping_operators[key] = None
                    type_of_commutativities[key] = None

        # NOTE just a wrapper to this
        result = parallel_map(
            QEquationOfMotion._build_single_hopping_operator,
            to_be_executed_list,
            task_args=(self._num_particles, self._num_orbitals,
                       self._qubit_mapping, self._two_qubit_reduction,
                       self._z2_symmetries),
            num_processes=aqua_globals.num_processes)

        for excitations, res in zip(to_be_executed_list, result):
            key = '_'.join([str(x) for x in excitations])
            hopping_operators[key] = res[0]
            type_of_commutativities[key] = res[1]

        return hopping_operators, type_of_commutativities
예제 #21
0
    def _build_hopping_operators(self):
        if logger.isEnabledFor(logging.DEBUG):
            TextProgressBar(sys.stderr)

        results = parallel_map(UVCC._build_hopping_operator, self._excitations,
                               task_args=(self._basis, 'direct'),
                               num_processes=algorithm_globals.num_processes)
        hopping_ops = [qubit_op for qubit_op in results if qubit_op is not None]
        num_parameters = len(hopping_ops) * self._reps

        return hopping_ops, num_parameters
예제 #22
0
def split_into_paulis(ham):
	"""
		Used to split the given hamiltonian into lists of constituent parts:
		weight_list: list of complex floats that are the weights of terms in the hamiltonian
		pauli_list: a list of the Weighted_pauli_operator representations of the pauli strings in the hamiltonian
					(does not include weights)
		name_list: a list of strings that correspond to the names of the operators in the hamiltonian
	"""
	ham_list = ham.paulis
	separated_ham_list = parallel_map(convert_to_wpauli_list, ham_list, args, num_processes = aqua_globals.num_processes)

	return separated_ham_list
예제 #23
0
 def _measure_energies(self, wavefunc, *current_ops):
     """
     method: measure_energies
            finds the meausred energy for each new operator at pi/2 and -pi/2
     args: 
        circuit - the current optimal circuit
        current_ops - the current optimal operators
     returns:
        dictionary with: evaluation energy lists with parameter values at pi/2 and -pi/2
     """
     #measure energies (theta = 0, theta = pi/4, theta = -pi/4)
     args = []
     kwargs = {
         'ham': self._hamiltonian,
         'energy_step_tol': self.energy_tol,
         'parameter': np.pi / 4
     }
     op_list_pi4 = list(
         parallel_map(Generate_roto_op, self._operator_pool.pool, args,
                      kwargs, aqua_globals.num_processes))
     kwargs['parameter'] = -np.pi / 4
     op_list_negpi4 = list(
         parallel_map(Generate_roto_op, self._operator_pool.pool, args,
                      kwargs, aqua_globals.num_processes))
     op_list = op_list_pi4 + op_list_negpi4
     del op_list_pi4
     del op_list_negpi4
     E_list, evals = np.real(
         multi_circuit_eval(wavefunc, op_list, self.quantum_instance,
                            self._drop_duplicate_circuits))
     del op_list
     E_list, E_list_std = list(zip(*E_list))
     cutoff = int(len(E_list) / 2)
     Energy_pi4 = np.array(E_list[0:cutoff])
     Energy_negpi4 = np.array(E_list[cutoff:])
     return {
         'energy pi4': Energy_pi4,
         'energy negpi4': Energy_negpi4,
         'num evals': evals
     }
예제 #24
0
    def _build_hopping_operators(self):
        if logger.isEnabledFor(logging.DEBUG):
            TextProgressBar(sys.stderr)

        results = parallel_map(UCCSD._build_hopping_operator,
                               self._single_excitations + self._double_excitations,
                               task_args=(self._num_orbitals,
                                          self._num_particles, self._qubit_mapping,
                                          self._two_qubit_reduction, self._z2_symmetries),
                               num_processes=aqua_globals.num_processes)
        hopping_ops = [qubit_op for qubit_op in results if qubit_op is not None]
        num_parameters = len(hopping_ops) * self._depth
        return hopping_ops, num_parameters
예제 #25
0
def print_UCCSD_parameters(molecule, core, var_form, algo_result, z2syms,
                           sqlist, deleted_orbitals, outfile):
    sd, dd = UCCSD.compute_excitation_lists(
        [var_form._num_alpha, var_form._num_beta],
        var_form._num_orbitals,
        None,
        None,
        same_spin_doubles=var_form.same_spin_doubles,
        method_singles=var_form._method_singles,
        method_doubles=var_form._method_doubles,
        excitation_type=var_form._excitation_type)

    kept_orbitals = [
        x for x in range(molecule.num_orbitals) if x not in deleted_orbitals
    ]

    ed = sd + dd
    results = parallel_map(UCCSD._build_hopping_operator,
                           ed,
                           task_args=(var_form._num_orbitals, [
                               var_form._num_alpha, var_form._num_beta
                           ], core._qubit_mapping, core._two_qubit_reduction,
                                      z2syms),
                           num_processes=aqua_globals.num_processes)

    def convert_index(idx):
        idx_converted = []
        for i in idx:
            if (i < len(kept_orbitals)):
                idx_converted.append(str(kept_orbitals[i]) + 'u')
            else:
                idx_converted.append(
                    str(kept_orbitals[i - len(kept_orbitals)]) + 'd')
        return idx_converted

    t = PrettyTable(['excitation', 'amplitude'])
    lst = []
    im = 0
    for m, (op, index) in enumerate(results):
        if op is not None and not op.is_empty():
            lst.append(
                [convert_index(index), algo_result['optimal_point'][im]])
            im += 1
    for i in range(len(lst)):
        for j in range(i + 1, len(lst)):
            if (np.abs(lst[j][1]) > np.abs(lst[i][1])):
                lst[i], lst[j] = lst[j], lst[i]
        t.add_row([str(lst[i][0])] + [str(lst[i][1])])
    outfile.write(str(t))
    outfile.write("\n")
예제 #26
0
def split_into_paulis_minus_weight(ham):
    """
        Used to split the given hamiltonian into lists of constituent parts:
        weight_list: list of complex floats that are the weights of terms in the hamiltonian
        pauli_list: a list of the Weighted_pauli_operator representations of the pauli strings in the hamiltonian
                    (does not include weights)
        name_list: a list of strings that correspond to the names of the operators in the hamiltonian
    """
    args = [ham.num_qubits]
    ham_list = ham.paulis
    separated_ham_list = parallel_map(convert_to_wpauli_list,
                                      ham_list,
                                      args,
                                      num_processes=len(
                                          psutil.Process().cpu_affinity()))

    return separated_ham_list
예제 #27
0
    def construct_circuit(self, parameters, q=None):
        """
        Construct the variational form, given its parameters.

        Args:
            parameters (numpy.ndarray): circuit parameters
            q (QuantumRegister): Quantum Register for the circuit.

        Returns:
            QuantumCircuit: a quantum circuit with given `parameters`

        Raises:
            ValueError: the number of parameters is incorrect.
        """
        from .uccsd import UCCSD
        if len(parameters) != self._num_parameters:
            raise ValueError('The number of parameters has to be {}'.format(
                self._num_parameters))

        if q is None:
            q = QuantumRegister(self._num_qubits, name='q')
        if self._initial_state is not None:
            circuit = self._initial_state.construct_circuit('circuit', q)
        else:
            circuit = QuantumCircuit(q)

        if logger.isEnabledFor(
                logging.DEBUG) and self._logging_construct_circuit:
            logger.debug("Evolving hopping operators:")
            TextProgressBar(sys.stderr)
            self._logging_construct_circuit = False

        num_excitations = len(self._hopping_ops)
        results = parallel_map(
            UCCSD._construct_circuit_for_one_excited_operator,
            [(self._hopping_ops[index % num_excitations], parameters[index])
             for index in range(self._depth * num_excitations)],
            task_args=(q, self._num_time_slices),
            num_processes=aqua_globals.num_processes)
        for qc in results:
            if self._shallow_circuit_concat:
                circuit.data += qc.data
            else:
                circuit += qc

        return circuit
예제 #28
0
    def _build_hopping_operators(self):
        from .uccsd import UCCSD
        hopping_ops = []

        if logger.isEnabledFor(logging.DEBUG):
            TextProgressBar(sys.stderr)

        results = parallel_map(
            UCCSD._build_hopping_operator,
            self._single_excitations + self._double_excitations,
            task_args=(self._num_orbitals, self._num_particles,
                       self._qubit_mapping, self._two_qubit_reduction,
                       self._qubit_tapering, self._symmetries, self._cliffords,
                       self._sq_list, self._tapering_values))
        hopping_ops = [
            qubit_op for qubit_op in results if qubit_op is not None
        ]
        num_parameters = len(hopping_ops) * self._depth
        return hopping_ops, num_parameters
예제 #29
0
	def _reconstruct_op_descendants(self, ham_term_list = None):
		"""

		"""
		if ham_term_list == None:
			ham_list= split_into_paulis(self._operator)
			for term in ham_list:
				ham_term_list.append({'term': term, 'descendants': [term], 'tree': []})
		if self.starting_point:
			op_list = self.op_list[-1]
		else:
			op_list = self.op_list
		for num, op in enumerate(op_list): #make sure op list in right direction
			print('num', num)
			if self.starting_point:
				prev_op_list = self.op_list[:-1]
			else:
				prev_op_list = self.op_list[:num]
				
			ham_term_list = parallel_map(sort_term, ham_term_list, num_processes = aqua_globals.num_processes)
		return ham_term_list
예제 #30
0
 def mapping_new(self, map_type, threshold=0.00000001):
     """Map fermionic operator to qubit operator.        Using multiprocess to speedup the mapping, the improvement can be
     observed when h2 is a non-sparse matrix.        Args:
         map_type (str): case-insensitive mapping type.
                         "jordan_wigner", "parity", "bravyi_kitaev", "bksf"
         threshold (float): threshold for Pauli simplification        Returns:
         WeightedPauliOperator: create an Operator object in Paulis form.        Raises:
         QiskitChemistryError: if the `map_type` can not be recognized.
     """        # ###################################################################
     # ###########   DEFINING MAPPED FERMIONIC OPERATORS    ##############
     # ###################################################################        self._map_type = map_type
     n = self._modes  # number of fermionic modes / qubits
     map_type = map_type.lower()
     if map_type == 'jordan_wigner':
         a_list = self._jordan_wigner_mode(n)
     elif map_type == 'parity':
         a_list = self._parity_mode(n)
     elif map_type == 'bravyi_kitaev':
         a_list = self._bravyi_kitaev_mode(n)
     elif map_type == 'bksf':
         return bksf_mapping(self)
     else:
         raise QiskitChemistryError('Please specify the supported modes: '
                                    'jordan_wigner, parity, bravyi_kitaev, bksf')        # ###################################################################
     # ###########    BUILDING THE MAPPED HAMILTONIAN     ################
     # ###################################################################        pauli_list = WeightedPauliOperator(paulis=[])
     if logger.isEnabledFor(logging.DEBUG):
         logger.debug("Mapping one-body terms to Qubit Hamiltonian:")
         TextProgressBar(output_handler=sys.stderr)
     results = parallel_map(FermionicOperator._n_body_mapping,
                            [(self._h1[i, j], a_list[i], a_list[j])
                             for i, j in itertools.product(range(n), repeat=2)
                             if self._h1[i, j] != 0],
                            task_args=(threshold,), num_processes=aqua_globals.num_processes)
     for result in results:
         pauli_list += result
     pauli_list.chop(threshold=threshold)        if logger.isEnabledFor(logging.DEBUG):
         logger.debug("Mapping two-body terms to Qubit Hamiltonian:")
         TextProgressBar(output_handler=sys.stderr)