Exemple #1
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_array(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"
            with open(circuit_filename) as f:
                circuit = new_circuits.circuit_from_dict(json.load(f))
            assert circuit == expected_circuit
        finally:
            remove_file_if_exists(circuit_filename)
Exemple #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_array(combined_parameters_filename)
            params1 = load_array(params1_filename)
            params2 = load_array(params2_filename)
            assert all(parameters == np.concatenate([params1, params2]))
        finally:
            remove_file_if_exists(combined_parameters_filename)
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 = serialization.load_array(parameters)

    symbols_map = create_symbols_map(parametrized_circuit.symbolic_params,
                                     parameters)
    bound_circuit = parametrized_circuit.bind(symbols_map)
    save_circuit(bound_circuit, "evaluated-circuit.json")
Exemple #4
0
def optimize_variational_qcbm_circuit(
    distance_measure_specs,
    distance_measure_parameters,
    n_layers,
    n_qubits,
    n_samples,
    topology,
    backend_specs,
    optimizer_specs,
    initial_parameters,
    target_distribution,
    keep_history,
    gradient_type = "finite_difference",
    gradient_kwargs = None,
):

    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_array(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,
        n_samples,
        distance_measure,
        distance_measure_parameters,
        target_distribution,
        gradient_type,
        gradient_kwargs
    )
    opt_results = optimizer.minimize(cost_function, initial_parameters, keep_history)

    save_optimization_results(opt_results, "qcbm-optimization-results.json")
    save_array(opt_results.opt_params, "optimized-parameters.json")
def build_ansatz_circuit(ansatz_specs: Specs,
                         params: Optional[Union[str, List]] = None):
    ansatz = load_from_specs(ansatz_specs)
    params_array: np.ndarray
    if params is not None:
        if isinstance(params, str):
            params_array = serialization.load_array(params)
        else:
            params_array = np.array(params)
        circuit = ansatz.get_executable_circuit(params_array)
    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")
Exemple #6
0
    def test_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_array(filename)
            assert len(parameters) == number_of_parameters
        finally:
            remove_file_if_exists(filename)
Exemple #7
0
    def test_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_array(filename)
            assert len(parameters) == number_of_layers
        finally:
            remove_file_if_exists(filename)
Exemple #8
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,
    thetas: 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)
    ansatz_specs["cost_hamiltonian"] = cost_hamiltonian
    if mixer_hamiltonian:
        mixer_hamiltonian = load_qubit_operator(mixer_hamiltonian)
        ansatz_specs["mixer_hamiltonian"] = mixer_hamiltonian
    if thetas:
        thetas = np.array(load_list(thetas))
        ansatz_specs["thetas"] = thetas

    ansatz = load_from_specs(ansatz_specs)
    if params is not None:
        if isinstance(params, str):
            params = load_array(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 combine_ansatz_params(params1: str, params2: str):
    parameters1 = serialization.load_array(params1)
    parameters2 = serialization.load_array(params2)
    combined_params = ansatz_utils.combine_ansatz_params(
        parameters1, parameters2)
    serialization.save_array(combined_params, "combined-params.json")
def evaluate_ansatz_based_cost_function(
    ansatz_specs: Specs,
    backend_specs: Specs,
    cost_function_specs: Specs,
    ansatz_parameters: str,
    target_operator: Union[str, openfermion.SymbolicOperator],
    estimation_method_specs: Optional[Specs] = None,
    estimation_preprocessors_specs: Optional[List[Specs]] = None,
    noise_model: Optional[str] = None,
    device_connectivity: Optional[str] = None,
    prior_expectation_values: Optional[str] = None,
    estimation_tasks_transformations_kwargs: Optional[Dict] = None,
):
    # Empty dict as default is bad
    if estimation_tasks_transformations_kwargs is None:
        estimation_tasks_transformations_kwargs = {}
    ansatz_parameters = load_array(ansatz_parameters)
    # Load qubit op
    if isinstance(target_operator, str):
        operator = load_qubit_operator(target_operator)
    else:
        operator = target_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"] = layouts.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 (
        "estimator-specs" in cost_function_specs.keys()
        or "estimation-tasks-transformations-specs" in cost_function_specs.keys()
    ):
        raise RuntimeError(
            "Estimation-related specs should be separate arguments and not in "
            "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)

    if estimation_method_specs is not None:
        if isinstance(estimation_method_specs, str):
            estimation_method_specs = json.loads(estimation_method_specs)
        estimation_method = create_object(estimation_method_specs)
    else:
        estimation_method = estimate_expectation_values_by_averaging

    cost_function_specs["estimation_method"] = estimation_method

    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,
                    **estimation_tasks_transformations_kwargs
                )
            )

    # 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")
Exemple #11
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,
    estimation_method_specs: Optional[Specs] = None,
    estimation_preprocessors_specs: Optional[List[Specs]] = 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,
    keep_history: bool = True,
    **kwargs,
):
    """Optimize the parameters of a parametrized quantum circuit to prepare the ground
    state of a target operator.

    Args:
        optimizer_specs: The specs of the optimizer to use to refine the parameter
            values
        target_operator: The operator of which to prepare the ground state
        parametrized_circuit: The parametrized quantum circuit that prepares trial
            states
        backend_specs: The specs of the quantum backend (or simulator) to use to run the
            circuits
        estimation_method_specs: A reference to a callable to use to estimate the
            expectation value of the operator. The default is the
            estimate_expectation_values_by_averaging function.
        estimation_preprocessors_specs: A list of Specs that describe callable functions
            that adhere to the EstimationPreprocessor protocol.
        initial_parameters: The initial parameter values to begin optimization
        fixed_parameters: values for the circuit parameters that should be fixed.
        parameter_precision: the standard deviation of the Gaussian noise to add to each
            parameter, if any.
        parameter_precision_seed: seed for randomly generating parameter deviation if
            using parameter_precision
        keep_history: flag indicating whether to store optimization history.
        kwargs: unused, exists for compatibility
    """
    if isinstance(optimizer_specs, str):
        optimizer_specs = json.loads(optimizer_specs)

    optimizer = create_object(optimizer_specs)

    if isinstance(target_operator, str):
        target_operator = load_qubit_operator(target_operator)

    if isinstance(parametrized_circuit, str):
        with open(parametrized_circuit) as f:
            parametrized_circuit = new_circuits.circuit_from_dict(json.load(f))

    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = create_object(backend_specs)

    if estimation_method_specs is not None:
        if isinstance(estimation_method_specs, str):
            estimation_method_specs = json.loads(estimation_method_specs)
        estimation_method = create_object(estimation_method_specs)
    else:
        estimation_method = estimate_expectation_values_by_averaging

    estimation_preprocessors = []
    if estimation_preprocessors_specs is not None:
        for estimation_preprocessor_specs in estimation_preprocessors_specs:
            if isinstance(estimation_preprocessor_specs, str):
                estimation_preprocessor_specs = json.loads(
                    estimation_preprocessor_specs)
            estimation_preprocessors.append(
                create_object(estimation_preprocessor_specs))

    if initial_parameters is not None:
        if isinstance(initial_parameters, str):
            initial_parameters = load_array(initial_parameters)

    if fixed_parameters is not None:
        if isinstance(fixed_parameters, str):
            fixed_parameters = load_array(fixed_parameters)

    cost_function = get_ground_state_cost_function(
        target_operator,
        parametrized_circuit,
        backend,
        estimation_method=estimation_method,
        estimation_preprocessors=estimation_preprocessors,
        fixed_parameters=fixed_parameters,
        parameter_precision=parameter_precision,
        parameter_precision_seed=parameter_precision_seed,
    )

    optimization_results = optimizer.minimize(cost_function,
                                              initial_parameters, keep_history)

    save_optimization_results(optimization_results,
                              "optimization-results.json")
    save_array(optimization_results.opt_params, "optimized-parameters.json")
Exemple #12
0
def optimize_ansatz_based_cost_function(
    optimizer_specs: Specs,
    target_operator: Union[SymbolicOperator, str],
    ansatz_specs: Specs,
    backend_specs: Specs,
    estimation_method_specs: Optional[Specs] = None,
    estimation_preprocessors_specs: Optional[List[Specs]] = 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,
    keep_history: bool = False,
    **kwargs,
):
    """Optimize the parameters of an ansatz circuit to prepare the ground state of a
    target operator.

    Args:
        optimizer_specs: The specs of the optimizer to use to refine the parameter
            values
        target_operator: The operator of which to prepare the ground state
        ansatz_specs: The specs describing an Ansatz which will prepare the quantum
            circuit
        backend_specs: The specs of the quantum backend (or simulator) to use to run the
            circuits
        estimation_method_specs: A reference to a callable to use to estimate the
            expectation value of the operator. The default is the
            estimate_expectation_values_by_averaging function.
        estimation_preprocessors_specs: A list of Specs that describe callable functions
            that adhere to the EstimationPreprocessor protocol.
        initial_parameters: The initial parameter values to begin optimization
        fixed_parameters: values for the circuit parameters that should be fixed.
        parameter_precision: the standard deviation of the Gaussian noise to add to each
            parameter, if any.
        parameter_precision_seed: seed for randomly generating parameter deviation if
            using parameter_precision
        keep_history: flag indicating whether to store optimization history.
        kwargs:
            The following key word arguments are handled explicitly when appropriate:
                - thetas: A list of thetas used to initialize the WarmStartQAOAAnsatz
    """
    if isinstance(optimizer_specs, str):
        optimizer_specs = json.loads(optimizer_specs)

    optimizer = create_object(optimizer_specs)

    if isinstance(target_operator, str):
        target_operator = load_qubit_operator(target_operator)

    if isinstance(ansatz_specs, str):
        ansatz_specs = json.loads(ansatz_specs)

    if "WarmStartQAOAAnsatz" in ansatz_specs["function_name"]:
        ansatz_specs["thetas"] = np.array(load_list(kwargs.pop("thetas")))
        ansatz_specs["cost_hamiltonian"] = target_operator
    elif "QAOA" in ansatz_specs["function_name"]:
        ansatz_specs["cost_hamiltonian"] = target_operator
    ansatz = create_object(ansatz_specs)

    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = create_object(backend_specs)

    if estimation_method_specs is not None:
        if isinstance(estimation_method_specs, str):
            estimation_method_specs = json.loads(estimation_method_specs)
        estimation_method = create_object(estimation_method_specs)
    else:
        estimation_method = estimate_expectation_values_by_averaging

    estimation_preprocessors = []
    if estimation_preprocessors_specs is not None:
        for estimation_preprocessor_specs in estimation_preprocessors_specs:
            if isinstance(estimation_preprocessor_specs, str):
                estimation_preprocessor_specs = json.loads(
                    estimation_preprocessor_specs)
            estimation_preprocessors.append(
                create_object(estimation_preprocessor_specs))

    if initial_parameters is not None:
        if isinstance(initial_parameters, str):
            initial_parameters = load_array(initial_parameters)

    if fixed_parameters is not None:
        if isinstance(fixed_parameters, str):
            fixed_parameters = load_array(fixed_parameters)

    cost_function = AnsatzBasedCostFunction(
        target_operator,
        ansatz,
        backend,
        estimation_method=estimation_method,
        estimation_preprocessors=estimation_preprocessors,
        fixed_parameters=fixed_parameters,
        parameter_precision=parameter_precision,
        parameter_precision_seed=parameter_precision_seed,
    )

    optimization_results = optimizer.minimize(cost_function,
                                              initial_parameters, keep_history)

    save_optimization_results(optimization_results,
                              "optimization-results.json")
    save_array(optimization_results.opt_params, "optimized-parameters.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",
    parameter_values_list=None,
    constraint_operator="None",
    prior_expectation_values: Optional[str] = None,
    keep_history=False,
    thetas=None,
):
    warnings.warn(
        "optimize_variational_circuit will be depreciated in favor of optimize_ansatz_based_cost_function in steps/optimize.py in z-quantum-core.",
        DeprecationWarning,
    )
    if initial_parameters != "None":
        initial_params = load_array(initial_parameters)
    else:
        initial_params = None

    if fixed_parameters != "None":
        fixed_params = load_array(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 "WarmStartQAOAAnsatz" in ansatz_specs_dict["function_name"]:
        thetas = np.array(load_list(thetas))
        ansatz = create_object(ansatz_specs_dict,
                               cost_hamiltonian=operator,
                               thetas=thetas)
    elif "QAOA" in ansatz_specs_dict["function_name"]:
        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 parameter values list
    if parameter_values_list is not None:
        parameter_values_list = load_array(parameter_values_list)

    # 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)
    elif (parameter_values_list is not None and
          optimizer_specs_dict["function_name"] == "SearchPointsOptimizer"):
        optimizer = create_object(optimizer_specs_dict,
                                  parameter_values_list=parameter_values_list)
    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
    estimation_method_specs = cost_function_specs_dict.pop(
        "estimation_method_specs", None)

    if estimation_method_specs is not None:
        if isinstance(estimation_method_specs, str):
            estimation_method_specs = yaml.loads(estimation_method_specs)
        estimation_method = create_object(estimation_method_specs)
    else:
        estimation_method = estimate_expectation_values_by_averaging
    cost_function_specs_dict["estimation_method"] = estimation_method

    estimation_preprocessors_specs_list = cost_function_specs_dict.pop(
        "estimation_preprocessors_specs", None)
    if estimation_preprocessors_specs_list is not None:
        estimation_preprocessors = []
        for estimation_preprocessor_specs in estimation_preprocessors_specs_list:
            if isinstance(estimation_preprocessor_specs, str):
                estimation_preprocessor_specs = yaml.loads(
                    estimation_preprocessor_specs)
            estimation_preprocessors.append(
                create_object(estimation_preprocessor_specs))
        cost_function_specs_dict[
            "estimation_preprocessors"] = estimation_preprocessors

    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 prior_expectation_values is not None:
        if isinstance(prior_expectation_values, str):
            cost_function.estimator.prior_expectation_values = load_expectation_values(
                prior_expectation_values)

    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,
                                     keep_history)

    save_optimization_results(opt_results, "optimization-results.json")
    save_array(opt_results.opt_params, "optimized-parameters.json")