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
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
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
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]
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)
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]
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