Example #1
0
    def test_add_ancilla_register_to_circuit_artifact_file(
            self, circuit_filename_and_number_of_ancilla_qubits):
        # Given
        (
            circuit_filename,
            number_of_ancilla_qubits,
        ) = circuit_filename_and_number_of_ancilla_qubits
        expected_extended_circuit_filename = "extended-circuit.json"

        with open(circuit_filename) as f:
            circuit = new_circuits.circuit_from_dict(json.load(f))
        expected_extended_circuit = new_circuits.add_ancilla_register(
            circuit, number_of_ancilla_qubits)

        # When
        add_ancilla_register_to_circuit(number_of_ancilla_qubits,
                                        circuit_filename)

        # Then
        try:
            with open(expected_extended_circuit_filename) as f:
                extended_circuit = new_circuits.circuit_from_dict(json.load(f))
            assert (extended_circuit.n_qubits == circuit.n_qubits +
                    number_of_ancilla_qubits)
            assert extended_circuit == expected_extended_circuit
        finally:
            remove_file_if_exists(expected_extended_circuit_filename)
def get_expectation_values_for_qubit_operator(
    backend_specs: Specs,
    circuit: Union[str, Circuit, Dict],
    qubit_operator: Union[str, SymbolicOperator, Dict],
):
    """Measure the expectation values of the terms in an input operator with respect to
    the state prepared by the input circuit on the backend described by the
    `backend_specs`. The results are serialized into a JSON under the file:
    "expectation-values.json"

    Args:
        backend_specs: The backend on which to run the quantum circuit
        circuit: The circuit that prepares the state to be measured
        qubit_operator: The operator to measure
    """
    if isinstance(circuit, str):
        circuit = load_circuit(circuit)
    elif isinstance(circuit, dict):
        circuit = circuit_from_dict(circuit)
    if isinstance(qubit_operator, str):
        qubit_operator = load_qubit_operator(qubit_operator)
    elif isinstance(qubit_operator, dict):
        qubit_operator = convert_dict_to_qubitop(qubit_operator)
    if isinstance(backend_specs, str):
        backend_specs = json.loads(backend_specs)
    backend = cast(QuantumBackend, create_object(backend_specs))

    estimation_tasks = [
        EstimationTask(qubit_operator, circuit, backend.n_samples)
    ]

    expectation_values = estimate_expectation_values_by_averaging(
        backend, estimation_tasks)

    save_expectation_values(expectation_values[0], "expectation-values.json")
Example #3
0
    def test_add_ancilla_register_to_circuit_python_object(
            self, number_of_ancilla_qubits):
        # Given
        number_of_qubits = 4
        number_of_gates = 10
        circuit = new_circuits.create_random_circuit(
            number_of_qubits,
            number_of_gates,
            rng=np.random.default_rng(RNDSEED),
        )
        expected_extended_cirucit = new_circuits.add_ancilla_register(
            copy.deepcopy(circuit), number_of_ancilla_qubits)
        expected_extended_circuit_filename = "extended-circuit.json"

        # When
        circuit = add_ancilla_register_to_circuit(number_of_ancilla_qubits,
                                                  circuit)

        # Then
        try:
            with open(expected_extended_circuit_filename) as f:
                extended_circuit = new_circuits.circuit_from_dict(json.load(f))
            assert (extended_circuit.n_qubits == number_of_qubits +
                    number_of_ancilla_qubits)
            assert extended_circuit == expected_extended_cirucit
        finally:
            remove_file_if_exists(expected_extended_circuit_filename)
Example #4
0
    def test_create_random_circuit(self, number_of_qubits, number_of_gates,
                                   seed):
        # Given
        expected_filename = "circuit.json"
        expected_circuit = new_circuits.create_random_circuit(
            number_of_qubits,
            number_of_gates,
            rng=np.random.default_rng(seed),
        )

        # When
        create_random_circuit(
            number_of_qubits=number_of_qubits,
            number_of_gates=number_of_gates,
            seed=seed,
        )

        # Then
        try:
            with open(expected_filename) as f:
                circuit = new_circuits.circuit_from_dict(json.load(f))
            if seed is not None:
                assert circuit.operations == expected_circuit.operations
            else:
                assert circuit.operations != expected_circuit.operations
        finally:
            remove_file_if_exists(expected_filename)
Example #5
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)
Example #6
0
    def test_concatenate_circuits_python_objects(self, circuit_set):
        # Given
        expected_concatenated_circuit_filename = "result-circuit.json"
        expected_concatenated_circuit = sum(
            [circuit for circuit in circuit_set], new_circuits.Circuit())

        # When
        concatenate_circuits(circuit_set)

        # Then
        try:
            with open(expected_concatenated_circuit_filename) as f:
                concatenated_circuit = new_circuits.circuit_from_dict(
                    json.load(f))
            assert concatenated_circuit == expected_concatenated_circuit
        finally:
            remove_file_if_exists(expected_concatenated_circuit_filename)
Example #7
0
    def test_batch_circuits_all_artifacts_no_circuit_set(
            self, input_circuits_filenames):
        # Given
        expected_circuitset_filename = "circuit-set.json"
        expected_circuitset = []
        for circuit_filename in input_circuits_filenames:
            with open(circuit_filename) as f:
                circuit = new_circuits.circuit_from_dict(json.load(f))
            expected_circuitset.append(circuit)

        # When
        batch_circuits(input_circuits_filenames)

        # Then
        try:
            with open(expected_circuitset_filename) as f:
                circuitset = new_circuits.circuitset_from_dict(json.load(f))
            assert circuitset == expected_circuitset
        finally:
            remove_file_if_exists(expected_circuitset_filename)
def run_circuit_and_measure(
    backend_specs: Specs,
    circuit: Union[str, Dict],
    n_samples: Optional[int] = None,
    noise_model: Optional[str] = None,
    device_connectivity: Optional[str] = None,
):
    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(circuit, str):
        circuit = circuits.load_circuit(circuit)
    else:
        circuit = circuits.circuit_from_dict(circuit)

    measurements = backend.run_circuit_and_measure(circuit, n_samples=n_samples)
    measurements.save("measurements.json")
Example #9
0
    def test_build_ansatz_circuit_ansatz_specs_as_string(self):
        # Given
        number_of_layers = 2
        ansatz_specs = {
            "module_name": "zquantum.core.interfaces.mock_objects",
            "function_name": "MockAnsatz",
            "number_of_layers": number_of_layers,
            "problem_size": 2,
        }

        ansatz = create_object(copy.deepcopy(ansatz_specs))
        expected_circuit = ansatz.parametrized_circuit

        # When
        build_ansatz_circuit(ansatz_specs=json.dumps(ansatz_specs))

        # 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)
Example #10
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")