示例#1
0
 def __init__(self,
              operator,
              initial_state,
              evo_operator,
              operator_mode=None,
              evo_time=1,
              num_time_slices=1,
              expansion_mode='trotter',
              expansion_order=1):
     self.validate(locals())
     super().__init__()
     if operator_mode is not None:
         warnings.warn(
             "operator_mode option is deprecated and it will be removed after 0.6. "
             "Now the operator has its own mode, no need extra info to tell the EOH.",
             DeprecationWarning)
     self._operator = op_converter.to_weighted_pauli_operator(operator)
     self._initial_state = initial_state
     self._evo_operator = op_converter.to_weighted_pauli_operator(
         evo_operator)
     self._evo_time = evo_time
     self._num_time_slices = num_time_slices
     self._expansion_mode = expansion_mode
     self._expansion_order = expansion_order
     self._ret = {}
示例#2
0
 def __init__(self,
              operator: BaseOperator,
              initial_state: InitialState,
              evo_operator: BaseOperator,
              evo_time: float = 1,
              num_time_slices: int = 1,
              expansion_mode: str = 'trotter',
              expansion_order: int = 1) -> None:
     """
     Args:
         operator: Operator to evaluate
         initial_state: Initial state for evolution
         evo_operator: Operator to evolve
         evo_time: Evolution time, has min value of 0
         num_time_slices: Number of time slices, has minimum value of 1
         expansion_mode: Either ``"trotter"`` (Lloyd's method) or ``"suzuki"``
             (for Trotter-Suzuki expansion)
         expansion_order: The Trotter-Suzuki expansion order.
     """
     validate_min('evo_time', evo_time, 0)
     validate_min('num_time_slices', num_time_slices, 1)
     validate_in_set('expansion_mode', expansion_mode,
                     {'trotter', 'suzuki'})
     validate_min('expansion_order', expansion_order, 1)
     super().__init__()
     self._operator = op_converter.to_weighted_pauli_operator(operator)
     self._initial_state = initial_state
     self._evo_operator = op_converter.to_weighted_pauli_operator(
         evo_operator)
     self._evo_time = evo_time
     self._num_time_slices = num_time_slices
     self._expansion_mode = expansion_mode
     self._expansion_order = expansion_order
     self._ret = {}
示例#3
0
    def __init__(self, operator, var_form, optimizer, operator_mode=None,
                 initial_point=None, max_evals_grouped=1, aux_operators=None, callback=None,
                 auto_conversion=True):
        """Constructor.

        Args:
            operator (BaseOperator): Qubit operator
            operator_mode (str): operator mode, used for eval of operator
            var_form (VariationalForm): parametrized variational form.
            optimizer (Optimizer): the classical optimization algorithm.
            initial_point (numpy.ndarray): optimizer initial point.
            max_evals_grouped (int): max number of evaluations performed simultaneously
            aux_operators (list[BaseOperator]): Auxiliary operators to be evaluated at each eigenvalue
            callback (Callable): a callback that can access the intermediate data during the optimization.
                                 Internally, four arguments are provided as follows
                                 the index of evaluation, parameters of variational form,
                                 evaluated mean, evaluated standard devation.
            auto_conversion (bool): an automatic conversion for operator and aux_operators into the type which is
                                    most suitable for the backend.
                                    - non-aer statevector_simulator: MatrixOperator
                                    - aer statevector_simulator: WeightedPauliOperator
                                    - qasm simulator or real backend: TPBGroupedWeightedPauliOperator
        """
        if operator_mode is not None:
            warnings.warn("operator_mode option is deprecated and it will be removed after 0.6. "
                          "Now the operator has its own mode, no need extra info to tell the VQE.", DeprecationWarning)
        self.validate(locals())
        super().__init__(var_form=var_form,
                         optimizer=optimizer,
                         cost_fn=self._energy_evaluation,
                         initial_point=initial_point)
        self._optimizer.set_max_evals_grouped(max_evals_grouped)
        self._callback = callback
        if initial_point is None:
            self._initial_point = var_form.preferred_init_points
        if isinstance(operator, Operator):
            warnings.warn("operator should be type of BaseOperator, Operator type is deprecated and "
                          "it will be removed after 0.6.", DeprecationWarning)
            operator = op_converter.to_weighted_pauli_operator(operator)
        self._operator = operator
        self._eval_count = 0
        self._aux_operators = []
        if aux_operators is not None:
            aux_operators = [aux_operators] if not isinstance(aux_operators, list) else aux_operators
            for aux_op in aux_operators:
                if isinstance(aux_op, Operator):
                    warnings.warn("aux operator should be type of BaseOperator, Operator type is deprecated and "
                                  "it will be removed after 0.6.", DeprecationWarning)
                    aux_op = op_converter.to_weighted_pauli_operator(aux_op)
                self._aux_operators.append(aux_op)
        self._auto_conversion = auto_conversion
        logger.info(self.print_settings())
示例#4
0
    def __init__(self,
                 operator,
                 state_in,
                 num_time_slices=1,
                 num_iterations=1,
                 expansion_mode='suzuki',
                 expansion_order=2,
                 shallow_circuit_concat=False):
        """
        Constructor.

        Args:
            operator (BaseOperator): the hamiltonian Operator object
            state_in (InitialState): the InitialState pluggable component representing the initial quantum state
            num_time_slices (int): the number of time slices
            num_iterations (int): the number of iterations
            expansion_mode (str): the expansion mode (trotter|suzuki)
            expansion_order (int): the suzuki expansion order
            shallow_circuit_concat (bool): indicate whether to use shallow (cheap) mode for circuit concatenation
        """
        self.validate(locals())
        super().__init__()
        self._operator = op_converter.to_weighted_pauli_operator(operator)
        self._state_in = state_in
        self._num_time_slices = num_time_slices
        self._num_iterations = num_iterations
        self._expansion_mode = expansion_mode
        self._expansion_order = expansion_order
        self._shallow_circuit_concat = shallow_circuit_concat
        self._state_register = None
        self._ancillary_register = None
        self._pauli_list = None
        self._ret = {}
        self._setup()
示例#5
0
    def _setup(self, operator: Optional[BaseOperator]) -> None:
        self._operator = None
        self._ret = {}
        self._pauli_list = None
        self._phase_estimation_circuit = None
        if operator:
            self._operator = op_converter.to_weighted_pauli_operator(operator.copy())
            self._ret['translation'] = sum([abs(p[0]) for p in self._operator.reorder_paulis()])
            self._ret['stretch'] = 0.5 / self._ret['translation']

            # translate the operator
            self._operator.simplify()
            translation_op = WeightedPauliOperator([
                [
                    self._ret['translation'],
                    Pauli(
                        np.zeros(self._operator.num_qubits),
                        np.zeros(self._operator.num_qubits)
                    )
                ]
            ])
            translation_op.simplify()
            self._operator += translation_op
            self._pauli_list = self._operator.reorder_paulis()

            # stretch the operator
            for p in self._pauli_list:
                p[0] = p[0] * self._ret['stretch']

            self._phase_estimation_circuit = PhaseEstimationCircuit(
                operator=self._operator, state_in=self._state_in, iqft=self._iqft,
                num_time_slices=self._num_time_slices, num_ancillae=self._num_ancillae,
                expansion_mode=self._expansion_mode, expansion_order=self._expansion_order,
                shallow_circuit_concat=self._shallow_circuit_concat, pauli_list=self._pauli_list
            )
示例#6
0
 def test_to_weighted_pauli_operator(self):
     """ to weighted pauli operator """
     mat_op = op_converter.to_matrix_operator(self.pauli_op)
     pauli_op = op_converter.to_weighted_pauli_operator(mat_op)
     pauli_op.rounding(8)
     self.pauli_op.rounding(8)
     self.assertEqual(pauli_op, self.pauli_op)
示例#7
0
    def __init__(self,
                 operator,
                 state_in,
                 iqft,
                 num_time_slices=1,
                 num_ancillae=1,
                 expansion_mode='trotter',
                 expansion_order=1,
                 shallow_circuit_concat=False):
        """
        Constructor.

        Args:
            operator (BaseOperator): the hamiltonian Operator object
            state_in (InitialState): the InitialState pluggable component
                representing the initial quantum state
            iqft (IQFT): the Inverse Quantum Fourier Transform pluggable component
            num_time_slices (int): the number of time slices
            num_ancillae (int): the number of ancillary qubits to use for the measurement
            expansion_mode (str): the expansion mode (trotter|suzuki)
            expansion_order (int): the suzuki expansion order
            shallow_circuit_concat (bool): indicate whether to use shallow
                (cheap) mode for circuit concatenation
        """
        self.validate(locals())
        super().__init__()
        self._operator = op_converter.to_weighted_pauli_operator(operator)
        self._num_ancillae = num_ancillae
        self._ret = {}

        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.reorder_paulis()])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator.simplify()
        translation_op = WeightedPauliOperator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op.simplify()
        self._operator += translation_op
        self._pauli_list = self._operator.reorder_paulis()

        # stretch the operator
        for p in self._pauli_list:
            p[0] = p[0] * self._ret['stretch']

        self._phase_estimation_circuit = PhaseEstimationCircuit(
            operator=self._operator,
            state_in=state_in,
            iqft=iqft,
            num_time_slices=num_time_slices,
            num_ancillae=num_ancillae,
            expansion_mode=expansion_mode,
            expansion_order=expansion_order,
            shallow_circuit_concat=shallow_circuit_concat,
            pauli_list=self._pauli_list)
        self._binary_fractions = [1 / 2**p for p in range(1, num_ancillae + 1)]
示例#8
0
    def __init__(self,
                 operator,
                 iqft,
                 num_time_slices=1,
                 num_ancillae=1,
                 expansion_mode='trotter',
                 expansion_order=1,
                 evo_time=None,
                 negative_evals=False,
                 ne_qfts=[None, None]):
        """Constructor.

        Args:
            operator (BaseOperator): the hamiltonian Operator object
            iqft (IQFT): the Inverse Quantum Fourier Transform pluggable component
            num_time_slices (int, optional): the number of time slices
            num_ancillae (int, optional): the number of ancillary qubits to use for the measurement
            expansion_mode (str, optional): the expansion mode (trotter|suzuki)
            expansion_order (int, optional): the suzuki expansion order
            evo_time (float, optional): the evolution time
            negative_evals (bool, optional): indicate if negative eigenvalues need to be handled
            ne_qfts ([QFT, IQFT], optional): the QFT and IQFT pluggable components for handling negative eigenvalues
        """
        super().__init__()
        super().validate(locals())
        self._operator = op_converter.to_weighted_pauli_operator(operator)
        self._iqft = iqft
        self._num_ancillae = num_ancillae
        self._num_time_slices = num_time_slices
        self._expansion_mode = expansion_mode
        self._expansion_order = expansion_order
        self._evo_time = evo_time
        self._negative_evals = negative_evals
        self._ne_qfts = ne_qfts
        self._init_constants()
    def setUp(self):
        super().setUp()
        # np.random.seed(50)
        self.seed = 50
        aqua_globals.random_seed = self.seed
        try:
            driver = PySCFDriver(atom='H .0 .0 .0; H .0 .0 0.735',
                                 unit=UnitsType.ANGSTROM,
                                 basis='sto3g')
        except QiskitChemistryError:
            self.skipTest('PYSCF driver does not appear to be installed')
            return

        molecule = driver.run()
        self.num_particles = molecule.num_alpha + molecule.num_beta
        self.num_spin_orbitals = molecule.num_orbitals * 2
        fer_op = FermionicOperator(h1=molecule.one_body_integrals,
                                   h2=molecule.two_body_integrals)
        map_type = 'PARITY'
        qubit_op = fer_op.mapping(map_type)
        self.qubit_op = Z2Symmetries.two_qubit_reduction(
            to_weighted_pauli_operator(qubit_op), self.num_particles)
        self.num_qubits = self.qubit_op.num_qubits
        self.init_state = HartreeFock(self.num_qubits, self.num_spin_orbitals,
                                      self.num_particles)
        self.var_form_base = None
示例#10
0
    def _config_the_best_mode(self, operator, backend):

        if not isinstance(operator, (WeightedPauliOperator, MatrixOperator,
                                     TPBGroupedWeightedPauliOperator)):
            logger.debug("Unrecognized operator type, skip auto conversion.")
            return operator

        ret_op = operator
        if not is_statevector_backend(backend) and not (
                is_aer_provider(backend)
                and self._quantum_instance.run_config.shots == 1):
            if isinstance(operator, (WeightedPauliOperator, MatrixOperator)):
                logger.debug(
                    "When running with Qasm simulator, grouped pauli can "
                    "save number of measurements. "
                    "We convert the operator into grouped ones.")
                ret_op = op_converter.to_tpb_grouped_weighted_pauli_operator(
                    operator, TPBGroupedWeightedPauliOperator.sorted_grouping)
        else:
            if not is_aer_provider(backend):
                if not isinstance(operator, MatrixOperator):
                    logger.info(
                        "When running with non-Aer statevector simulator, "
                        "represent operator as a matrix could "
                        "achieve the better performance. We convert "
                        "the operator to matrix.")
                    ret_op = op_converter.to_matrix_operator(operator)
            else:
                if not isinstance(operator, WeightedPauliOperator):
                    logger.info("When running with Aer simulator, "
                                "represent operator as weighted paulis could "
                                "achieve the better performance. We convert "
                                "the operator to weighted paulis.")
                    ret_op = op_converter.to_weighted_pauli_operator(operator)
        return ret_op
示例#11
0
    def __init__(
            self, operator: BaseOperator, state_in: Optional[InitialState],
            iqft: IQFT, num_time_slices: int = 1,
            num_ancillae: int = 1, expansion_mode: str = 'trotter',
            expansion_order: int = 1, shallow_circuit_concat: bool = False) -> None:
        """

        Args:
            operator: The Hamiltonian Operator
            state_in: An optional InitialState component representing an initial quantum state.
                ``None`` may be supplied.
            iqft: A Inverse Quantum Fourier Transform component
            num_time_slices: The number of time slices, has a minimum value of 1.
            num_ancillae: The number of ancillary qubits to use for the measurement,
                has a min. value of 1.
            expansion_mode: The expansion mode ('trotter'|'suzuki')
            expansion_order: The suzuki expansion order, has a min. value of 1.
            shallow_circuit_concat: Set True to use shallow (cheap) mode for circuit concatenation
                of evolution slices. By default this is False.
                See :meth:`qiskit.aqua.operators.common.evolution_instruction` for more information.
        """
        validate_min('num_time_slices', num_time_slices, 1)
        validate_min('num_ancillae', num_ancillae, 1)
        validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'})
        validate_min('expansion_order', expansion_order, 1)
        super().__init__()
        self._operator = op_converter.to_weighted_pauli_operator(operator.copy())
        self._num_ancillae = num_ancillae
        self._ret = {}

        self._ret['translation'] = sum([abs(p[0]) for p in self._operator.reorder_paulis()])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator.simplify()
        translation_op = WeightedPauliOperator([
            [
                self._ret['translation'],
                Pauli(
                    np.zeros(self._operator.num_qubits),
                    np.zeros(self._operator.num_qubits)
                )
            ]
        ])
        translation_op.simplify()
        self._operator += translation_op
        self._pauli_list = self._operator.reorder_paulis()

        # stretch the operator
        for p in self._pauli_list:
            p[0] = p[0] * self._ret['stretch']

        self._phase_estimation_circuit = PhaseEstimationCircuit(
            operator=self._operator, state_in=state_in, iqft=iqft,
            num_time_slices=num_time_slices, num_ancillae=num_ancillae,
            expansion_mode=expansion_mode, expansion_order=expansion_order,
            shallow_circuit_concat=shallow_circuit_concat, pauli_list=self._pauli_list
        )
        self._binary_fractions = [1 / 2 ** p for p in range(1, num_ancillae + 1)]
示例#12
0
def Generate_op(op,*args, **kwargs):
    parameter = kwargs['parameter']
    ham = kwargs['ham']
    energy_step_tol = kwargs['energy_step_tol']
    mat = np.identity(2**op.num_qubits)
    Iden = to_weighted_pauli_operator(MatrixOperator(mat)) #creates random hamiltonian from random matrix "mat"
    #return np.exp(1j*parameter*op)*ham*np.exp(-1j*parameter*op).chop(threshold=energy_step_tol, copy=True)
    return (np.cos(parameter)*Iden + 1j*np.sin(parameter)*op)*ham*(np.cos(parameter)*Iden - 1j*np.sin(parameter)*op).chop(threshold=energy_step_tol, copy=True)
示例#13
0
 def __init__(self,
              operator,
              initial_state,
              evo_operator,
              evo_time=1,
              num_time_slices=1,
              expansion_mode='trotter',
              expansion_order=1):
     self.validate(locals())
     super().__init__()
     self._operator = op_converter.to_weighted_pauli_operator(operator)
     self._initial_state = initial_state
     self._evo_operator = op_converter.to_weighted_pauli_operator(
         evo_operator)
     self._evo_time = evo_time
     self._num_time_slices = num_time_slices
     self._expansion_mode = expansion_mode
     self._expansion_order = expansion_order
     self._ret = {}
示例#14
0
 def __init__(self, operator: BaseOperator,
              initial_state: InitialState,
              evo_operator: BaseOperator,
              evo_time: int = 1,
              num_time_slices: int = 1,
              expansion_mode: str = 'trotter',
              expansion_order: int = 1) -> None:
     validate_min('evo_time', evo_time, 0)
     validate_min('num_time_slices', num_time_slices, 0)
     validate_in_set('expansion_mode', expansion_mode, {'trotter', 'suzuki'})
     validate_min('expansion_order', expansion_order, 1)
     super().__init__()
     self._operator = op_converter.to_weighted_pauli_operator(operator)
     self._initial_state = initial_state
     self._evo_operator = op_converter.to_weighted_pauli_operator(evo_operator)
     self._evo_time = evo_time
     self._num_time_slices = num_time_slices
     self._expansion_mode = expansion_mode
     self._expansion_order = expansion_order
     self._ret = {}
示例#15
0
    def __init__(self,
                 cost_operator,
                 p,
                 initial_state=None,
                 mixer_operator=None):
        """
        Constructor, following the QAOA paper https://arxiv.org/abs/1411.4028

        Args:
            cost_operator (WeightedPauliOperator): The operator representing the cost of
                                                   the optimization problem,
                                                   denoted as U(B, gamma) in the original paper.
            p (int): The integer parameter p, which determines the depth of the circuit,
                     as specified in the original paper.
            initial_state (InitialState, optional): An optional initial state to use.
            mixer_operator (WeightedPauliOperator, optional): An optional custom mixer operator
                                                              to use instead of
                                                              the global X-rotations,
                                                              denoted as U(B, beta)
                                                              in the original paper.
        Raises:
            TypeError: invalid input
        """
        super().__init__()
        cost_operator = op_converter.to_weighted_pauli_operator(cost_operator)
        self._cost_operator = cost_operator
        self._num_qubits = cost_operator.num_qubits
        self._p = p
        self._initial_state = initial_state
        self._num_parameters = 2 * p
        self._bounds = [(0, np.pi)] * p + [(0, 2 * np.pi)] * p
        self._preferred_init_points = [0] * p * 2

        # prepare the mixer operator
        v = np.zeros(self._cost_operator.num_qubits)
        ws = np.eye(self._cost_operator.num_qubits)
        if mixer_operator is None:
            self._mixer_operator = reduce(lambda x, y: x + y, [
                WeightedPauliOperator([[1.0, Pauli(v, ws[i, :])]])
                for i in range(self._cost_operator.num_qubits)
            ])
        else:
            if not isinstance(mixer_operator, WeightedPauliOperator):
                raise TypeError(
                    'The mixer should be a qiskit.aqua.operators.WeightedPauliOperator '
                    + 'object, found {} instead'.format(type(mixer_operator)))
            self._mixer_operator = mixer_operator
        self.support_parameterized_circuit = True
示例#16
0
def limit_paulis(mat, n=5, sparsity=None):
    """
    Limits the number of Pauli basis matrices of a hermitian matrix to the n
    highest magnitude ones.

    Args:
        mat (np.ndarray): Input matrix
        n (int): number of surviving Pauli matrices (default=5)
        sparsity (float): sparsity of matrix < 1

    Returns:
        scipy.sparse.csr_matrix: matrix
    """
    # pylint: disable=import-outside-toplevel
    from qiskit.aqua.operators import MatrixOperator
    from qiskit.aqua.operators.op_converter import to_weighted_pauli_operator
    # Bringing matrix into form 2**Nx2**N
    __l = mat.shape[0]
    if np.log2(__l) % 1 != 0:
        k = int(2**np.ceil(np.log2(__l)))
        m = np.zeros([k, k], dtype=np.complex128)
        m[:__l, :__l] = mat
        m[__l:, __l:] = np.identity(k - __l)
        mat = m

    # Getting Pauli matrices
    # pylint: disable=invalid-name
    op = MatrixOperator(matrix=mat)
    op = to_weighted_pauli_operator(op)
    paulis = sorted(op.paulis, key=lambda x: abs(x[0]), reverse=True)
    g = 2**op.num_qubits
    mat = scipy.sparse.csr_matrix(([], ([], [])),
                                  shape=(g, g),
                                  dtype=np.complex128)

    # Truncation
    if sparsity is None:
        for pa in paulis[:n]:
            mat += pa[0] * pa[1].to_spmatrix()
    else:
        idx = 0
        while mat[:__l, :__l].nnz / __l**2 < sparsity:
            mat += paulis[idx][0] * paulis[idx][1].to_spmatrix()
            idx += 1
        n = idx
    mat = mat.toarray()
    return mat[:__l, :__l]
示例#17
0
 def __init__(self,
              operator: BaseOperator,
              iqft: IQFT,
              num_time_slices: int = 1,
              num_ancillae: int = 1,
              expansion_mode: str = 'trotter',
              expansion_order: int = 1,
              evo_time: Optional[float] = None,
              negative_evals: bool = False,
              ne_qfts: Optional[List] = None) -> None:
     """
     Args:
         operator: The Hamiltonian Operator object
         iqft: The Inverse Quantum Fourier Transform component
         num_time_slices: The number of time slices, has a minimum value of 1.
         num_ancillae: The number of ancillary qubits to use for the measurement,
             has a minimum value of 1.
         expansion_mode: The expansion mode ('trotter' | 'suzuki')
         expansion_order: The suzuki expansion order, has a minimum value of 1.
         evo_time: An optional evolution time which should scale the eigenvalue onto the range
             :math:`(0,1]` (or :math:`(-0.5,0.5]` for negative eigenvalues). Defaults to
             ``None`` in which case a suitably estimated evolution time is internally computed.
         negative_evals: Set ``True`` to indicate negative eigenvalues need to be handled
         ne_qfts: The QFT and IQFT components for handling negative eigenvalues
     """
     super().__init__()
     ne_qfts = ne_qfts if ne_qfts is not None else [None, None]
     validate_min('num_time_slices', num_time_slices, 1)
     validate_min('num_ancillae', num_ancillae, 1)
     validate_in_set('expansion_mode', expansion_mode,
                     {'trotter', 'suzuki'})
     validate_min('expansion_order', expansion_order, 1)
     self._operator = op_converter.to_weighted_pauli_operator(operator)
     self._iqft = iqft
     self._num_ancillae = num_ancillae
     self._num_time_slices = num_time_slices
     self._expansion_mode = expansion_mode
     self._expansion_order = expansion_order
     self._evo_time = evo_time
     self._negative_evals = negative_evals
     self._ne_qfts = ne_qfts
     self._circuit = None
     self._output_register = None
     self._input_register = None
     self._init_constants()
示例#18
0
    def __init__(self,
                 operator: BaseOperator,
                 iqft: IQFT,
                 num_time_slices: int = 1,
                 num_ancillae: int = 1,
                 expansion_mode: str = 'trotter',
                 expansion_order: int = 1,
                 evo_time: Optional[float] = None,
                 negative_evals: bool = False,
                 ne_qfts: Optional[List] = None) -> None:
        """Constructor.

        Args:
            operator: the hamiltonian Operator object
            iqft: the Inverse Quantum Fourier Transform component
            num_time_slices: the number of time slices, has a min. value of 1.
            num_ancillae: the number of ancillary qubits to use for the measurement,
                            has a min. value of 1.
            expansion_mode: the expansion mode (trotter|suzuki)
            expansion_order: the suzuki expansion order, has a min. value of 1.
            evo_time: the evolution time
            negative_evals: indicate if negative eigenvalues need to be handled
            ne_qfts: the QFT and IQFT components for handling negative eigenvalues
        """
        super().__init__()
        ne_qfts = ne_qfts if ne_qfts is not None else [None, None]
        validate_min('num_time_slices', num_time_slices, 1)
        validate_min('num_ancillae', num_ancillae, 1)
        validate_in_set('expansion_mode', expansion_mode,
                        {'trotter', 'suzuki'})
        validate_min('expansion_order', expansion_order, 1)
        self._operator = op_converter.to_weighted_pauli_operator(operator)
        self._iqft = iqft
        self._num_ancillae = num_ancillae
        self._num_time_slices = num_time_slices
        self._expansion_mode = expansion_mode
        self._expansion_order = expansion_order
        self._evo_time = evo_time
        self._negative_evals = negative_evals
        self._ne_qfts = ne_qfts
        self._circuit = None
        self._output_register = None
        self._input_register = None
        self._init_constants()
示例#19
0
    def construct_wpo_operator(self):
        """Returns Weighted Pauli Operator (WPO) constructed from Hamiltonian
            text file.

        Args:
            None

        Returns:
            qubit_op (QISKit WPO object): Weighted Pauli Operator
        """
        # Loading matrix representation of Hamiltonian txt file
        H = np.loadtxt(self.file_path)
        # Converting Hamiltonian to Matrix Operator
        qubit_op = MatrixOperator(matrix=H)
        # Converting to Pauli Operator
        qubit_op = to_weighted_pauli_operator(qubit_op)
        self.num_qubits = qubit_op.num_qubits
        self.num_paulis = len(qubit_op.paulis)
        return qubit_op
示例#20
0
    def __init__(self,
                 operator: BaseOperator,
                 state_in: InitialState,
                 num_time_slices: int = 1,
                 num_iterations: int = 1,
                 expansion_mode: str = 'suzuki',
                 expansion_order: int = 2,
                 shallow_circuit_concat: bool = False) -> None:
        """

        Args:
            operator: the hamiltonian Operator object
            state_in: the InitialState component representing
                    the initial quantum state
            num_time_slices: the number of time slices, has a min. value of 1.
            num_iterations: the number of iterations, has a min. value of 1.
            expansion_mode: the expansion mode (trotter|suzuki)
            expansion_order: the suzuki expansion order, has a min. value of 1.
            shallow_circuit_concat: indicate whether to use shallow (cheap)
                    mode for circuit concatenation
        """
        validate_min('num_time_slices', num_time_slices, 1)
        validate_min('num_iterations', num_iterations, 1)
        validate_in_set('expansion_mode', expansion_mode,
                        {'trotter', 'suzuki'})
        validate_min('expansion_order', expansion_order, 1)
        super().__init__()
        self._operator = op_converter.to_weighted_pauli_operator(
            operator.copy())
        self._state_in = state_in
        self._num_time_slices = num_time_slices
        self._num_iterations = num_iterations
        self._expansion_mode = expansion_mode
        self._expansion_order = expansion_order
        self._shallow_circuit_concat = shallow_circuit_concat
        self._state_register = None
        self._ancillary_register = None
        self._pauli_list = None
        self._ret = {}
        self._ancilla_phase_coef = None
        self._setup()
示例#21
0
    def _setup(self, operator: Optional[BaseOperator]) -> None:
        self._operator = None
        self._ret = {}
        self._pauli_list = None
        self._phase_estimation_circuit = None
        self._slice_pauli_list = None
        if operator:
            self._operator = op_converter.to_weighted_pauli_operator(operator.copy())
            self._ret['translation'] = sum([abs(p[0]) for p in self._operator.reorder_paulis()])
            self._ret['stretch'] = 0.5 / self._ret['translation']

            # translate the operator
            self._operator.simplify()
            translation_op = WeightedPauliOperator([
                [
                    self._ret['translation'],
                    Pauli(
                        np.zeros(self._operator.num_qubits),
                        np.zeros(self._operator.num_qubits)
                    )
                ]
            ])
            translation_op.simplify()
            self._operator += translation_op
            self._pauli_list = self._operator.reorder_paulis()

            # stretch the operator
            for p in self._pauli_list:
                p[0] = p[0] * self._ret['stretch']

            if len(self._pauli_list) == 1:
                slice_pauli_list = self._pauli_list
            else:
                if self._expansion_mode == 'trotter':
                    slice_pauli_list = self._pauli_list
                else:
                    slice_pauli_list = suzuki_expansion_slice_pauli_list(self._pauli_list,
                                                                         1, self._expansion_order)
            self._slice_pauli_list = slice_pauli_list
示例#22
0
    def calculate_excited_states(self,
                                 wave_fn,
                                 excitations_list=None,
                                 quantum_instance=None):
        """Calculate energy gap of excited states from the reference state.

        Args:
            wave_fn (Union(QuantumCircuit, numpy.ndarray)): wavefunction of reference state
            excitations_list (list): excitation list for calculating the excited states
            quantum_instance (QuantumInstance): a quantum instance with configured settings

        Returns:
            list: energy gaps to the reference state
            dict: information of qeom matrices

        Raises:
            ValueError: wrong setting for wave_fn and quantum_instance
        """
        if isinstance(wave_fn, QuantumCircuit):
            if quantum_instance is None:
                raise ValueError(
                    "quantum_instance is required when wavn_fn is a QuantumCircuit."
                )
            temp_quantum_instance = copy.deepcopy(quantum_instance)
            if temp_quantum_instance.is_statevector and temp_quantum_instance.noise_config == {}:
                initial_statevector = quantum_instance.execute(
                    wave_fn).get_statevector(wave_fn)
                q = QuantumRegister(self._operator.num_qubits, name='q')
                tmp_wave_fn = QuantumCircuit(q)
                tmp_wave_fn.append(wave_fn.to_instruction(), q)
                logger.info(
                    "Under noise-free and statevector simulation, "
                    "the wave_fn is reused and set in initial_statevector "
                    "for faster simulation.")
                temp_quantum_instance.set_config(
                    initial_statevector=initial_statevector)
                wave_fn = QuantumCircuit(q)
        else:
            temp_quantum_instance = None

        # this is required to assure paulis mode is there regardless how you compute VQE
        # it might be slow if you calculate vqe through matrix mode and then convert
        # it back to paulis
        self._operator = op_converter.to_weighted_pauli_operator(
            self._operator)
        self._untapered_op = op_converter.to_weighted_pauli_operator(
            self._untapered_op)

        excitations_list = self._de_list + self._se_list if excitations_list is None \
            else excitations_list

        # build all hopping operators
        hopping_operators, type_of_commutativities = self.build_hopping_operators(
            excitations_list)
        # build all commutators
        q_commutators, w_commutators, m_commutators, v_commutators, available_entry = \
            self.build_all_commutators(excitations_list, hopping_operators, type_of_commutativities)
        # build qeom matrices (the step involves quantum)
        m_mat, v_mat, q_mat, w_mat, m_mat_std, v_mat_std, q_mat_std, w_mat_std = \
            self.build_eom_matrices(excitations_list, q_commutators, w_commutators,
                                    m_commutators, v_commutators, available_entry,
                                    wave_fn, temp_quantum_instance)
        excitation_energies_gap = self.compute_excitation_energies(
            m_mat, v_mat, q_mat, w_mat)

        logger.info('Net excited state values (gap to reference state): %s',
                    excitation_energies_gap)

        eom_matrices = {
            'm_mat': m_mat,
            'v_mat': v_mat,
            'q_mat': q_mat,
            'w_mat': w_mat,
            'm_mat_std': m_mat_std,
            'v_mat_std': v_mat_std,
            'q_mat_std': q_mat_std,
            'w_mat_std': w_mat_std
        }

        return excitation_energies_gap, eom_matrices
示例#23
0
    def __init__(self,
                 operator: BaseOperator,
                 iqft: Union[QuantumCircuit, IQFT],
                 num_time_slices: int = 1,
                 num_ancillae: int = 1,
                 expansion_mode: str = 'trotter',
                 expansion_order: int = 1,
                 evo_time: Optional[float] = None,
                 negative_evals: bool = False,
                 ne_qfts: Optional[List] = None) -> None:
        """
        Args:
            operator: The Hamiltonian Operator object
            iqft: The Inverse Quantum Fourier Transform component
            num_time_slices: The number of time slices, has a minimum value of 1.
            num_ancillae: The number of ancillary qubits to use for the measurement,
                has a minimum value of 1.
            expansion_mode: The expansion mode ('trotter' | 'suzuki')
            expansion_order: The suzuki expansion order, has a minimum value of 1.
            evo_time: An optional evolution time which should scale the eigenvalue onto the range
                :math:`(0,1]` (or :math:`(-0.5,0.5]` for negative eigenvalues). Defaults to
                ``None`` in which case a suitably estimated evolution time is internally computed.
            negative_evals: Set ``True`` to indicate negative eigenvalues need to be handled
            ne_qfts: The QFT and IQFT components for handling negative eigenvalues
        """
        super().__init__()
        ne_qfts = ne_qfts if ne_qfts is not None else [None, None]
        validate_min('num_time_slices', num_time_slices, 1)
        validate_min('num_ancillae', num_ancillae, 1)
        validate_in_set('expansion_mode', expansion_mode,
                        {'trotter', 'suzuki'})
        validate_min('expansion_order', expansion_order, 1)
        self._operator = op_converter.to_weighted_pauli_operator(operator)

        if isinstance(iqft, IQFT):
            warnings.warn(
                'The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 '
                'and will be removed no earlier than 3 months after the release. '
                'You should pass a QuantumCircuit instead, see '
                'qiskit.circuit.library.QFT and the .inverse() method.',
                DeprecationWarning,
                stacklevel=2)
        self._iqft = iqft

        self._num_ancillae = num_ancillae
        self._num_time_slices = num_time_slices
        self._expansion_mode = expansion_mode
        self._expansion_order = expansion_order
        self._evo_time = evo_time
        self._negative_evals = negative_evals

        if ne_qfts and any(isinstance(ne_qft, IQFT) for ne_qft in ne_qfts):
            warnings.warn(
                'The qiskit.aqua.components.iqfts.IQFT module is deprecated as of 0.7.0 '
                'and will be removed no earlier than 3 months after the release. '
                'You should pass a QuantumCircuit instead, see '
                'qiskit.circuit.library.QFT and the .inverse() method.',
                DeprecationWarning,
                stacklevel=2)
        self._ne_qfts = ne_qfts

        self._circuit = None
        self._output_register = None
        self._input_register = None
        self._init_constants()
示例#24
0
from qiskit import BasicAer
from qiskit.aqua import QuantumInstance
from qiskit.aqua.operators import MatrixOperator, WeightedPauliOperator, op_converter
from qiskit.aqua.utils import decimal_to_binary
from qiskit.aqua.algorithms import ExactEigensolver
from qiskit.aqua.algorithms import QPE
from qiskit.aqua.components.iqfts import Standard
from qiskit.aqua.components.initial_states import Custom

X = np.array([[0, 1], [1, 0]])
Y = np.array([[0, -1j], [1j, 0]])
Z = np.array([[1, 0], [0, -1]])
_I = np.array([[1, 0], [0, 1]])
H1 = X + Y + Z + _I
QUBIT_OP_SIMPLE = MatrixOperator(matrix=H1)
QUBIT_OP_SIMPLE = op_converter.to_weighted_pauli_operator(QUBIT_OP_SIMPLE)

PAULI_DICT = {
    'paulis': [{
        "coeff": {
            "imag": 0.0,
            "real": -1.052373245772859
        },
        "label": "II"
    }, {
        "coeff": {
            "imag": 0.0,
            "real": 0.39793742484318045
        },
        "label": "IZ"
    }, {
示例#25
0
 def test_to_matrix_operator(self):
     """ to matrix operator """
     pauli_op = op_converter.to_weighted_pauli_operator(self.mat_op)
     mat_op = op_converter.to_matrix_operator(pauli_op)
     diff = float(np.sum(np.abs(self.mat_op.matrix - mat_op.matrix)))
     self.assertAlmostEqual(0, diff, places=8)
def run_exp(num_reps=1):

    # choice of Hi basis
    H_basis = [Pauli.from_label(p) for p in ['II', 'ZI', 'IZ', 'ZZ', 'YY', 'XX']]

    num_qubits = 2
    evo_time = 1
    epsilon = 0.1
    L = 32    ## number of local hamiltonian terms

    ############################################################
    # Generate a random Hamiltonian H as the sum of m basis Hi operators
    ############################################################

    hs = np.random.random(L)
    indexes = np.random.randint(low=0, high=6, size=L)

    ## H in matrix form
    H_matrix = np.zeros((2 ** num_qubits, 2 ** num_qubits))

    ## H as a list of pauli operators (unweighted)
    H_list = []
    for i in range(L):
        H_matrix = H_matrix + hs[i] * H_basis[indexes[i]].to_matrix()
        H_list.append(H_basis[indexes[i]])
    print('matrix H: \n', H_matrix)

    # H as a pauli operator
    H_qubitOp = op_converter.to_weighted_pauli_operator(MatrixOperator(matrix=H_matrix))

    # Generate an initial state
    state_in = Custom(num_qubits, state='random')

    ############################################################
    # Ground truth and benchmarks
    ############################################################

    # Ground truth
    state_in_vec = state_in.construct_circuit('vector')
    groundtruth = expm(-1.j * H_matrix * evo_time) @ state_in_vec
    print('The directly computed groundtruth evolution result state is')
    print('{}\n.'.format(groundtruth))

    # Build circuit using Qiskit's evolve algorithm, which based on Trotter-Suzuki.
    quantum_registers = QuantumRegister(num_qubits)
    circuit = state_in.construct_circuit('circuit', quantum_registers)
    circuit += H_qubitOp.evolve(
        None, evo_time, num_time_slices=10,
        quantum_registers=quantum_registers,
        expansion_mode='suzuki',
        expansion_order=1
    )

    # Simulate Trotter-Suzuki circuit and print it
    backend = BasicAer.get_backend('statevector_simulator')
    job = q_execute(circuit, backend)
    circuit_execution_result = np.asarray(job.result().get_statevector(circuit))
    print('The simulated (suzuki) evolution result state is')
    print('{}\n'.format(circuit_execution_result))

    # The difference between the ground truth and the simulated state
    # measured by "Fidelity"
    fidelity_suzuki = state_fidelity(groundtruth, circuit_execution_result)
    print('Fidelity between the groundtruth and the circuit result states is {}.'.format(fidelity_suzuki))
    print('\n')

    ############################################################
    # Our qdrift implementation
    ############################################################

    quantum_registers = QuantumRegister(num_qubits)
    circuit = state_in.construct_circuit('circuit', quantum_registers)

    # Contruct the circuit which implements qdrift
    circuit = time_evolve_qubits(quantum_registers, circuit, num_qubits, H_list, hs, evo_time, epsilon, num_reps)

    # Simulate circuit and print it
    backend = BasicAer.get_backend('statevector_simulator')
    job = q_execute(circuit, backend)
    circuit_execution_result = np.asarray(job.result().get_statevector(circuit))
    print('The simulated (qdrift) evolution result state is\n{}.'.format(circuit_execution_result))
    print('\n')

    # Measure the fidelity
    fidelity_qdrift = state_fidelity(groundtruth, circuit_execution_result)
    print('Fidelity between the groundtruth and the circuit result states is {}.'.format(fidelity_qdrift))
    print('\n')

    print('benchmark, suzuki:', fidelity_suzuki)
    print('qdrift:', fidelity_qdrift)
    return fidelity_qdrift, fidelity_suzuki
示例#27
0
from qiskit.aqua.operators import MatrixOperator, WeightedPauliOperator, op_converter
from qiskit.aqua.utils import decimal_to_binary
from qiskit.aqua.algorithms import ExactEigensolver
from qiskit.aqua.algorithms import QPE
from qiskit.aqua.components.iqfts import Standard
from qiskit.aqua.components.initial_states import Custom
from test.aqua.common import QiskitAquaTestCase


X = np.array([[0, 1], [1, 0]])
Y = np.array([[0, -1j], [1j, 0]])
Z = np.array([[1, 0], [0, -1]])
_I = np.array([[1, 0], [0, 1]])
h1 = X + Y + Z + _I
qubit_op_simple = MatrixOperator(matrix=h1)
qubit_op_simple = op_converter.to_weighted_pauli_operator(qubit_op_simple)

pauli_dict = {
    'paulis': [
        {"coeff": {"imag": 0.0, "real": -1.052373245772859}, "label": "II"},
        {"coeff": {"imag": 0.0, "real": 0.39793742484318045}, "label": "IZ"},
        {"coeff": {"imag": 0.0, "real": -0.39793742484318045}, "label": "ZI"},
        {"coeff": {"imag": 0.0, "real": -0.01128010425623538}, "label": "ZZ"},
        {"coeff": {"imag": 0.0, "real": 0.18093119978423156}, "label": "XX"}
    ]
}
qubit_op_h2_with_2_qubit_reduction = WeightedPauliOperator.from_dict(pauli_dict)


pauli_dict_zz = {
    'paulis': [
示例#28
0
# In[8]:

## CREATE WeightedPauliOperater (qubit_op)
## CAUTION: Take a long time

qubit_op, aux_ops = hamiltonian.run(qmolecule=qmolecule)

# In[9]:

vars(qubit_op)

# In[10]:

# FILE IO
wpOp = op_converter.to_weighted_pauli_operator(qubit_op)
for p in wpOp.paulis:
    p[0] = np.real(p[0])
with open('./PSPCz.hamiltonian', 'wb') as f:
    pickle.dump(classical_info, f)
wpOp.to_file('./PSPCz.wpOp')

# In[11]:

# Using exact eigensolver to get the smallest eigenvalue
energy_shift = hamiltonian._energy_shift
exact_eigensolver = ExactEigensolver(qubit_op, k=3)
ret = exact_eigensolver.run()

# In[12]:
    def __init__(self,
                 cost_operator,
                 p,
                 initial_state_circuit=None,
                 mixer_circuit=None,
                 measurement_circuit=None,
                 qregs=None):
        """
        Constructor, following the QAOA paper https://arxiv.org/abs/1411.4028

        Args:
            cost_operator (WeightedPauliOperator): The operator representing the cost of
                                                   the optimization problem,
                                                   denoted as U(B, gamma) in the original paper.
            p (int): The integer parameter p, which determines the depth of the circuit,
                     as specified in the original paper.
            initial_state_circuit (QuantumCircuit, optional): Circuit that prepares the initial state.
            mixer_circuit (QuantumCircuit, optional): An optional custom mixer operator
                                                              to use instead of
                                                              the global X-rotations,
                                                              denoted as U(B, beta)
                                                              in the original paper.
                                                      Mixer circuit should be a parameterized
                                                      QuantumCircuit with parameter beta
                                                      See default for example
            measurement_circuit (QuantumCircuit, optional): An optional circuit with measurements (useful if your mixer has ancillas in it)
            qregs (list of QuantumRegister) : Registers (also vis-a-vis ancillas)
                                              qregs[0] MUST BE the register with working qubits (i.e. the ones that are measured in the end)
        Raises:
            TypeError: invalid input
        """
        super().__init__()
        cost_operator = op_converter.to_weighted_pauli_operator(cost_operator)
        self._cost_operator = cost_operator
        self._num_qubits = cost_operator.num_qubits
        self._p = p
        self._initial_state_circuit = initial_state_circuit
        self._num_parameters = 2 * p
        self._bounds = [(0, np.pi)] * p + [(0, 2 * np.pi)] * p
        self._preferred_init_points = [0] * p * 2

        # prepare the mixer operator
        v = np.zeros(self._cost_operator.num_qubits)
        ws = np.eye(self._cost_operator.num_qubits)
        if mixer_circuit is None:
            # default mixer is transverse field
            self._mixer_circuit = QuantumCircuit(self._num_qubits)
            beta = Parameter('beta')
            for q1 in range(self._num_qubits):
                self._mixer_circuit.h(q1)
                self._mixer_circuit.rz(2 * beta, q1)
                self._mixer_circuit.h(q1)
        else:
            if not isinstance(mixer_circuit, QuantumCircuit):
                raise TypeError(
                    'The mixer should be a qiskit.QuantumCircuit ' +
                    'object, found {} instead'.format(type(mixer_circuit)))
            self._mixer_circuit = mixer_circuit
        if len(self._mixer_circuit.parameters) != 1:
            raise ValueError(
                f"Mixer circuit should have exactly one parameter (beta), received {self._mixer_circuit.parameters}"
            )
        self.support_parameterized_circuit = True
        self._measurement_circuit = measurement_circuit
        self.qregs = qregs
示例#30
0
    def __init__(self,
                 operator: BaseOperator,
                 state_in: InitialState,
                 iqft: IQFT,
                 num_time_slices: int = 1,
                 num_ancillae: int = 1,
                 expansion_mode: str = 'trotter',
                 expansion_order: int = 1,
                 shallow_circuit_concat: bool = False) -> None:
        """

        Args:
            operator: the hamiltonian Operator object
            state_in: the InitialState component
                representing the initial quantum state
            iqft: the Inverse Quantum Fourier Transform component
            num_time_slices: the number of time slices, has a min. value of 1.
            num_ancillae: the number of ancillary qubits to use for the measurement,
                            has a min. value of 1.
            expansion_mode: the expansion mode (trotter|suzuki)
            expansion_order: the suzuki expansion order, has a min. value of 1.
            shallow_circuit_concat: indicate whether to use shallow
                (cheap) mode for circuit concatenation
        """
        validate_min('num_time_slices', num_time_slices, 1)
        validate_min('num_ancillae', num_ancillae, 1)
        validate_in_set('expansion_mode', expansion_mode,
                        {'trotter', 'suzuki'})
        validate_min('expansion_order', expansion_order, 1)
        super().__init__()
        self._operator = op_converter.to_weighted_pauli_operator(
            operator.copy())
        self._num_ancillae = num_ancillae
        self._ret = {}

        self._ret['translation'] = sum(
            [abs(p[0]) for p in self._operator.reorder_paulis()])
        self._ret['stretch'] = 0.5 / self._ret['translation']

        # translate the operator
        self._operator.simplify()
        translation_op = WeightedPauliOperator([[
            self._ret['translation'],
            Pauli(np.zeros(self._operator.num_qubits),
                  np.zeros(self._operator.num_qubits))
        ]])
        translation_op.simplify()
        self._operator += translation_op
        self._pauli_list = self._operator.reorder_paulis()

        # stretch the operator
        for p in self._pauli_list:
            p[0] = p[0] * self._ret['stretch']

        self._phase_estimation_circuit = PhaseEstimationCircuit(
            operator=self._operator,
            state_in=state_in,
            iqft=iqft,
            num_time_slices=num_time_slices,
            num_ancillae=num_ancillae,
            expansion_mode=expansion_mode,
            expansion_order=expansion_order,
            shallow_circuit_concat=shallow_circuit_concat,
            pauli_list=self._pauli_list)
        self._binary_fractions = [1 / 2**p for p in range(1, num_ancillae + 1)]