示例#1
0
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")
示例#2
0
    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)
示例#3
0
    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)
示例#4
0
    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)
示例#5
0
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")
示例#6
0
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")
示例#7
0
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")
示例#8
0
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")
示例#9
0
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")
示例#10
0
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")
示例#11
0
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")
示例#12
0
    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)
示例#13
0
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")
示例#14
0
    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)
示例#16
0
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")
示例#17
0
 def return_x_squared(self):
     return load_circuit_template_params(io.StringIO(self.parameters))[0]**2
示例#18
0
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")
示例#19
0
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")
示例#20
0
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")