コード例 #1
0
ファイル: utils_test.py プロジェクト: clausia/z-quantum-core
    def test_value_estimate_to_string(self):
        value = -1.0
        precision = 0.1
        value_estimate = ValueEstimate(value, precision)
        assert str(value_estimate) == f"{value} ± {precision}"

        value_estimate_no_precision = ValueEstimate(value)
        assert str(value_estimate_no_precision) == f"{value}"
コード例 #2
0
    def __call__(self, parameters: np.ndarray) -> ValueEstimate:
        """Evaluates the value of the cost function for given parameters.

        Args:
            parameters: parameters for which the evaluation should occur.

        Returns:
            value: cost function value for given parameters.
        """
        full_parameters = parameters.copy()
        if self.fixed_parameters is not None:
            full_parameters = combine_ansatz_params(self.fixed_parameters,
                                                    parameters)
        if self.parameter_precision is not None:
            rng = np.random.default_rng(self.parameter_precision_seed)
            noise_array = rng.normal(0.0, self.parameter_precision,
                                     len(full_parameters))
            full_parameters += noise_array

        circuit = self.ansatz.get_executable_circuit(full_parameters)
        expectation_values = self.estimator.get_estimated_expectation_values(
            self.backend,
            circuit,
            self.target_operator,
            n_samples=self.n_samples,
            epsilon=self.epsilon,
            delta=self.delta,
        )
        return ValueEstimate(np.sum(expectation_values.values))
コード例 #3
0
def evaluate_qubit_operator(
        qubit_operator: QubitOperator,
        expectation_values: ExpectationValues) -> ValueEstimate:
    """Evaluate the expectation value of a qubit operator using
	expectation values for the terms.

	Args:
		qubit_operator (openfermion.QubitOperator): the operator
		expectation_values (core.measurement.ExpectationValues): the expectation values

	Returns:
		value_estimate (zquantum.core.utils.ValueEstimate): stores the value of the expectation and its
			 precision
	"""

    # Sum the contributions from all terms
    total = 0

    # Add all non-trivial terms
    term_index = 0
    for term in qubit_operator.terms:
        total += np.real(qubit_operator.terms[term] *
                         expectation_values.values[term_index])
        term_index += 1

    value_estimate = ValueEstimate(total)
    return value_estimate
コード例 #4
0
    def cost_function(parameters: np.ndarray,
                      store_artifact: StoreArtifact = None) -> ValueEstimate:
        """
        Evaluates the value of the cost function for given parameters.

        Args:
            parameters: parameters for which the evaluation should occur.
            store_artifact: callable defining how the bitstring distributions should be stored.
        """
        # TODO: we use private method here due to performance reasons.
        # This should be fixed once better mechanism for handling it will be implemented.
        # In case of questions ask mstechly.
        # circuit = ansatz.get_executable_circuit(parameters)
        circuit = ansatz._generate_circuit(parameters)
        distribution = backend.get_bitstring_distribution(circuit, n_samples)
        value = evaluate_distribution_distance(
            target_bitstring_distribution,
            distribution,
            distance_measure,
            distance_measure_parameters=distance_measure_parameters,
        )

        if store_artifact:
            store_artifact("bitstring_distribution", distribution)

        return ValueEstimate(value)
コード例 #5
0
    def cost_function(parameters: np.ndarray,
                      store_artifact: StoreArtifact = None) -> ValueEstimate:
        """
        Evaluates the value of the cost function for given parameters.

        Args:
            parameters: parameters for which the evaluation should occur.

        Returns:
            (float): cost function value for given parameters
            zquantum.core.bitstring_distribution.BitstringDistribution: distribution obtained
        """
        circuit = ansatz.get_executable_circuit(parameters)
        distribution = backend.get_bitstring_distribution(circuit)
        value = evaluate_distribution_distance(
            target_bitstring_distribution,
            distribution,
            distance_measure,
            distance_measure_parameters=distance_measure_parameters,
        )

        if store_artifact:
            store_artifact("bitstring_distribution", distribution)

        return ValueEstimate(value)
コード例 #6
0
def test_value_estimate_with_specified_precision_is_not_equal_to_its_raw_value(
):
    value = 6.193
    estimate = ValueEstimate(value, precision=4)

    assert value != estimate
    assert estimate != value
コード例 #7
0
def solve_relaxed_qubo(
    qubo,
    optimizer_specs=None,
    number_of_trials=10,
    symmetrize_matrix=True,
):
    qubo = load_qubo(qubo)

    qubo_matrix = qubo.to_numpy_matrix().astype(float)
    if symmetrize_matrix:
        qubo_matrix = (qubo_matrix + qubo_matrix.T) / 2

    if is_matrix_positive_semidefinite(qubo_matrix):
        solution, optimal_value = solve_qp_problem_for_psd_matrix(
            qubo_matrix, symmetrize_matrix)
    else:
        if optimizer_specs is None:
            raise ValueError(
                "For qubo with semipositive definite matrix, an optimizer must be provided."
            )
        optimizer = create_object(optimizer_specs)
        solution, optimal_value = solve_qp_problem_with_optimizer(
            qubo_matrix, optimizer, number_of_trials, symmetrize_matrix)

    save_list(solution.tolist(), "solution.json")
    save_value_estimate(ValueEstimate(optimal_value), "energy.json")
コード例 #8
0
 def get_evaluation_result(self, id):
     # make cost function result
     result = ValueEstimate(self.cost_func())
     save_value_estimate(result, 'client_mock_evaluation_result.json')
     with open('client_mock_evaluation_result.json', 'r') as f:
         result_data = json.load(f)
     result_data["optimization-evaluation-id"] = "MOCKED-ID"
     return json.JSONEncoder().encode(result_data)
コード例 #9
0
ファイル: utils_test.py プロジェクト: clausia/z-quantum-core
def test_value_estimate_with_no_precision_is_equivalent_to_its_raw_value():
    value = 6.193
    estimate = ValueEstimate(value)

    # Note that it is not that obvious that this comparison is symmetric, since we override
    # the __eq__ method in ValueEstimate. The same goes about __ne__ method in the next test.
    assert value == estimate
    assert estimate == value
コード例 #10
0
def evaluate_operator_for_parameter_grid(ansatz,
                                         grid,
                                         backend,
                                         operator,
                                         previous_layer_params=[]):
    """Evaluate the expectation value of an operator for every set of circuit
    parameters in the parameter grid.

    Args:
        ansatz (dict): the ansatz
        grid (zquantum.core.circuit.ParameterGrid): The parameter grid containing
            the parameters for the last layer of the ansatz
        backend (zquantum.core.interfaces.backend.QuantumSimulator): the backend
            to run the circuits on
        operator (openfermion.ops.QubitOperator): the operator
        previous_layer_params (array): A list of the parameters for previous layers
            of the ansatz

    Returns:
        value_estimate (zquantum.core.utils.ValueEstimate): stores the value of the expectation and its
             precision
        optimal_parameters (numpy array): the ansatz parameters representing the ansatz parameters
            resulting in the best minimum evaluation. If multiple sets of parameters evaluate to the same value,
            the first set of parameters is chosen as the optimal.
    """
    parameter_grid_evaluation = []
    circuitset = []
    params_set = []
    for last_layer_params in grid.params_list:
        # Build the ansatz circuit
        params = np.concatenate(
            (np.asarray(previous_layer_params), np.asarray(last_layer_params)))

        # Build the ansatz circuit
        circuitset.append(ansatz.get_executable_circuit(params))
        params_set.append(params)

    expectation_values_set = backend.get_expectation_values_for_circuitset(
        circuitset, operator)

    min_value_estimate = None
    for params, expectation_values in zip(params_set, expectation_values_set):
        expectation_values = expectation_values_to_real(expectation_values)
        value_estimate = ValueEstimate(sum(expectation_values.values))
        parameter_grid_evaluation.append({
            "value": value_estimate,
            "parameter1": params[-2],
            "parameter2": params[-1],
        })

        if min_value_estimate is None:
            min_value_estimate = value_estimate
            optimal_parameters = params
        elif value_estimate.value < min_value_estimate.value:
            min_value_estimate = value_estimate
            optimal_parameters = params

    return parameter_grid_evaluation, optimal_parameters
コード例 #11
0
ファイル: utils_test.py プロジェクト: clausia/z-quantum-core
def test_arithmetic_on_value_estimate_and_float_gives_the_same_result_as_arithmetic_on_two_floats():
    value = 5.1
    estimate = ValueEstimate(value, precision=None)
    other = 3.4

    assert estimate + other == value + other
    assert estimate - other == value - other
    assert estimate * other == value * other
    assert estimate / other == value / other
コード例 #12
0
def test_arithmetic_on_value_estimate_and_float():
    value = 5.1
    estimate = ValueEstimate(value, precision=None)
    other = 3.4

    assert estimate + other == value + other
    assert estimate - other == value - other
    assert estimate * other == value * other
    assert estimate / other == value / other
コード例 #13
0
    def test_post_result(self):
        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # POST argument values to allow proxy to verify that id that comes in with
        # result POST are correct
        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:
            arg_val_data = json.load(f)

        # set status to be OPTIMIZING in order to POST argument values
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST argument values
        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(arg_val_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)
        # decode id from response
        id_from_argument_value_post = response.read().decode("utf-8")

        # set status to be EVALUATING
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # make cost function result
        result = ValueEstimate(1.5,10.0)
        save_value_estimate(result, 'proxy_test_results_artifact.json')
        with open('proxy_test_results_artifact.json', 'r') as f:
            result_data = json.load(f)
        result_data["optimization-evaluation-id"] = id_from_argument_value_post
        
        # POST cost function result
        connection.request('POST', '/cost-function-results', body=json.JSONEncoder().encode(result_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # GET cost function result
        connection.request('GET', '/cost-function-results', body=id_from_argument_value_post)
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)

        # remove id from response and verify it is correct
        response_string = response.read().decode("utf-8")
        response_json = json.loads(response_string)
        response_id = response_json.pop("optimization-evaluation-id")
        self.assertEqual(id_from_argument_value_post, response_id)

        # assert result is same as above
        with open('proxy_test_results_artifact_from_proxy.json', 'w') as f:
            f.write(json.dumps(response_json))
        new_data_loaded_from_file = load_value_estimate('proxy_test_results_artifact_from_proxy.json')
        self.assertEqual(result.value, new_data_loaded_from_file.value)
        self.assertEqual(result.precision, new_data_loaded_from_file.precision)
コード例 #14
0
def jw_get_ground_state_at_particle_number(particle_number, qubit_operator):
    qubit_operator = load_qubit_operator(qubit_operator)
    sparse_matrix = qubit_operator_sparse(qubit_operator)

    ground_energy, ground_state_amplitudes = _jw_get_ground_state_at_particle_number(
        sparse_matrix, particle_number
    )
    ground_state = Wavefunction(ground_state_amplitudes)
    value_estimate = ValueEstimate(ground_energy)

    save_wavefunction(ground_state, "ground-state.json")
    save_value_estimate(value_estimate, "value-estimate.json")
コード例 #15
0
    def test_value_estimate_io(self):
        # Given
        value = -1.0
        precision = 0.1
        value_estimate_object = ValueEstimate(value, precision)

        # When
        save_value_estimate(value_estimate_object, "value_estimate.json")
        value_estimate_object_loaded = load_value_estimate(
            "value_estimate.json")

        # Then
        assert value_estimate_object.value == value_estimate_object_loaded.value
        assert value_estimate_object.precision == value_estimate_object_loaded.precision

        # Given
        value_estimate_object = ValueEstimate(value)
        # When
        save_value_estimate(value_estimate_object, "value_estimate.json")
        value_estimate_object_loaded = load_value_estimate(
            "value_estimate.json")
        # Then
        assert value_estimate_object.value == value_estimate_object_loaded.value
        assert value_estimate_object.precision == value_estimate_object_loaded.precision

        # Given
        value = np.float64(-1.0)
        precision = np.float64(0.1)
        value_estimate_object = ValueEstimate(value, precision)

        # When
        save_value_estimate(value_estimate_object, "value_estimate.json")
        value_estimate_object_loaded = load_value_estimate(
            "value_estimate.json")

        # Then
        assert value_estimate_object.value == value_estimate_object_loaded.value
        assert value_estimate_object.precision == value_estimate_object_loaded.precision

        remove_file_if_exists("value_estimate.json")
コード例 #16
0
    def test_evaluate(self):
        # Given
        client = MockedClient(self.ipaddress, self.port, "return_x_squared")
        params = np.array([4])
        cost_function = ProxyCostFunction(client)
        target_value = ValueEstimate(16)

        # When
        value = cost_function(params)

        # Then
        self.assertEqual(value, target_value)
        os.remove("client_mock_evaluation_result.json")
        os.remove("current_optimization_params.json")
コード例 #17
0
def solve_qubo(qubo, solver_specs, solver_params=None):
    """Solves qubo using any sampler implementing either dimod.Sampler or zquantum.qubo.BQMSolver"""
    if solver_params is None:
        solver_params = {}
    solver = create_object(solver_specs)
    qubo = load_qubo(qubo)

    sampleset = solver.sample(qubo, **solver_params)
    best_sample_dict = sampleset.first.sample
    solution_bitstring = tuple(best_sample_dict[i] for i in sorted(best_sample_dict))
    lowest_energy = evaluate_bitstring_for_qubo(solution_bitstring, qubo)

    save_value_estimate(ValueEstimate(lowest_energy), "lowest-energy.json")
    Measurements([solution_bitstring]).save("solution.json")
    save_sampleset(sampleset, "sampleset.json")
コード例 #18
0
    def test_unsuccessful_post_result_wrong_status(self):
        connection = http.client.HTTPConnection(self.ipaddress+":"+str(self.listening_port), timeout=2)

        # POST argument values to allow proxy to verify that argument values that come in with
        # Value POST are correct
        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:
            arg_val_data = json.load(f)

        # set status to be OPTIMIZING in order to POST argument values
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST argument values
        connection.request('POST', '/cost-function-argument-values', body=json.JSONEncoder().encode(arg_val_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 200)
        # decode id from response
        id_from_argument_value_post = response.read().decode("utf-8")

        # set status to be EVALUATING
        connection.request('POST', '/status', body="EVALUATING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # make cost function result
        result = ValueEstimate(1.5,10.0)
        save_value_estimate(result, 'proxy_test_results_artifact.json')
        with open('proxy_test_results_artifact.json', 'r') as f:
            result_data = json.load(f)
        result_data["optimization-evaluation-id"] = id_from_argument_value_post
        
        # set status to be OPTIMIZING - new results should not be able to
        # be posted while that is the status
        connection.request('POST', '/status', body="OPTIMIZING")
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 204)

        # POST cost function result
        connection.request('POST', '/cost-function-results', body=json.JSONEncoder().encode(result_data))
        response = connection.getresponse()
        self.assertEqual(response.getcode(), 409)
        response_lower = response.read().decode("utf-8").lower()
        self.assertTrue(response_lower.find('error') != -1)
        self.assertTrue(response_lower.find('status') != -1)
        self.assertTrue(response_lower.find('evaluating') != -1)
コード例 #19
0
 def cost_function(params):
     # build the ansatz circuit
     qcbm_circuit = build_qcbm_circuit_ion_trap(n_qubits,
                                                params,
                                                single_qubit_gate,
                                                static_entangler,
                                                topology=topology)
     measured_distr = backend.get_bitstring_distribution(qcbm_circuit)
     distribution_history.append(measured_distr)
     value_estimate = ValueEstimate(
         evaluate_distribution_distance(
             target_bitstring_distribution,
             measured_distr,
             distance_measure,
             epsilon=epsilon,
         ))
     return value_estimate.value
コード例 #20
0
ファイル: evaluation.py プロジェクト: kottmanj/z-quantum-core
def jw_get_ground_state_at_particle_number(
        particle_number: int, qubit_operator: Union[str, SymbolicOperator]):
    """Get the ground state wavefunction of the operator for the input particle number. Outputs are serialized to JSON
    within the files: "ground-state.json" and "value-estimate.json"

    ARGS:
        particle_number (int): The given number of particles in the system
        qubit_operator (Union[str, SymbolicOperator]): The operator for which to find the ground state
    """
    if isinstance(qubit_operator, str):
        qubit_operator = load_qubit_operator(qubit_operator)
    sparse_matrix = qubit_operator_sparse(qubit_operator)

    ground_energy, ground_state_amplitudes = _jw_get_ground_state_at_particle_number(
        sparse_matrix, particle_number)
    ground_state = Wavefunction(ground_state_amplitudes)
    value_estimate = ValueEstimate(ground_energy)

    save_wavefunction(ground_state, "ground-state.json")
    save_value_estimate(value_estimate, "value-estimate.json")
コード例 #21
0
def evaluate_operator_for_parameter_grid(ansatz,
                                         grid,
                                         backend,
                                         operator,
                                         previous_layer_params=[]):
    """Evaluate the expectation value of an operator for every set of circuit
	parameters in the parameter grid.

	Args:
		ansatz (dict): the ansatz
		grid (zquantum.core.circuit.ParameterGrid): The parameter grid containing
			the parameters for the last layer of the ansatz
        backend (zquantum.core.interfaces.backend.QuantumSimulator): the backend 
			to run the circuits on 
		operator (openfermion.ops.QubitOperator): the operator
		previous_layer_params (array): A list of the parameters for previous layers
			of the ansatz

	Returns:
		value_estimate (zquantum.core.utils.ValueEstimate): stores the value of the expectation and its
			 precision
	"""
    parameter_grid_evaluation = []
    for last_layer_params in grid.params_list:
        # Build the ansatz circuit
        params = np.concatenate(
            (np.asarray(previous_layer_params), np.asarray(last_layer_params)))

        # Build the ansatz circuit
        circuit = build_ansatz_circuit(ansatz, params)

        expectation_values = backend.get_expectation_values(circuit, operator)
        value_estimate = ValueEstimate(sum(expectation_values.values))
        parameter_grid_evaluation.append({
            'value': value_estimate,
            'parameter1': last_layer_params[0],
            'parameter2': last_layer_params[1]
        })

    return parameter_grid_evaluation
コード例 #22
0
    def __call__(self, parameters: np.ndarray) -> ValueEstimate:
        """Evaluates the value of the cost function for given parameters.

        Args:
            parameters: parameters for which the evaluation should occur.

        Returns:
            value: cost function value for given parameters.
        """
        if self.fixed_parameters is not None:
            parameters = combine_ansatz_params(self.fixed_parameters,
                                               parameters)
        circuit = self.ansatz.get_executable_circuit(parameters)
        expectation_values = self.estimator.get_estimated_expectation_values(
            self.backend,
            circuit,
            self.target_operator,
            n_samples=self.n_samples,
            epsilon=self.epsilon,
            delta=self.delta,
        )
        return ValueEstimate(np.sum(expectation_values.values))
コード例 #23
0
)
from zquantum.core.utils import ValueEstimate, convert_array_to_dict

# The result constructed below does not make sense.
# It does not matter though, as we are only testing serialization and it contains variety
# of data to be serialized.
EXAMPLE_OPTIMIZATION_RESULT = optimization_result(
    opt_value=0.5,
    opt_params=np.array([0, 0.5, 2.5]),
    nit=3,
    fev=10,
    history=[
        HistoryEntry(
            call_number=0,
            params=np.array([0.1, 0.2, 0.3j]),
            value=ValueEstimate(0.5, precision=6),
        ),
        HistoryEntry(call_number=1, params=np.array([1, 2, 3]), value=-10.0),
        HistoryEntryWithArtifacts(
            call_number=2,
            params=np.array([-1, -0.5, -0.6]),
            value=-20.0,
            artifacts={
                "bitstring":
                "0111",
                "bitstring_distribution":
                BitstringDistribution({
                    "111": 0.25,
                    "010": 0.75
                }),
            },
コード例 #24
0
ファイル: utils_test.py プロジェクト: clausia/z-quantum-core
    assert value == estimate
    assert estimate == value


def test_value_estimate_with_specified_precision_is_not_equal_to_its_raw_value():
    value = 6.193
    estimate = ValueEstimate(value, precision=4)

    assert value != estimate
    assert estimate != value


@pytest.mark.parametrize(
    "estimate_1,estimate_2,expected_result",
    [
        (ValueEstimate(14.1), ValueEstimate(14.1), True),
        (ValueEstimate(12.3, 3), ValueEstimate(12.3, 3), True),
        (ValueEstimate(14.1, 5), ValueEstimate(14.1, 4), False),
        (ValueEstimate(2.5, 3), ValueEstimate(2.5), False),
        (ValueEstimate(0.15, 3), ValueEstimate(1.1, 3), False),
    ],
)
def test_two_value_estimates_are_equal_iff_their_values_and_precisions_are_equal(
    estimate_1, estimate_2, expected_result
):
    assert (estimate_1 == estimate_2) == expected_result


@pytest.mark.parametrize(
    "estimate", [ValueEstimate(2.0), ValueEstimate(5.0, precision=1e-5)]
)