def init_args(self, training_dataset, test_dataset, datapoints, feature_map, multiclass_extension=None): if training_dataset is None: raise AlgorithmError('Training dataset must be provided') is_multiclass = get_num_classes(training_dataset) > 2 if is_multiclass: if multiclass_extension is None: raise AlgorithmError('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() else: qsvm_instance = QSVM_Kernel_Multiclass(multiclass_extension) if datapoints is not None: if not isinstance(datapoints, np.ndarray): datapoints = np.asarray(datapoints) qsvm_instance.init_args(training_dataset, test_dataset, datapoints, feature_map, self) self.instance = qsvm_instance
def __init__(self, configuration=None): self._configuration = configuration if 'problems' not in configuration or len( configuration['problems']) <= 0: raise AlgorithmError( 'Algorithm Input missing or empty configuration problems') for problem in configuration['problems']: if problem not in AlgorithmInput._PROBLEM_SET: raise AlgorithmError( 'Problem {} not in known problem set {}'.format( problem, AlgorithmInput._PROBLEM_SET))
def _auto_detect_qubitnum(self, training_dataset): auto_detected_size = -1 for key, val in training_dataset.items(): for item in val: auto_detected_size = len(item) break if auto_detected_size == -1: raise AlgorithmError( 'Something wrong in detecting required qubits, please check your data set.' ) if auto_detected_size != 2 and auto_detected_size != 3: raise AlgorithmError( 'You should lower the feature dimension to 2 or 3 first!') return auto_detected_size
def init_params(self, 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 AlgorithmError("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_initial_state_instance(init_state_params['name']) init_state.init_params(init_state_params) self.init_args(operator, init_state, num_time_slices, num_iterations, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def init_args(self, training_dataset, test_dataset, datapoints, optimizer, feature_map, var_form): """Initialize the object Args: training_dataset (dict): {'A': numpy.ndarray, 'B': numpy.ndarray, ...} test_dataset (dict): the same format as `training_dataset` datapoints (numpy.ndarray): NxD array, N is the number of data and D is data dimension optimizer (Optimizer): Optimizer instance feature_map (FeatureMap): FeatureMap instance var_form (VariationalForm): VariationalForm instance Notes: We used `label` denotes numeric results and `class` means the name of that class (str). """ if 'statevector' in self._backend: raise ValueError('Selected backend "{}" is not supported.'.format(self._backend)) if training_dataset is None: raise AlgorithmError('Training dataset must be provided') 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) 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._optimizer = optimizer self._feature_map = feature_map self._var_form = var_form self._num_qubits = self._feature_map.num_qubits
def init_params(self, params, algo_input): if algo_input.training_dataset is None: raise AlgorithmError("Training dataset is required.") fea_map_params = params.get(QuantumAlgorithm.SECTION_KEY_FEATURE_MAP) feature_map = get_feature_map_instance(fea_map_params['name']) num_qubits = get_feature_dimension(algo_input.training_dataset) fea_map_params['num_qubits'] = num_qubits feature_map.init_params(fea_map_params) is_multiclass = get_num_classes(algo_input.training_dataset) > 2 if is_multiclass: multicls_ext_params = params.get( QuantumAlgorithm.SECTION_KEY_MULTICLASS_EXTENSION) multiclass_extension = get_multiclass_extension_instance( multicls_ext_params['name']) # we need to set this explicitly for quantum version multicls_ext_params['params'] = [feature_map, self] multicls_ext_params['estimator_cls'] = QKernalSVM_Estimator multiclass_extension.init_params(multicls_ext_params) logger.info("Multiclass classifcation algo:" + multicls_ext_params['name']) else: logger.warning( "Only two classes in the dataset, use binary classifer" " and ignore all options of multiclass_extension") multiclass_extension = None self.init_args(algo_input.training_dataset, algo_input.test_dataset, algo_input.datapoints, feature_map, multiclass_extension)
def init_params(self, 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 AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op qaoa_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = qaoa_params.get(QAOA.PROP_OPERATOR_MODE) p = qaoa_params.get(QAOA.PROP_P) initial_point = qaoa_params.get(QAOA.PROP_INIT_POINT) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) if 'statevector' not in self._backend and operator_mode == 'matrix': logger.debug('Qasm simulation does not work on {} mode, changing \ the operator_mode to paulis'.format(operator_mode)) operator_mode = 'paulis' self.init_args(operator, operator_mode, p, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops)
def init_params(self, 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 AlgorithmError("EnergyInput instance is required.") operator = algo_input.qubit_op qaoa_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = qaoa_params.get(QAOA.PROP_OPERATOR_MODE) p = qaoa_params.get(QAOA.PROP_P) initial_point = qaoa_params.get(QAOA.PROP_INIT_POINT) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) self.init_args(operator, operator_mode, p, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops)
def check_property_value(self, section_name, property_name, value): """ Check value for property name Params: section_name (string): section name property_name (string): property name value (obj): value 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 AlgorithmError( "{}.{} Value '{}' is not of types: '{}'".format( section_name, property_name, value, types)) return value
def init_params(self, params, algo_input): svm_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) if algo_input.training_dataset is None: raise AlgorithmError( 'Training dataset is required! please provide it') is_multiclass = get_num_classes(algo_input.training_dataset) > 2 if is_multiclass: multiclass_extension_params = params.get( QuantumAlgorithm.SECTION_KEY_MULTICLASS_EXTENSION) multiclass_extension = get_multiclass_extension_instance( multiclass_extension_params['name']) multiclass_extension_params['estimator_cls'] = RBF_SVC_Estimator multiclass_extension.init_params(multiclass_extension_params) logger.info("Multiclass classifcation algo:" + multiclass_extension_params['name']) else: logger.warning( "Only two classes in the dataset, use binary classifer" " and ignore all options of multiclass_extension") multiclass_extension = None self.init_args(algo_input.training_dataset, algo_input.test_dataset, algo_input.datapoints, svm_params.get('gamma'), multiclass_extension)
def set_default_properties_for_name(self, section_name): if self._parser is None: raise AlgorithmError('Input not initialized.') name = self._parser.get_section_property(section_name, InputParser.NAME) self._parser.delete_section_properties(section_name) value = self._parser.get_section_default_properties(section_name) if name is not None: self._parser.set_section_property(section_name, InputParser.NAME, name) if isinstance(value, dict): for property_name, property_value in value.items(): if property_name != InputParser.NAME: self._parser.set_section_property(section_name, property_name, property_value) else: if value is None: types = self._parser.get_section_types(section_name) if 'null' not in types: if 'string' in types: value = '' elif 'object' in types: value = {} elif 'array' in types: value = [] self._parser.set_section_data(section_name, value)
def set_section(self, section_name): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.set_section(section_name) value = self._parser.get_section_default_properties(section_name) if isinstance(value, dict): for property_name, property_value in value.items(): self._parser.set_section_property(section_name, property_name, property_value) # do one more time in case schema was updated value = self._parser.get_section_default_properties(section_name) for property_name, property_value in value.items(): self._parser.set_section_property(section_name, property_name, property_value) else: if value is None: types = self._parser.get_section_types(section_name) if 'null' not in types: if 'string' in types: value = '' elif 'object' in types: value = {} elif 'array' in types: value = [] self._parser.set_section_data(section_name, value)
def format_property_name(property_name): if property_name is None: property_name = '' property_name = property_name.strip() if len(property_name) == 0: raise AlgorithmError("Empty property name.") return property_name
def _register_pluggable(pluggable_type, cls, configuration=None): """ Registers a pluggable class Args: pluggable_type(str): The pluggable type cls (object): Pluggable class. configuration (object, optional): Pluggable configuration Returns: name: pluggable name Raises: AlgorithmError: if the class is already registered or could not be registered """ if pluggable_type not in _REGISTERED_PLUGGABLES: _REGISTERED_PLUGGABLES[pluggable_type] = {} # 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 AlgorithmError( 'Could not register class {} is already registered'.format(cls)) try: pluggable_instance = cls(configuration=configuration) except Exception as err: raise AlgorithmError( 'Could not register puggable:{} could not be instantiated: {}'. format(cls, str(err))) # Verify that it has a minimal valid configuration. try: pluggable_name = pluggable_instance.configuration['name'] except (LookupError, TypeError): raise AlgorithmError( 'Could not register pluggable: invalid configuration') if pluggable_name in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError( '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, pluggable_instance.configuration) return pluggable_name
def init_params(self, params, algo_input): if algo_input is None: raise AlgorithmError("EnergyInput instance is required.") algo_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) timelimit = algo_params['timelimit'] thread = algo_params['thread'] display = algo_params['display'] self.init_args(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 AlgorithmError("Empty section name.") return section_name
def delete_section_property(self, section_name, property_name): if self._parser is None: raise AlgorithmError('Input not initialized.') self._parser.delete_section_property(section_name, property_name) if property_name == InputParser.NAME and \ (InputParser.is_pluggable_section(section_name) or section_name == InputParser.INPUT): self._parser.delete_section_properties(section_name)
def init_params(self, 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 AlgorithmError("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 AlgorithmError( "EnergyInput, a single aux op is required for evaluation.") evo_operator = aux_ops[0] if evo_operator is None: raise AlgorithmError("EnergyInput, invalid aux op.") dynamics_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) operator_mode = dynamics_params.get(Dynamics.PROP_OPERATOR_MODE) evo_time = dynamics_params.get(Dynamics.PROP_EVO_TIME) num_time_slices = dynamics_params.get(Dynamics.PROP_NUM_TIME_SLICES) paulis_grouping = dynamics_params.get(Dynamics.PROP_PAULIS_GROUPING) expansion_mode = dynamics_params.get(Dynamics.PROP_EXPANSION_MODE) expansion_order = dynamics_params.get(Dynamics.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_initial_state_instance( initial_state_params['name']) initial_state.init_params(initial_state_params) self.init_args(operator, operator_mode, initial_state, evo_operator, evo_time, num_time_slices, paulis_grouping=paulis_grouping, expansion_mode=expansion_mode, expansion_order=expansion_order)
def validate(self, sections_json): try: logger.debug('JSON Input: {}'.format( json.dumps(sections_json, sort_keys=True, indent=4))) logger.debug('Aqua Chemistry 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 AlgorithmError(ve.message)
def from_params(self, params): if EnergyInput.PROP_KEY_QUBITOP not in params: raise AlgorithmError("Qubit operator is required.") qparams = params[EnergyInput.PROP_KEY_QUBITOP] self._qubit_op = Operator.load_from_dict(qparams) if EnergyInput.PROP_KEY_AUXOPS in params: auxparams = params[EnergyInput.PROP_KEY_AUXOPS] self._aux_ops = [ Operator.load_from_dict(auxparams[i]) for i in range(len(auxparams)) ]
def deregister_pluggable(pluggable_type, pluggable_name): """ Deregisters a pluggable class Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('Could not deregister {} {} not registered'.format( pluggable_type, pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('Could not deregister {} {} not registered'.format( pluggable_type, pluggable_name)) _REGISTERED_PLUGGABLES[pluggable_type].pop(pluggable_name)
def init_args(self, training_dataset, test_dataset, datapoints, gamma, multiclass_extension=None): if training_dataset is None: raise AlgorithmError('Training dataset must be provided') is_multiclass = get_num_classes(training_dataset) > 2 if is_multiclass: if multiclass_extension is None: raise AlgorithmError('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() else: svm_instance = SVM_Classical_Multiclass(multiclass_extension) svm_instance.init_args(training_dataset, test_dataset, datapoints, gamma) self.instance = svm_instance
def get_pluggable_instance(pluggable_type, pluggable_name): """ Instantiates a pluggable class Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Returns: instance: pluggable instance """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} {} not registered'.format( pluggable_type, pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('{} {} not registered'.format( pluggable_type, pluggable_name)) return _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].cls( configuration=_REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].configuration)
def init_params(self, 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 AlgorithmError("EnergyInput instance is required.") ee_params = params.get(QuantumAlgorithm.SECTION_KEY_ALGORITHM) k = ee_params.get(ExactEigensolver.PROP_K) self.init_args(algo_input.qubit_op, k, algo_input.aux_ops)
def register_input(cls, configuration=None): """ Registers an input class Args: cls (object): Input class. configuration (object, optional): Pluggable configuration Returns: name: input name Raises: AlgorithmError: if the class is already registered or could not be registered """ _discover_on_demand() # Verify that the pluggable is not already registered if cls in [input.cls for input in _REGISTERED_INPUTS.values()]: raise AlgorithmError( 'Could not register class {} is already registered'.format(cls)) try: input_instance = cls(configuration=configuration) except Exception as err: raise AlgorithmError( 'Could not register input:{} could not be instantiated: {}'.format( cls, str(err))) # Verify that it has a minimal valid configuration. try: input_name = input_instance.configuration['name'] except (LookupError, TypeError): raise AlgorithmError('Could not register input: invalid configuration') if input_name in _REGISTERED_INPUTS: raise AlgorithmError( 'Could not register class {}. Name {} {} is already registered'. format(cls, input_name, _REGISTERED_INPUTS[input_name].cls)) # Append the pluggable to the `registered_classes` dict. _REGISTERED_INPUTS[input_name] = RegisteredInput( input_name, cls, input_instance.configuration) return input_name
def get_pluggable_configuration(pluggable_type, pluggable_name): """ Accesses pluggable configuration Args: pluggable_type(str): The pluggable type pluggable_name (str): The pluggable name Returns: configuration: pluggable configuration Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} {} not registered'.format( pluggable_type, pluggable_name)) if pluggable_name not in _REGISTERED_PLUGGABLES[pluggable_type]: raise AlgorithmError('{} {} not registered'.format( pluggable_type, pluggable_name)) return _REGISTERED_PLUGGABLES[pluggable_type][pluggable_name].configuration
def deregister_input(input_name): """ Deregisters am input class Args: input_name(str): The input name Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if input_name not in _REGISTERED_INPUTS: raise AlgorithmError( 'Could not deregister {} not registered'.format(input_name)) _REGISTERED_INPUTS.pop(input_name)
def local_pluggables(pluggable_type): """ Accesses pluggable names Args: pluggable_type(str): The pluggable type Returns: names: pluggable names Raises: AlgorithmError: if the tyoe is not registered """ _discover_on_demand() if pluggable_type not in _REGISTERED_PLUGGABLES: raise AlgorithmError('{} not registered'.format(pluggable_type)) return [pluggable.name for pluggable in _REGISTERED_PLUGGABLES[pluggable_type].values()]
def init_params(self, 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 AlgorithmError("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') # 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_initial_state_instance(init_state_params['name']) init_state.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_variational_form_instance(var_form_params['name']) var_form.init_params(var_form_params) # Set up optimizer opt_params = params.get(QuantumAlgorithm.SECTION_KEY_OPTIMIZER) optimizer = get_optimizer_instance(opt_params['name']) optimizer.init_params(opt_params) if 'statevector' not in self._backend and operator_mode == 'matrix': logger.debug('Qasm simulation does not work on {} mode, changing \ the operator_mode to paulis'.format(operator_mode)) operator_mode = 'paulis' self.init_args(operator, operator_mode, var_form, optimizer, opt_init_point=initial_point, aux_operators=algo_input.aux_ops) logger.info(self.print_setting())
def get_input_configuration(input_name): """ Accesses input configuration Args: input_name (str): The input name Returns: configuration: input configuration Raises: AlgorithmError: if the class is not registered """ _discover_on_demand() if input_name not in _REGISTERED_INPUTS: raise AlgorithmError('{} not registered'.format(input_name)) return _REGISTERED_INPUTS[input_name].configuration