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 = {}
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 = {}
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())
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()
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 )
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)
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)]
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
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
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)]
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)
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 = {}
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 = {}
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
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]
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()
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()
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
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()
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
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
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()
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" }, {
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
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': [
# 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
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)]