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")
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)
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)
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)
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)
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")
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)
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")