Exemplo n.º 1
0
 def __init__(self,
              operator: WeightedPauliOperator,
              timelimit: int = 600,
              thread: int = 1,
              display: int = 2) -> None:
     """
     Args:
         operator: The Ising Hamiltonian as an Operator
         timelimit: A time limit in seconds for the execution
         thread: The number of threads that CPLEX uses. Setting this 0 lets CPLEX decide the
             number of threads to allocate, but this may not be ideal for small problems for
             which the default of 1 is more suitable.
         display: Decides what CPLEX reports to the screen and records in a log during
             mixed integer optimization. This value must be between 0 and 5 where the
             amount of information displayed increases with increasing values of this parameter.
     """
     validate_min('timelimit', timelimit, 1)
     validate_min('thread', thread, 0)
     validate_range('display', display, 0, 5)
     super().__init__()
     self._ins = IsingInstance()
     self._ins.parse(operator.to_dict()['paulis'])
     self._timelimit = timelimit
     self._thread = thread
     self._display = display
     self._sol = None
Exemplo n.º 2
0
    def __init__(self,
                 pat_length: Optional[int] = None,
                 subpat_length: Optional[int] = None,
                 scale: float = 0,
                 negative_evals: bool = False,
                 evo_time: Optional[float] = None,
                 lambda_min: Optional[float] = None) -> None:
        """Constructor.

        Args:
            pat_length: the number of qubits used for binning pattern
            subpat_length: the number of qubits used for binning sub-pattern
            scale: the scale of rotation angle, corresponds to HHL constant C,
                     has values between 0 and 1.
            negative_evals: indicate if negative eigenvalues need to be handled
            evo_time: the evolution time
            lambda_min: the smallest expected eigenvalue
        """
        validate_range('scale', scale, 0, 1)
        super().__init__()
        self._pat_length = pat_length
        self._subpat_length = subpat_length
        self._negative_evals = negative_evals
        self._scale = scale
        self._evo_time = evo_time
        self._lambda_min = lambda_min
        self._anc = None
        self._workq = None
        self._msq = None
        self._ev = None
        self._circuit = None
        self._reg_size = 0
Exemplo n.º 3
0
 def __init__(self,
              operator: WeightedPauliOperator,
              timelimit: int = 600,
              thread: int = 1,
              display: int = 2) -> None:
     validate_min('timelimit', timelimit, 1)
     validate_min('thread', thread, 0)
     validate_range('display', display, 0, 5)
     super().__init__()
     self._ins = IsingInstance()
     self._ins.parse(operator.to_dict()['paulis'])
     self._timelimit = timelimit
     self._thread = thread
     self._display = display
     self._sol = None
Exemplo n.º 4
0
    def __init__(
        self,
        epsilon: float,
        alpha: float,
        confint_method: str = 'beta',
        min_ratio: float = 2.0,
        a_factory: Optional[CircuitFactory] = None,
        q_factory: Optional[CircuitFactory] = None,
        i_objective: Optional[int] = None,
        quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None
    ) -> None:
        """
        The output of the algorithm is an estimate for the amplitude `a`, that with at least
        probability 1 - alpha has an error of epsilon. The number of A operator calls scales
        linearly in 1/epsilon (up to a logarithmic factor).

        Args:
            epsilon: Target precision for estimation target `a`, has values between 0 and 0.5
            alpha: Confidence level, the target probability is 1 - alpha, has values between 0 and 1
            confint_method: Statistical method used to estimate the confidence intervals in
                each iteration, can be 'chernoff' for the Chernoff intervals or 'beta' for the
                Clopper-Pearson intervals (default)
            min_ratio: Minimal q-ratio (K_{i+1} / K_i) for FindNextK
            a_factory: The A operator, specifying the QAE problem
            q_factory: The Q operator (Grover operator), constructed from the
                A operator
            i_objective: Index of the objective qubit, that marks the 'good/bad' states
            quantum_instance: Quantum Instance or Backend

        Raises:
            AquaError: if the method to compute the confidence intervals is not supported
        """
        # validate ranges of input arguments
        validate_range('epsilon', epsilon, 0, 0.5)
        validate_range('alpha', alpha, 0, 1)
        validate_in_set('confint_method', confint_method, {'chernoff', 'beta'})

        super().__init__(a_factory, q_factory, i_objective, quantum_instance)

        # store parameters
        self._epsilon = epsilon
        self._alpha = alpha
        self._min_ratio = min_ratio
        self._confint_method = confint_method

        # results dictionary
        self._ret = {}  # type: Dict[str, Any]
Exemplo n.º 5
0
 def __init__(
         self,
         pat_length: Optional[int] = None,
         subpat_length: Optional[int] = None,
         scale: float = 0,
         negative_evals: bool = False,
         evo_time: Optional[float] = None,
         lambda_min: Optional[float] = None) -> None:
     r"""
     Args:
         pat_length: The number of qubits used for binning pattern. Specifies the number of bits
             following the most-significant bit that is used to identify a number. This leads to
             a binning of large values, while preserving the accuracy for smaller values. It
             should be chosen as :math:`min(k-1,5)` for an input register with k qubits to limit
             the error in the rotation to < 3%.
         subpat_length: The number of qubits used for binning sub-pattern. This parameter is
             computed in the circuit creation routine and helps reducing the gate count.
             For `pat_length<=5` it is chosen as
             :math:`\left\lceil(\frac{patlength}{2})\right\rceil`.
         scale: The scale of rotation angle, corresponds to HHL constant C,
             has values between 0 and 1. This parameter is used to scale the reciprocals such
             that for a scale C, the rotation is performed by an angle
             :math:`\arcsin{\frac{C}{\lambda}}`. If neither the `scale` nor the
             `evo_time` and `lambda_min` parameters are specified, the smallest resolvable
             Eigenvalue is used.
         negative_evals: Indicate if negative eigenvalues need to be handled
         evo_time: The evolution time. This parameter scales the Eigenvalues in the phase
             estimation onto the range (0,1] ( (-0.5,0.5] for negative Eigenvalues ).
         lambda_min: The smallest expected eigenvalue
     """
     validate_range('scale', scale, 0, 1)
     super().__init__()
     self._pat_length = pat_length
     self._subpat_length = subpat_length
     self._negative_evals = negative_evals
     self._scale = scale
     self._evo_time = evo_time
     self._lambda_min = lambda_min
     self._anc = None
     self._workq = None
     self._msq = None
     self._ev = None
     self._circuit = None
     self._reg_size = 0
 def test_validate_range(self):
     """ validate range test """
     test_value = 2.5
     with self.assertRaises(ValueError):
         validate_range('test_value', test_value, 0, 2)
     with self.assertRaises(ValueError):
         validate_range('test_value', test_value, 3, 4)
     validate_range('test_value', test_value, 2.5, 3)
     validate_range_exclusive('test_value', test_value, 0, 3)
     with self.assertRaises(ValueError):
         validate_range_exclusive('test_value', test_value, 0, 2.5)
         validate_range_exclusive('test_value', test_value, 2.5, 3)
     validate_range_exclusive_min('test_value', test_value, 0, 3)
     with self.assertRaises(ValueError):
         validate_range_exclusive_min('test_value', test_value, 2.5, 3)
     validate_range_exclusive_min('test_value', test_value, 0, 2.5)
     validate_range_exclusive_max('test_value', test_value, 2.5, 3)
     with self.assertRaises(ValueError):
         validate_range_exclusive_max('test_value', test_value, 0, 2.5)
     validate_range_exclusive_max('test_value', test_value, 2.5, 3)
Exemplo n.º 7
0
    def __init__(
        self,
        epsilon: float,
        alpha: float,
        confint_method: str = 'beta',
        min_ratio: float = 2,
        state_preparation: Optional[Union[QuantumCircuit,
                                          CircuitFactory]] = None,
        grover_operator: Optional[Union[QuantumCircuit,
                                        CircuitFactory]] = None,
        objective_qubits: Optional[List[int]] = None,
        post_processing: Optional[Callable[[float], float]] = None,
        a_factory: Optional[CircuitFactory] = None,
        q_factory: Optional[CircuitFactory] = None,
        i_objective: Optional[int] = None,
        initial_state: Optional[QuantumCircuit] = None,
        quantum_instance: Optional[Union[QuantumInstance, BaseBackend,
                                         Backend]] = None
    ) -> None:
        r"""
        The output of the algorithm is an estimate for the amplitude `a`, that with at least
        probability 1 - alpha has an error of epsilon. The number of A operator calls scales
        linearly in 1/epsilon (up to a logarithmic factor).

        Args:
            epsilon: Target precision for estimation target `a`, has values between 0 and 0.5
            alpha: Confidence level, the target probability is 1 - alpha, has values between 0 and 1
            confint_method: Statistical method used to estimate the confidence intervals in
                each iteration, can be 'chernoff' for the Chernoff intervals or 'beta' for the
                Clopper-Pearson intervals (default)
            min_ratio: Minimal q-ratio (:math:`K_{i+1} / K_i`) for FindNextK
            state_preparation: A circuit preparing the input state, referred to as
                :math:`\mathcal{A}`.
            grover_operator: The Grover operator :math:`\mathcal{Q}` used as unitary in the
                phase estimation circuit.
            objective_qubits: A list of qubit indices. A measurement outcome is classified as
                'good' state if all objective qubits are in state :math:`|1\rangle`, otherwise it
                is classified as 'bad'.
            post_processing: A mapping applied to the estimate of :math:`0 \leq a \leq 1`,
                usually used to map the estimate to a target interval.
            a_factory: The A operator, specifying the QAE problem
            q_factory: The Q operator (Grover operator), constructed from the
                A operator
            i_objective: Index of the objective qubit, that marks the 'good/bad' states
            initial_state: A state to prepend to the constructed circuits.
            quantum_instance: Quantum Instance or Backend

        Raises:
            AquaError: if the method to compute the confidence intervals is not supported
        """
        # validate ranges of input arguments
        validate_range('epsilon', epsilon, 0, 0.5)
        validate_range('alpha', alpha, 0, 1)
        validate_in_set('confint_method', confint_method, {'chernoff', 'beta'})

        # support legacy input if passed as positional arguments
        if isinstance(state_preparation, CircuitFactory):
            a_factory = state_preparation
            state_preparation = None

        if isinstance(grover_operator, CircuitFactory):
            q_factory = grover_operator
            grover_operator = None

        if isinstance(objective_qubits, int):
            i_objective = objective_qubits
            objective_qubits = None

        super().__init__(state_preparation=state_preparation,
                         grover_operator=grover_operator,
                         objective_qubits=objective_qubits,
                         post_processing=post_processing,
                         a_factory=a_factory,
                         q_factory=q_factory,
                         i_objective=i_objective,
                         quantum_instance=quantum_instance)

        # store parameters
        self._epsilon = epsilon
        self._alpha = alpha
        self._min_ratio = min_ratio
        self._confint_method = confint_method
        self._initial_state = initial_state

        # results dictionary
        self._ret = {}  # type: Dict[str, Any]
Exemplo n.º 8
0
    def __init__(self,
                 initial_state: InitialState,
                 operator: Optional[BaseOperator] = None,
                 q: Optional[float] = 0.5,
                 num_ancillae: Optional[int] = 0,
                 var_form: Optional[VariationalForm] = None,
                 optimizer: Optional[Optimizer] = None,
                 initial_point: Optional[np.ndarray] = None,
                 max_evals_grouped: int = 1,
                 callback: Optional[Callable[[int, np.ndarray, float, float], None]] = None,
                 quantum_instance: Optional[Union[QuantumInstance, BaseBackend]] = None) -> None:
        """
        Constructor.

        Args:
            initial_state (InitialState): The state to be diagonalized
            operator (BaseOperator): The density matrix of the
            initial state
            q (int): Free parameter that ones to tailer the VQSD method
            num_ancillae (int): The number of ancillae qubits if the initial
            state is a mixed state
            var_form: A parameterized variational form (ansatz).
            optimizer: A classical optimizer.
            initial_point: An optional initial point (i.e. initial parameter values)
                for the optimizer. If ``None`` then VQE will look to the variational form for a
                preferred point and if not will simply compute a random one.
            max_evals_grouped: Max number of evaluations performed simultaneously. Signals the
                given optimizer that more than one set of parameters can be supplied so that
                potentially the expectation values can be computed in parallel. Typically this is
                possible when a finite difference gradient is used by the optimizer such that
                multiple points to compute the gradient can be passed and if computed in parallel
                improve overall execution time.
            callback: a callback that can access the intermediate data during the optimization.
                Four parameter values are passed to the callback as follows during each evaluation
                by the optimizer for its current set of parameters as it works towards the minimum.
                These are: the evaluation count, the optimizer parameters for the
                variational form, the evaluated global cost, local cost and
                weighted cost
            quantum_instance: Quantum Instance or Backend
        """

        validate_min('max_evals_grouped', max_evals_grouped, 1)
        validate_range('num_ancillae', num_ancillae, 0, initial_state._num_qubits - 1)
        validate_range('q', q, 0.0, 1.0)

        if var_form is None:
            # TODO after ansatz refactor num qubits can be set later so we do not have to have
            #      an operator to create a default
            if initial_state is not None:
                var_form = RY(initial_state._num_qubits -
                              num_ancillae)

        if optimizer is None:
            optimizer = SLSQP()

        if operator is None:
            initial_state_vector = initial_state.construct_circuit(mode='vector')
            mat = np.outer(initial_state_vector, np.conj(initial_state_vector))
            operator = DensityMatrix(mat)

        # TODO after ansatz refactor we may still not be able to do this
        # if num qubits is not set on var form
        if initial_point is None and var_form is not None:
            initial_point = var_form.preferred_init_points

        self._max_evals_grouped = max_evals_grouped

        super().__init__(var_form=var_form,
                         optimizer=optimizer,
                         cost_fn=self._cost_evaluation,
                         initial_point=initial_point,
                         quantum_instance=quantum_instance)

        self._callback = callback
        self._use_simulator_snapshot_mode = None
        self._ret = None
        self._eval_time = None
        self._eval_count = 0

        logger.info(self.print_settings())
        self._var_form_params = None
        if self.var_form is not None:
            self._var_form_params = ParameterVector('θ', self.var_form.num_parameters)
        self._parameterized_circuits = None

        self._initial_state = initial_state
        self._q = q
        self._num_ancillae = num_ancillae
        self._num_working_qubits = initial_state._num_qubits - num_ancillae
        self._operator = operator
        self.initial_state = initial_state

        # TODO : Verify that if the ancillae qubits form an orthonormal basis

        # Compute state purity
        if self._num_ancillae > 0:
            # pylint: disable=import-outside-toplevel
            from qiskit.quantum_info import purity, partial_trace

            rho = self._operator.data
            ancillae_idx = list(set(range(self._initial_state._num_qubits)) -
                                set(range(self._num_ancillae)))
            self._operator = partial_trace(rho, ancillae_idx)
            self._purity = purity(self._operator)
        else:
            self._purity = 1.0