def build_qaoa_ansatz_circuit( ansatz_specs: Specs, cost_hamiltonian: Union[str, List], mixer_hamiltonian: Union[str, List] = None, params: Optional[Union[str, List]] = None, ): if isinstance(ansatz_specs, str): DeprecationWarning( "Loading ansatz_specs as a string will be depreciated in future, please change it to a dictionary." ) ansatz_specs = json.loads(ansatz_specs) cost_hamiltonian = load_qubit_operator(cost_hamiltonian) if mixer_hamiltonian: mixer_hamiltonian = load_qubit_operator(mixer_hamiltonian) ansatz_specs["cost_hamiltonian"] = cost_hamiltonian ansatz_specs["mixer_hamiltonian"] = mixer_hamiltonian ansatz = load_from_specs(ansatz_specs) if params is not None: if isinstance(params, str): params = load_circuit_template_params(params) else: params = np.array(params) circuit = ansatz.get_executable_circuit(params) elif ansatz.supports_parametrized_circuits: circuit = ansatz.parametrized_circuit else: raise (Exception( "Ansatz is not parametrizable and no parameters has been provided." )) save_circuit(circuit, "circuit.json")
def test_combine_ansatz_params(self, params_filenames): # Given params1_filename, params2_filename = params_filenames # When combine_ansatz_params(params1_filename, params2_filename) # Then try: combined_parameters_filename = "combined-params.json" parameters = load_circuit_template_params(combined_parameters_filename) params1 = load_circuit_template_params(params1_filename) params2 = load_circuit_template_params(params2_filename) assert all(parameters == np.concatenate([params1, params2])) finally: remove_file_if_exists(combined_parameters_filename)
def test_build_ansatz_circuit_with_parameter_values( self, params_filename_and_number_of_layers): # Given params_filename, number_of_layers = params_filename_and_number_of_layers ansatz_specs = { "module_name": "zquantum.core.interfaces.mock_objects", "function_name": "MockAnsatz", "number_of_layers": number_of_layers, "problem_size": 2, } parameters = load_circuit_template_params(params_filename) ansatz = create_object(copy.deepcopy(ansatz_specs)) expected_circuit = ansatz.get_executable_circuit(parameters) # When build_ansatz_circuit(ansatz_specs=ansatz_specs, params=params_filename) # Then try: circuit_filename = "circuit.json" circuit = load_circuit(circuit_filename) assert isinstance(circuit, Circuit) assert circuit == expected_circuit finally: remove_file_if_exists(circuit_filename)
def test_post_current_argument_values(self): params = np.random.random((2,2)) save_circuit_template_params(params, 'proxy_test_current_argument_values_artifact.json') with open('proxy_test_current_argument_values_artifact.json', 'r') as f: data = json.load(f) connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2) # set status to be OPTIMIZING connection.request('POST', '/status', body="OPTIMIZING") response = connection.getresponse() self.assertEqual(response.getcode(), 204) connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(data)) response = connection.getresponse() self.assertEqual(response.getcode(), 200) # decode id from response id_from_argument_value_post = response.read().decode("utf-8") connection.request('GET', '/cost-function-argument-values') response = connection.getresponse() self.assertEqual(response.getcode(), 200) # remove id from response and verify it is correct response_json = json.loads(response.read().decode("utf-8")) response_id = response_json.pop("optimization-evaluation-id") self.assertEqual(id_from_argument_value_post, response_id) # assert argument values are same as above with open('proxy_test_current_argument_values_artifact_from_proxy.json', 'w') as f: f.write(json.dumps(response_json)) new_data_loaded_from_file = load_circuit_template_params('proxy_test_current_argument_values_artifact_from_proxy.json') np.testing.assert_array_equal(params, new_data_loaded_from_file)
def evaluate_operator_for_parameter_grid( ansatz_specs, backend_specs, grid, operator, fixed_parameters="None", ): ansatz = create_object(json.loads(ansatz_specs)) backend = create_object(json.loads(backend_specs)) grid = load_parameter_grid(grid) operator = load_qubit_operator(operator) if fixed_parameters != "None": if type(fixed_parameters) == str: if os.path.exists(fixed_parameters): fixed_parameters = load_circuit_template_params(fixed_parameters) else: fixed_parameters = [] ( parameter_grid_evaluation, optimal_parameters, ) = _evaluate_operator_for_parameter_grid( ansatz, grid, backend, operator, previous_layer_params=fixed_parameters ) save_parameter_grid_evaluation( parameter_grid_evaluation, "parameter-grid-evaluation.json" ) save_circuit_template_params(optimal_parameters, "/app/optimal-parameters.json")
def build_ansatz_circuit(ansatz_specs: Dict, params: str = "None"): ansatz = create_object(json.loads(ansatz_specs)) if params != "None": # TODO Non issue in worklow v1 parameters = load_circuit_template_params(params) circuit = ansatz.get_executable_circuit(parameters) elif ansatz.supports_parametrized_circuits: circuit = ansatz.parametrized_circuit else: raise (Exception( "Ansatz is not parametrizable and no parameters has been provided." )) save_circuit(circuit, "circuit.json")
def evaluate_parametrized_circuit(parametrized_circuit: Union[str, Circuit], parameters: Union[str, np.ndarray]): if isinstance(parametrized_circuit, str): parametrized_circuit = load_circuit(parametrized_circuit) if isinstance(parameters, str): parameters = load_circuit_template_params(parameters) symbols_map = create_symbols_map(parametrized_circuit.symbolic_params, parameters) evaluated_circuit = parametrized_circuit.evaluate(symbols_map) save_circuit(evaluated_circuit, "evaluated-circuit.json")
def evaluate_operator_for_parameter_grid( ansatz_specs: Specs, backend_specs: Specs, grid: Union[str, ParameterGrid], operator: Union[str, SymbolicOperator], fixed_parameters: Union[List[float], np.ndarray, str] = None, ): """Measure the expection values of the terms in an input operator with respect to the states prepared by the input ansatz circuits when set to the different parameters in the input parameter grid on the backend described by the backend_specs. The results are serialized into a JSON under the files: "parameter-grid-evaluation.json" and "optimal-parameters.json" ARGS: ansatz_specs (Union[dict, str]): The ansatz producing the parameterized quantum circuits backend_specs (Union[dict, str]): The backend on which to run the quantum circuit grid (Union[str, ParameterGrid]): The parameter grid describing the different ansatz parameters to use operator (Union[str, SymbolicOperator]): The operator to measure fixed_parameters (Union[List[float], np.ndarray, str]): Any fixed parameter values that the ansatz should be evaluated to that are not described by the parameter grid """ if isinstance(ansatz_specs, str): ansatz_specs = json.loads(ansatz_specs) ansatz = create_object(ansatz_specs) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) backend = create_object(backend_specs) if isinstance(grid, str): grid = load_parameter_grid(grid) if isinstance(operator, str): operator = load_qubit_operator(operator) if fixed_parameters is not None: if isinstance(fixed_parameters, str): fixed_parameters = load_circuit_template_params(fixed_parameters) else: fixed_parameters = [] ( parameter_grid_evaluation, optimal_parameters, ) = _evaluate_operator_for_parameter_grid( ansatz, grid, backend, operator, previous_layer_params=fixed_parameters) save_parameter_grid_evaluation(parameter_grid_evaluation, "parameter-grid-evaluation.json") save_circuit_template_params(optimal_parameters, "optimal-parameters.json")
def evaluate_ansatz_based_cost_function( ansatz_specs: Specs, backend_specs: Specs, cost_function_specs: Specs, ansatz_parameters: Specs, qubit_operator: str, noise_model: Optional[str] = None, device_connectivity: Optional[str] = None, prior_expectation_values: Optional[str] = None, ): ansatz_parameters = load_circuit_template_params(ansatz_parameters) # Load qubit op operator = load_qubit_operator(qubit_operator) if isinstance(ansatz_specs, str): ansatz_specs = json.loads(ansatz_specs) if ansatz_specs["function_name"] == "QAOAFarhiAnsatz": ansatz = create_object(ansatz_specs, cost_hamiltonian=operator) else: ansatz = create_object(ansatz_specs) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) if noise_model is not None: backend_specs["noise_model"] = load_noise_model(noise_model) if device_connectivity is not None: backend_specs["device_connectivity"] = load_circuit_connectivity( device_connectivity) backend = create_object(backend_specs) if isinstance(cost_function_specs, str): cost_function_specs = json.loads(cost_function_specs) estimator_specs = cost_function_specs.pop("estimator-specs", None) if estimator_specs is not None: cost_function_specs["estimator"] = create_object(estimator_specs) cost_function_specs["target_operator"] = operator cost_function_specs["ansatz"] = ansatz cost_function_specs["backend"] = backend cost_function = create_object(cost_function_specs) if prior_expectation_values is not None: if isinstance(prior_expectation_values, str): cost_function.estimator.prior_expectation_values = load_expectation_values( prior_expectation_values) value_estimate = cost_function(ansatz_parameters) save_value_estimate(value_estimate, "value_estimate.json")
def build_ansatz_circuit(ansatz_specs: Specs, params: Optional[Union[str, List]] = None): ansatz = load_from_specs(ansatz_specs) if params is not None: if isinstance(params, str): params = load_circuit_template_params(params) else: params = np.array(params) circuit = ansatz.get_executable_circuit(params) elif ansatz.supports_parametrized_circuits: circuit = ansatz.parametrized_circuit else: raise (Exception( "Ansatz is not parametrizable and no parameters has been provided." )) save_circuit(circuit, "circuit.json")
def optimize_variational_qcbm_circuit( distance_measure_specs, distance_measure_parameters, n_layers, n_qubits, topology, backend_specs, optimizer_specs, initial_parameters, target_distribution, ): if isinstance(distance_measure_specs, str): distance_measure_specs = json.loads(distance_measure_specs) distance_measure = get_func_from_specs(distance_measure_specs) ansatz = QCBMAnsatz(n_layers, n_qubits, topology) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) backend = create_object(backend_specs) if isinstance(optimizer_specs, str): optimizer_specs = json.loads(optimizer_specs) optimizer = create_object(optimizer_specs) initial_parameters = load_circuit_template_params(initial_parameters) target_distribution = load_bitstring_distribution(target_distribution) if isinstance(distance_measure_parameters, str): distance_measure_parameters = json.loads(distance_measure_parameters) cost_function = QCBMCostFunction( ansatz, backend, distance_measure, distance_measure_parameters, target_distribution, ) opt_results = optimizer.minimize(cost_function, initial_parameters) save_optimization_results(opt_results, "qcbm-optimization-results.json") save_circuit_template_params(opt_results.opt_params, "optimized-parameters.json")
def test_generate_random_ansatz_params_using_number_of_parameters( self, number_of_parameters, ): # Given seed = RNDSEED filename = "params.json" remove_file_if_exists(filename) # When generate_random_ansatz_params( number_of_parameters=number_of_parameters, seed=seed) # Then try: parameters = load_circuit_template_params(filename) assert len(parameters) == number_of_parameters finally: remove_file_if_exists(filename)
def evaluate_ansatz_based_cost_function( ansatz_specs: str, backend_specs: str, cost_function_specs: str, ansatz_parameters: str, qubit_operator: str, noise_model="None", device_connectivity="None", ): ansatz_parameters = load_circuit_template_params(ansatz_parameters) # Load qubit op operator = load_qubit_operator(qubit_operator) ansatz_specs = json.loads(ansatz_specs) if ansatz_specs["function_name"] == "QAOAFarhiAnsatz": ansatz = create_object(ansatz_specs, cost_hamiltonian=operator) else: ansatz = create_object(ansatz_specs) backend_specs = json.loads(backend_specs) if noise_model != "None": backend_specs["noise_model"] = load_noise_model(noise_model) if device_connectivity != "None": backend_specs["device_connectivity"] = load_circuit_connectivity( device_connectivity) backend = create_object(backend_specs) cost_function_specs = json.loads(cost_function_specs) estimator_specs = cost_function_specs.pop("estimator-specs", None) if estimator_specs is not None: cost_function_specs["estimator"] = create_object(estimator_specs) cost_function_specs["target_operator"] = operator cost_function_specs["ansatz"] = ansatz cost_function_specs["backend"] = backend cost_function = create_object(cost_function_specs) value_estimate = cost_function(ansatz_parameters) save_value_estimate(value_estimate, "value_estimate.json")
def test_generate_random_ansatz_params_using_mock_ansatz_specs( self, number_of_layers): # Given ansatz_specs = { "module_name": "zquantum.core.interfaces.mock_objects", "function_name": "MockAnsatz", "number_of_layers": number_of_layers, "problem_size": 2, } seed = RNDSEED filename = "params.json" remove_file_if_exists(filename) # When generate_random_ansatz_params(ansatz_specs=ansatz_specs, seed=seed) # Then try: parameters = load_circuit_template_params(filename) assert len(parameters) == number_of_layers finally: remove_file_if_exists(filename)
def return_x_squared(self): params = load_circuit_template_params(io.StringIO(self.parameters)) return sum(params**2)
def combine_ansatz_params(params1: str, params2: str): parameters1 = load_circuit_template_params(params1) parameters2 = load_circuit_template_params(params2) combined_params = _combine_ansatz_params(parameters1, parameters2) save_circuit_template_params(combined_params, "combined-params.json")
def return_x_squared(self): return load_circuit_template_params(io.StringIO(self.parameters))[0]**2
def optimize_parametrized_circuit_for_ground_state_of_operator( optimizer_specs: Specs, target_operator: Union[SymbolicOperator, str], parametrized_circuit: Union[Circuit, str], backend_specs: Specs, estimator_specs: Optional[Specs] = None, estimator_kwargs: Optional[Union[Dict, str]] = None, initial_parameters: Union[str, np.ndarray, List[float]] = None, fixed_parameters: Optional[Union[np.ndarray, str]] = None, parameter_precision: Optional[float] = None, parameter_precision_seed: Optional[int] = None, ): """Optimize the parameters of a parametrized quantum circuit to prepare the ground state of a target operator. Args: optimizer_specs (Union[Dict, str]): The specs of the optimizer to use to refine the parameter values target_operator (Union[SymbolicOperator, str]): The operator of which to prepare the ground state parametrized_circuit (Union[Circuit, str]): The parametrized quantum circuit that prepares trial states backend_specs (Union[Dict, str]): The specs of the quantum backend (or simulator) to use to run the circuits estimator_specs (Union[Dict, str]): The estimator to use to estimate the expectation value of the operator. The default is the BasicEstimator. estimator_kwargs (dict): kwargs required to run get_estimated_expectation_values method of the estimator. initial_parameters (Union[str, np.ndarray, List[float]]): The initial parameter values to begin optimization fixed_parameters (Optional[Union[np.ndarray, str]]): values for the circuit parameters that should be fixed. parameter_precision (float): the standard deviation of the Gaussian noise to add to each parameter, if any. parameter_precision_seed (int): seed for randomly generating parameter deviation if using parameter_precision initial_parameters (Union[str, np.ndarray, List[float]] = None, """ if estimator_kwargs is not None: if isinstance(estimator_kwargs, str): estimator_kwargs = json.loads(estimator_kwargs) estimator = create_object(estimator_kwargs) else: estimator_kwargs = {} if isinstance(optimizer_specs, str): optimizer_specs = json.loads(optimizer_specs) optimizer = create_object(optimizer_specs) if isinstance(target_operator, str): with open(target_operator, "r") as f: target_operator = json.loads(f.read()) if isinstance(parametrized_circuit, str): parametrized_circuit = load_circuit(parametrized_circuit) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) backend = create_object(backend_specs) if estimator_specs is not None: if isinstance(estimator_specs, str): estimator_specs = json.loads(estimator_specs) estimator = create_object(estimator_specs) else: estimator = BasicEstimator() if initial_parameters is not None: if isinstance(initial_parameters, str): initial_parameters = load_circuit_template_params( initial_parameters) if fixed_parameters is not None: if isinstance(fixed_parameters, str): fixed_parameters = load_circuit_template_params(fixed_parameters) cost_function = get_ground_state_cost_function( target_operator, parametrized_circuit, backend, estimator=estimator, estimator_kwargs=estimator_kwargs, fixed_parameters=fixed_parameters, parameter_precision=parameter_precision, parameter_precision_seed=parameter_precision_seed, ) optimization_results = optimizer.minimize(cost_function, initial_parameters) save_optimization_results(optimization_results, "optimization_results.json")
def evaluate_ansatz_based_cost_function( ansatz_specs: Specs, backend_specs: Specs, cost_function_specs: Specs, ansatz_parameters: str, qubit_operator: str, noise_model: Optional[str] = None, device_connectivity: Optional[str] = None, prior_expectation_values: Optional[str] = None, ): ansatz_parameters = load_circuit_template_params(ansatz_parameters) # Load qubit op operator = load_qubit_operator(qubit_operator) if isinstance(ansatz_specs, str): ansatz_specs = json.loads(ansatz_specs) if ansatz_specs["function_name"] == "QAOAFarhiAnsatz": ansatz = create_object(ansatz_specs, cost_hamiltonian=operator) else: ansatz = create_object(ansatz_specs) if isinstance(backend_specs, str): backend_specs = json.loads(backend_specs) if noise_model is not None: backend_specs["noise_model"] = load_noise_model(noise_model) if device_connectivity is not None: backend_specs["device_connectivity"] = load_circuit_connectivity( device_connectivity) backend = create_object(backend_specs) if isinstance(cost_function_specs, str): cost_function_specs = json.loads(cost_function_specs) if prior_expectation_values is not None: if isinstance(prior_expectation_values, str): prior_expectation_values = load_expectation_values( prior_expectation_values) estimator_specs = cost_function_specs.pop("estimator-specs", None) if estimator_specs is not None: if isinstance(estimator_specs, str): estimator_specs = json.loads(estimator_specs) cost_function_specs["estimator"] = create_object(estimator_specs) estimation_preprocessors_specs = cost_function_specs.pop( "estimation-tasks-transformations-specs", None) if estimation_preprocessors_specs is not None: cost_function_specs["estimation_preprocessors"] = [] for estimation_tasks_transformation_specs in estimation_preprocessors_specs: if isinstance(estimation_tasks_transformation_specs, str): estimation_tasks_transformation_specs = json.loads( estimation_tasks_transformation_specs) if prior_expectation_values is not None: # Since we don't know which estimation task transformation uses prior_expectation_values, # we add it to the kwargs of each one. If not used by a particular transformer, it will be ignored. estimation_tasks_transformation_specs[ "prior_expectation_values"] = prior_expectation_values cost_function_specs["estimation_preprocessors"].append( create_object(estimation_tasks_transformation_specs)) # cost_function.estimator.prior_expectation_values cost_function_specs["target_operator"] = operator cost_function_specs["ansatz"] = ansatz cost_function_specs["backend"] = backend cost_function = create_object(cost_function_specs) value_estimate = cost_function(ansatz_parameters) save_value_estimate(value_estimate, "value_estimate.json")
def optimize_variational_circuit( ansatz_specs, backend_specs, optimizer_specs, cost_function_specs, qubit_operator, initial_parameters="None", fixed_parameters="None", noise_model="None", device_connectivity="None", parameter_grid="None", constraint_operator="None", ): if initial_parameters != "None": initial_params = load_circuit_template_params(initial_parameters) else: initial_params = None if fixed_parameters != "None": fixed_params = load_circuit_template_params(fixed_parameters) else: fixed_params = None # Load qubit operator operator = load_qubit_operator(qubit_operator) if isinstance(ansatz_specs, str): ansatz_specs_dict = yaml.load(ansatz_specs, Loader=yaml.SafeLoader) else: ansatz_specs_dict = ansatz_specs if ansatz_specs_dict["function_name"] == "QAOAFarhiAnsatz": ansatz = create_object(ansatz_specs_dict, cost_hamiltonian=operator) else: ansatz = create_object(ansatz_specs_dict) # Load parameter grid if parameter_grid != "None": grid = load_parameter_grid(parameter_grid) else: grid = None # Load optimizer specs if isinstance(optimizer_specs, str): optimizer_specs_dict = yaml.load(optimizer_specs, Loader=yaml.SafeLoader) else: optimizer_specs_dict = optimizer_specs if (grid is not None and optimizer_specs_dict["function_name"] == "GridSearchOptimizer"): optimizer = create_object(optimizer_specs_dict, grid=grid) else: optimizer = create_object(optimizer_specs_dict) # Load backend specs if isinstance(backend_specs, str): backend_specs_dict = yaml.load(backend_specs, Loader=yaml.SafeLoader) else: backend_specs_dict = backend_specs if noise_model != "None": backend_specs_dict["noise_model"] = load_noise_model(noise_model) if device_connectivity != "None": backend_specs_dict["device_connectivity"] = load_circuit_connectivity( device_connectivity) backend = create_object(backend_specs_dict) # Load cost function specs if isinstance(cost_function_specs, str): cost_function_specs_dict = yaml.load(cost_function_specs, Loader=yaml.SafeLoader) else: cost_function_specs_dict = cost_function_specs estimator_specs = cost_function_specs_dict.pop("estimator-specs", None) if estimator_specs is not None: cost_function_specs_dict["estimator"] = create_object(estimator_specs) cost_function_specs_dict["target_operator"] = operator cost_function_specs_dict["ansatz"] = ansatz cost_function_specs_dict["backend"] = backend cost_function_specs_dict["fixed_parameters"] = fixed_params cost_function = create_object(cost_function_specs_dict) if constraint_operator != "None": constraint_op = load_qubit_operator(constraint_operator) constraints_cost_function_specs = yaml.load(cost_function_specs, Loader=yaml.SafeLoader) constraints_estimator_specs = constraints_cost_function_specs.pop( "estimator-specs", None) if constraints_estimator_specs is not None: constraints_cost_function_specs["estimator"] = create_object( constraints_estimator_specs) constraints_cost_function_specs["ansatz"] = ansatz constraints_cost_function_specs["backend"] = backend constraints_cost_function_specs["target_operator"] = constraint_op constraint_cost_function = create_object( constraints_cost_function_specs) constraint_cost_function_wrapper = ( lambda params: constraint_cost_function.evaluate(params).value) constraint_functions = ({ "type": "eq", "fun": constraint_cost_function_wrapper }, ) optimizer.constraints = constraint_functions opt_results = optimizer.minimize(cost_function, initial_params) save_optimization_results(opt_results, "optimization-results.json") save_circuit_template_params(opt_results.opt_params, "optimized-parameters.json")