def local_pluggables(pluggable_type): """ Accesses pluggable names Args: pluggable_type(PluggableType or str): The pluggable type Returns: names: pluggable names Raises: AquaError: if the tyoe is not registered """ _discover_on_demand() if isinstance(pluggable_type, str): for ptype in PluggableType: if ptype.value == pluggable_type: pluggable_type = ptype break if not isinstance(pluggable_type, PluggableType): raise AquaError( 'Invalid pluggable type {}'.format(pluggable_type)) if pluggable_type not in _REGISTERED_PLUGGABLES: raise AquaError('{} not registered'.format(pluggable_type)) return [pluggable.name for pluggable in _REGISTERED_PLUGGABLES[pluggable_type].values()]
def __init__(self, training_dataset, test_dataset=None, datapoints=None, gamma=None, multiclass_extension=None): self.validate(locals()) super().__init__() if training_dataset is None: raise AquaError('Training dataset must be provided.') is_multiclass = get_num_classes(training_dataset) > 2 if is_multiclass: if multiclass_extension is None: raise AquaError( 'Dataset has more than two classes. A multiclass extension must be provided.' ) else: if multiclass_extension is not None: logger.warning( "Dataset has just two classes. Supplied multiclass extension will be ignored" ) if multiclass_extension is None: svm_instance = _SVM_Classical_Binary(training_dataset, test_dataset, datapoints, gamma) else: svm_instance = _SVM_Classical_Multiclass(training_dataset, test_dataset, datapoints, gamma, multiclass_extension) self.instance = svm_instance
def get_pluggable_configuration(pluggable_type, pluggable_name): """ Accesses pluggable configuration Args: pluggable_type(PluggableType or str): The pluggable type pluggable_name (str): The pluggable name Returns: configuration: pluggable configuration Raises: AquaError: if the class is not registered """ _discover_on_demand() if isinstance(pluggable_type, str): for ptype in PluggableType: if ptype.value == pluggable_type: pluggable_type = ptype break if not isinstance(pluggable_type, PluggableType): raise AquaError('Invalid pluggable type {} {}'.format( pluggable_type, pluggable_name)) if pluggable_type not in _REGISTERED_PLUGGABLES: raise AquaError('{} {} not registered'.format( pluggable_type, pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AquaError('{} {} not registered'.format( pluggable_type, pluggable_name)) return copy.deepcopy(_REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].configuration)
def _register_pluggable(pluggable_type, cls): """ Registers a pluggable class Args: pluggable_type(PluggableType): The pluggable type cls (object): Pluggable class. Returns: name: pluggable name Raises: AquaError: if the class is already registered or could not be registered """ if pluggable_type not in _REGISTERED_PLUGGABLES: _REGISTERED_PLUGGABLES[pluggable_type] = {} # fix pickle problems method = 'from {} import {}\nglobal global_class\nglobal_class = {}'.format( cls.__module__, cls.__qualname__, cls.__qualname__) exec(method) cls = global_class # Verify that the pluggable is not already registered. registered_classes = _REGISTERED_PLUGGABLES[pluggable_type] if cls in [pluggable.cls for pluggable in registered_classes.values()]: raise AquaError( 'Could not register class {} is already registered'.format(cls)) # Verify that it has a minimal valid configuration. try: pluggable_name = cls.CONFIGURATION['name'] except (LookupError, TypeError): raise AquaError('Could not register pluggable: invalid configuration') # Verify that the pluggable is valid check_pluggable_valid = getattr(cls, 'check_pluggable_valid', None) if check_pluggable_valid is not None: try: check_pluggable_valid() except Exception as e: logger.debug(str(e)) raise AquaError( 'Could not register class {}. Name {} is not valid'.format( cls, pluggable_name)) from e if pluggable_name in _REGISTERED_PLUGGABLES[pluggable_type]: raise AquaError( 'Could not register class {}. Name {} {} is already registered'. format(cls, pluggable_name, _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].cls)) # Append the pluggable to the `registered_classes` dict. _REGISTERED_PLUGGABLES[pluggable_type][ pluggable_name] = RegisteredPluggable(pluggable_name, cls, copy.deepcopy(cls.CONFIGURATION)) return pluggable_name
def __init__(self): super().__init__() if 'problems' not in self.configuration or len( self.configuration['problems']) <= 0: raise AquaError( 'Algorithm Input missing or empty configuration problems') for problem in self.configuration['problems']: if problem not in AlgorithmInput._PROBLEM_SET: raise AquaError( 'Problem {} not in known problem set {}'.format( problem, AlgorithmInput._PROBLEM_SET))
def check_pluggable_valid(name): err_msg = "Unable to instantiate '{}', nlopt is not installed. Please install it if you want to use them.".format( name) try: spec = importlib.util.find_spec('nlopt') if spec is not None: return except Exception as e: logger.debug('{} {}'.format(err_msg, str(e))) raise AquaError(err_msg) from e raise AquaError(err_msg)
def check_pluggable_valid(): err_msg = 'CPLEX is not installed. See https://www.ibm.com/support/knowledgecenter/SSSA5P_12.8.0/ilog.odms.studio.help/Optimization_Studio/topics/COS_home.html' try: spec = importlib.util.find_spec('cplex.callbacks') if spec is not None: spec = importlib.util.find_spec('cplex.exceptions') if spec is not None: return except Exception as e: logger.debug('{} {}'.format(err_msg, str(e))) raise AquaError(err_msg) from e raise AquaError(err_msg)
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance. Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AquaError("EnergyInput instance is required.") operator = algo_input.qubit_op evolution_fidelity_params = params.get( QuantumAlgorithm.SECTION_KEY_ALGORITHM) expansion_order = evolution_fidelity_params.get( EvolutionFidelity.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_pluggable_class( PluggableType.INITIAL_STATE, initial_state_params['name']).init_params(initial_state_params) return cls(operator, initial_state, expansion_order)
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params (dict): parameters dictionary algo_input (EnergyInput): EnergyInput instance """ if algo_input is None: raise AquaError("EnergyInput instance is required.") operator = algo_input.qubit_op qaoa_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = qaoa_params.get('operator_mode') p = qaoa_params.get('p') initial_point = qaoa_params.get('initial_point') batch_mode = qaoa_params.get('batch_mode') # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_pluggable_class( PluggableType.OPTIMIZER, opt_params['name']).init_params(opt_params) return cls(operator, optimizer, p=p, operator_mode=operator_mode, initial_point=initial_point, batch_mode=batch_mode, aux_operators=algo_input.aux_ops)
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AquaError("EnergyInput instance is required.") operator = algo_input.qubit_op iqpe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) num_time_slices = iqpe_params.get(IQPE.PROP_NUM_TIME_SLICES) paulis_grouping = iqpe_params.get(IQPE.PROP_PAULIS_GROUPING) expansion_mode = iqpe_params.get(IQPE.PROP_EXPANSION_MODE) expansion_order = iqpe_params.get(IQPE.PROP_EXPANSION_ORDER) num_iterations = iqpe_params.get(IQPE.PROP_NUM_ITERATIONS) # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_pluggable_class( PluggableType.INITIAL_STATE, init_state_params['name']).init_params(init_state_params) return cls(operator, init_state, num_time_slices=num_time_slices, num_iterations=num_iterations, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def __init__(self, schema_input): """Create JSONSchema object.""" self._schema = None self._original_schema = None self.aqua_jsonschema = None if isinstance(schema_input, dict): self._schema = copy.deepcopy(schema_input) elif isinstance(schema_input, str): with open(schema_input) as json_file: self._schema = json.load(json_file) else: raise AquaError("Invalid JSONSchema input type.") validator = jsonschema.Draft4Validator(self._schema) self._schema = JSONSchema._resolve_schema_references( validator.schema, validator.resolver) self.commit_changes() self._initial_default_backend = None if 'properties' in self._schema and \ JSONSchema.BACKEND in self._schema['properties'] and \ 'properties' in self._schema['properties'][JSONSchema.BACKEND] and \ JSONSchema.NAME in self._schema['properties'][JSONSchema.BACKEND]['properties'] and \ 'default' in self._schema['properties'][JSONSchema.BACKEND]['properties'][JSONSchema.NAME]: self._initial_default_backend = self._schema['properties'][ JSONSchema.BACKEND]['properties'][JSONSchema.NAME]['default']
def check_property_value(self, section_name, property_name, value): """ Check value for property name Args: section_name (string): section name property_name (string): property name value (obj): value Returns: Returns converted value if valid """ section_name = JSONSchema.format_section_name(section_name) property_name = JSONSchema.format_property_name(property_name) types = self.get_property_types(section_name, property_name) value = JSONSchema.get_value(value, types) if len(types) > 0: validator = jsonschema.Draft4Validator(self._schema) valid = False for type in types: valid = validator.is_type(value, type) if valid: break if not valid: raise AquaError("{}.{} Value '{}' is not of types: '{}'".format( section_name, property_name, value, types)) return value
def from_params(cls, params): if 'training_dataset' not in params: raise AquaError("training_dataset is required.") training_dataset = params['training_dataset'] test_dataset = params['test_dataset'] datapoints = params['datapoints'] return cls(training_dataset, test_dataset, datapoints)
def format_property_name(property_name): if property_name is None: property_name = '' property_name = property_name.strip() if len(property_name) == 0: raise AquaError("Empty property name.") return property_name
def init_params(cls, params, algo_input): if algo_input is None: raise AquaError("EnergyInput instance is required.") algo_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) timelimit = algo_params['timelimit'] thread = algo_params['thread'] display = algo_params['display'] return cls(algo_input.qubit_op, timelimit, thread, display)
def format_section_name(section_name): if section_name is None: section_name = '' section_name = section_name.strip() if len(section_name) == 0: raise AquaError("Empty section name.") return section_name
def __init__(self, feature_map, training_dataset, test_dataset=None, datapoints=None, multiclass_extension=None): """Constructor. Args: feature_map (FeatureMap): feature map module, used to transform data training_dataset (dict): training dataset. test_dataset (dict): testing dataset. datapoints (numpy.ndarray): prediction dataset. multiclass_extension (MultiExtension): if number of classes > 2, a multiclass scheme is is needed. Raises: ValueError: if training_dataset is None AquaError: use binary classifer for classes > 3 """ super().__init__() if training_dataset is None: raise ValueError('Training dataset must be provided') is_multiclass = get_num_classes(training_dataset) > 2 if is_multiclass: if multiclass_extension is None: raise AquaError('Dataset has more than two classes. ' 'A multiclass extension must be provided.') else: if multiclass_extension is not None: logger.warning("Dataset has just two classes. " "Supplied multiclass extension will be ignored") self.training_dataset, self.class_to_label = split_dataset_to_data_and_labels( training_dataset) if test_dataset is not None: self.test_dataset = split_dataset_to_data_and_labels( test_dataset, self.class_to_label) else: self.test_dataset = None self.label_to_class = { label: class_name for class_name, label in self.class_to_label.items() } self.num_classes = len(list(self.class_to_label.keys())) self.datapoints = datapoints self.feature_map = feature_map self.num_qubits = self.feature_map.num_qubits if multiclass_extension is None: qsvm_instance = _QSVM_Kernel_Binary(self) else: qsvm_instance = _QSVM_Kernel_Multiclass(self, multiclass_extension) self.instance = qsvm_instance
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AquaError("EnergyInput instance is required.") # For getting the extra operator, caller has to do something like: algo_input.add_aux_op(evo_op) operator = algo_input.qubit_op aux_ops = algo_input.aux_ops if aux_ops is None or len(aux_ops) != 1: raise AquaError( "EnergyInput, a single aux op is required for evaluation.") evo_operator = aux_ops[0] if evo_operator is None: raise AquaError("EnergyInput, invalid aux op.") dynamics_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = dynamics_params.get(EOH.PROP_OPERATOR_MODE) evo_time = dynamics_params.get(EOH.PROP_EVO_TIME) num_time_slices = dynamics_params.get(EOH.PROP_NUM_TIME_SLICES) paulis_grouping = dynamics_params.get(EOH.PROP_PAULIS_GROUPING) expansion_mode = dynamics_params.get(EOH.PROP_EXPANSION_MODE) expansion_order = dynamics_params.get(EOH.PROP_EXPANSION_ORDER) # Set up initial state, we need to add computed num qubits to params initial_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) initial_state_params['num_qubits'] = operator.num_qubits initial_state = get_pluggable_class( PluggableType.INITIAL_STATE, initial_state_params['name']).init_params(initial_state_params) return cls(operator, initial_state, evo_operator, operator_mode, evo_time, num_time_slices, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def __init__(self, num_target_qubits, probabilities, low=0, high=1): super().__init__(num_target_qubits) self._num_values = 2 ** self.num_target_qubits self._probabilities = np.array(probabilities) self._low = low self._high = high self._values = np.linspace(low, high, self.num_values) if self.num_values != len(probabilities): raise AquaError('num qubits and length of probabilities vector do not match!')
def from_params(cls, params): if EnergyInput.PROP_KEY_QUBITOP not in params: raise AquaError("Qubit operator is required.") qparams = params[EnergyInput.PROP_KEY_QUBITOP] qubit_op = Operator.load_from_dict(qparams) if EnergyInput.PROP_KEY_AUXOPS in params: auxparams = params[EnergyInput.PROP_KEY_AUXOPS] aux_ops = [Operator.load_from_dict(auxparams[i]) for i in range(len(auxparams))] return cls(qubit_op, aux_ops)
def validate(self, sections_json): try: logger.debug('JSON Input: {}'.format( json.dumps(sections_json, sort_keys=True, indent=4))) logger.debug('Aqua Input Schema: {}'.format( json.dumps(self._schema, sort_keys=True, indent=4))) jsonschema.validate(sections_json, self._schema) except jsonschema.exceptions.ValidationError as ve: logger.info('JSON Validation error: {}'.format(str(ve))) raise AquaError(ve.message)
def init_params(cls, params, algo_input): if algo_input is not None: raise AquaError("Unexpected Input instance.") bv_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) oracle_params = params.get(QuantumAlgorithm.SECTION_KEY_ORACLE) oracle = get_pluggable_class( PluggableType.ORACLE, oracle_params['name']).init_params(oracle_params) return cls(oracle)
def deregister_pluggable(pluggable_type, pluggable_name): """ Deregisters a pluggable class Args: pluggable_type(PluggableType): The pluggable type pluggable_name (str): The pluggable name Raises: AquaError: if the class is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AquaError('Could not deregister {} {} not registered'.format( pluggable_type, pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AquaError('Could not deregister {} {} not registered'.format( pluggable_type, pluggable_name)) _REGISTERED_PLUGGABLES[pluggable_type].pop(pluggable_name)
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance Args: params: parameters dictionary algo_input: EnergyInput instance """ if algo_input is None: raise AquaError("EnergyInput instance is required.") ee_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) k = ee_params.get('k') return cls(algo_input.qubit_op, k, algo_input.aux_ops)
def __init__(self, operator, state_in, iqft, num_time_slices=1, num_ancillae=1, paulis_grouping='random', expansion_mode='trotter', expansion_order=1, state_in_circuit_factory=None, unitary_circuit_factory=None, shallow_circuit_concat=False): """ Constructor. Args: operator (Operator): 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 paulis_grouping (str): the pauli term grouping mode expansion_mode (str): the expansion mode (trotter|suzuki) expansion_order (int): the suzuki expansion order state_in_circuit_factory (CircuitFactory): the initial state represented by a CircuitFactory object unitary_circuit_factory (CircuitFactory): the problem unitary represented by a CircuitFactory object shallow_circuit_concat (bool): indicate whether to use shallow (cheap) mode for circuit concatenation """ if (operator is not None and unitary_circuit_factory is not None) or ( operator is None and unitary_circuit_factory is None): raise AquaError( 'Please supply either an operator or a unitary circuit factory but not both.' ) self._operator = operator self._unitary_circuit_factory = unitary_circuit_factory self._state_in = state_in self._state_in_circuit_factory = state_in_circuit_factory self._iqft = iqft self._num_time_slices = num_time_slices self._num_ancillae = num_ancillae self._paulis_grouping = paulis_grouping self._expansion_mode = expansion_mode self._expansion_order = expansion_order self._shallow_circuit_concat = shallow_circuit_concat self._ancilla_phase_coef = 1 self._state_register = None self._ancillary_register = None self._auxiliary_register = None self._circuit = None self._ret = {}
def init_params(cls, params, algo_input): """ Initialize via parameters dictionary and algorithm input instance. Args: params (dict): parameters dictionary algo_input (EnergyInput): EnergyInput instance Returns: VQE: vqe object """ if algo_input is None: raise AquaError("EnergyInput instance is required.") operator = algo_input.qubit_op vqe_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = vqe_params.get('operator_mode') initial_point = vqe_params.get('initial_point') batch_mode = vqe_params.get('batch_mode') # Set up initial state, we need to add computed num qubits to params init_state_params = params.get( QuantumAlgorithm.SECTION_KEY_INITIAL_STATE) init_state_params['num_qubits'] = operator.num_qubits init_state = get_pluggable_class( PluggableType.INITIAL_STATE, init_state_params['name']).init_params(init_state_params) # Set up variational form, we need to add computed num qubits, and initial state to params var_form_params = params.get(QuantumAlgorithm.SECTION_KEY_VAR_FORM) var_form_params['num_qubits'] = operator.num_qubits var_form_params['initial_state'] = init_state var_form = get_pluggable_class( PluggableType.VARIATIONAL_FORM, var_form_params['name']).init_params(var_form_params) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_pluggable_class( PluggableType.OPTIMIZER, opt_params['name']).init_params(opt_params) return cls(operator, var_form, optimizer, operator_mode=operator_mode, initial_point=initial_point, batch_mode=batch_mode, aux_operators=algo_input.aux_ops)
def __init__(self, feature_map, training_dataset, test_dataset=None, datapoints=None, multiclass_extension=None): """Constructor. Args: feature_map (FeatureMap): feature map module, used to transform data training_dataset (dict): training dataset. test_dataset (dict): testing dataset. datapoints (numpy.ndarray): prediction dataset. multiclass_extension (MultiExtension): if number of classes > 2, a multiclass scheme is is needed. Raises: ValueError: if training_dataset is None AquaError: use binary classifer for classes > 3 """ super().__init__() if training_dataset is None: raise ValueError('Training dataset must be provided') is_multiclass = get_num_classes(training_dataset) > 2 if is_multiclass: if multiclass_extension is None: raise AquaError( 'Dataset has more than two classes. A multiclass extension must be provided.' ) else: if multiclass_extension is not None: logger.warning( "Dataset has just two classes. Supplied multiclass extension will be ignored" ) if multiclass_extension is None: qsvm_instance = _QSVM_Kernel_Binary(feature_map, self, training_dataset, test_dataset, datapoints) else: qsvm_instance = _QSVM_Kernel_Multiclass(feature_map, self, training_dataset, test_dataset, datapoints, multiclass_extension) self.instance = qsvm_instance
def __init__(self, schema_input): """Create JSONSchema object.""" self._schema = None self._original_schema = None self.aqua_jsonschema = None if isinstance(schema_input, dict): self._schema = copy.deepcopy(schema_input) elif isinstance(schema_input, str): with open(schema_input) as json_file: self._schema = json.load(json_file) else: raise AquaError("Invalid JSONSchema input type.") validator = jsonschema.Draft4Validator(self._schema) self._schema = JSONSchema._resolve_schema_references( validator.schema, validator.resolver) self.commit_changes()
def run(self, quantum_instance=None, **kwargs): """Execute the algorithm with selected backend. Args: quantum_instance (QuantumInstance or BaseBackend): the experiemental setting. Returns: dict: results of an algorithm. """ if not self.configuration.get('classical', False): if quantum_instance is None: AquaError( "Quantum device or backend is needed since you are running quanutm algorithm." ) if isinstance(quantum_instance, BaseBackend): quantum_instance = QuantumInstance(quantum_instance, **kwargs) self._quantum_instance = quantum_instance return self._run()
def build_inverse(self, qc, q, q_ancillas=None, params=None): """ Adds inverse of corresponding sub-circuit to given circuit Args: qc : quantum circuit q : list of qubits (has to be same length as self._num_qubits) q_ancillas : list of ancilla qubits (or None if none needed) params : parameters for circuit """ qc_ = QuantumCircuit(*qc.qregs) self.build(qc_, q, q_ancillas, params) try: qc_.data = [gate.inverse() for gate in reversed(qc_.data)] except Exception as exc: raise AquaError( 'Irreversible circuit! Gate does not support inverse method.' ) from exc qc.extend(qc_)