def test_ansatz_circuit_two_layers(self, number_of_qubits, topology): # Given number_of_layers = 2 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=number_of_qubits, topology=topology, ) params = [ np.ones(2 * number_of_qubits), np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)), ] expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[0][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RZ(params[0][i + number_of_qubits], i) ) expected_circuit = Circuit(expected_pycircuit) expected_circuit += get_entangling_layer( params[1], number_of_qubits, "XX", topology ) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit
def test_ansatz_circuit_two_layers(self, n_qubits, topology): # Given number_of_layers = 2 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=n_qubits, topology=topology, ) params = [ np.random.rand(2 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), ] expected_circuit = Circuit([ # First layer *[RX(params[0][i])(i) for i in range(n_qubits)], *[RZ(params[0][i + n_qubits])(i) for i in range(n_qubits)], # Second layer *get_entangling_layer(params[1], n_qubits, XX, topology).operations, ]) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit
def test_ansatz_circuit_nine_layers(self, n_qubits, topology): # Given number_of_layers = 9 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=n_qubits, topology=topology, ) params = [ np.random.rand(2 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), np.random.rand(2 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), np.random.rand(2 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), np.random.rand(3 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), np.random.rand(2 * n_qubits), ] expected_circuit = Circuit([ # First layer *[RX(params[0][i])(i) for i in range(n_qubits)], *[RZ(params[0][i + n_qubits])(i) for i in range(n_qubits)], # Second layer *get_entangling_layer(params[1], n_qubits, XX, topology).operations, # Third layer *[RX(params[2][i])(i) for i in range(n_qubits)], *[RZ(params[2][i + n_qubits])(i) for i in range(n_qubits)], # Fouth layer *get_entangling_layer(params[3], n_qubits, XX, topology).operations, # Fifth layer *[RX(params[4][i])(i) for i in range(n_qubits)], *[RZ(params[4][i + n_qubits])(i) for i in range(n_qubits)], # Sixth layer *get_entangling_layer(params[5], n_qubits, XX, topology).operations, # Seventh layer *[RX(params[6][i])(i) for i in range(n_qubits)], *[RZ(params[6][i + n_qubits])(i) for i in range(n_qubits)], *[RX(params[6][i + 2 * n_qubits])(i) for i in range(n_qubits)], # Eigth layer *get_entangling_layer(params[7], n_qubits, XX, topology).operations, # Ningth layer *[RZ(params[8][i])(i) for i in range(n_qubits)], *[RX(params[8][i + n_qubits])(i) for i in range(n_qubits)], ]) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit
def setUp(self): number_of_layers = 1 number_of_qubits = 4 topology = "all" self.ansatz = QCBMAnsatz(number_of_layers, number_of_qubits, topology) self.target_bitstring_distribution = BitstringDistribution({ "0000": 1.0, "0001": 0.0, "0010": 0.0, "0011": 1.0, "0100": 0.0, "0101": 1.0, "0110": 0.0, "0111": 0.0, "1000": 0.0, "1001": 0.0, "1010": 1.0, "1011": 0.0, "1100": 1.0, "1101": 0.0, "1110": 0.0, "1111": 1.0, }) self.backend = create_object({ "module_name": "zquantum.core.interfaces.mock_objects", "function_name": "MockQuantumSimulator", "n_samples": 1, }) self.gradient_types = ["finite_difference"]
def test_get_executable_circuit_too_many_parameters( self, n_qubits, topology): # Given params = [ np.random.rand(2 * n_qubits), np.random.rand(int((n_qubits * (n_qubits - 1)) / 2)), np.random.rand(2 * n_qubits), ] params = np.concatenate(params) ansatz = QCBMAnsatz( number_of_layers=2, number_of_qubits=n_qubits, topology=topology, ) # When/Then with pytest.raises(ValueError): ansatz.get_executable_circuit(params),
def test_qubit_count_list_params(self, n_qubits, list, n_connections): # Given test_ansatz = QCBMAnsatz( 1, n_qubits, "graph", adjacency_list=list, ) # When assert test_ansatz.n_params_per_ent_layer == n_connections
def test_ansatz_circuit_one_layer(self, n_qubits, topology): # Given number_of_layers = 1 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=n_qubits, topology=topology, ) params = [np.random.rand(n_qubits)] expected_circuit = Circuit() for i in range(n_qubits): expected_circuit += RX(params[0][i])(i) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit
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 test_ansatz_circuit_one_layer(self, number_of_qubits, topology): # Given number_of_layers = 1 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=number_of_qubits, topology=topology, ) params = [np.ones(number_of_qubits)] expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[0][i], i)) expected_circuit = Circuit(expected_pycircuit) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit
def test_ansatz_from_dict(self, ansatz, n_qubits, topology): # Given expected_ansatz = QCBMAnsatz(2, n_qubits, topology) # When ansatz = ansatz.from_dict({ "schema": ANSATZ_SCHEMA, "number_of_layers": 2, "number_of_qubits": n_qubits, "topology": topology, }) # Then assert isinstance(ansatz, QCBMAnsatz) assert ansatz._number_of_qubits == expected_ansatz._number_of_qubits assert ansatz._number_of_layers == expected_ansatz._number_of_layers assert ansatz.topology == expected_ansatz.topology
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")
def ansatz(self, n_qubits, topology): return QCBMAnsatz( number_of_layers=2, number_of_qubits=n_qubits, topology=topology, )
import pytest from zquantum.core.bitstring_distribution import ( BitstringDistribution, compute_clipped_negative_log_likelihood, compute_mmd, ) from zquantum.core.gradients import finite_differences_gradient from zquantum.core.history.recorder import recorder from zquantum.core.utils import ValueEstimate, create_object from zquantum.qcbm.ansatz import QCBMAnsatz from zquantum.qcbm.cost_function import QCBMCostFunction, create_QCBM_cost_function number_of_layers = 1 number_of_qubits = 4 topology = "all" ansatz = QCBMAnsatz(number_of_layers, number_of_qubits, topology) target_bitstring_distribution = BitstringDistribution( { "0000": 1.0, "0001": 0.0, "0010": 0.0, "0011": 1.0, "0100": 0.0, "0101": 1.0, "0110": 0.0, "0111": 0.0, "1000": 0.0, "1001": 0.0, "1010": 1.0, "1011": 0.0, "1100": 1.0,
def test_qubit_count_matrix_params(self, n_qubits, matrix, n_connections): test_ansatz = QCBMAnsatz(1, n_qubits, "graph", adjacency_matrix=matrix) assert test_ansatz.n_params_per_ent_layer == n_connections
def test_qubit_count_topology(self, type, n_qubits): test_ansatz = QCBMAnsatz(1, n_qubits, type) assert test_ansatz.n_params_per_ent_layer == n_qubits - 1
def test_ansatz_circuit_nine_layers(self, number_of_qubits, topology): # Given number_of_layers = 9 ansatz = QCBMAnsatz( number_of_layers=number_of_layers, number_of_qubits=number_of_qubits, topology=topology, ) params = [ np.ones(2 * number_of_qubits), np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)), np.ones(2 * number_of_qubits), np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)), np.ones(2 * number_of_qubits), np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)), np.ones(3 * number_of_qubits), np.ones(int((number_of_qubits * (number_of_qubits - 1)) / 2)), np.ones(2 * number_of_qubits), ] expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[0][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RZ(params[0][i + number_of_qubits], i) ) expected_first_layer = Circuit(expected_pycircuit) expected_second_layer = get_entangling_layer( params[1], number_of_qubits, "XX", topology ) expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[2][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RZ(params[2][i + number_of_qubits], i) ) expected_third_layer = Circuit(expected_pycircuit) expected_fourth_layer = get_entangling_layer( params[3], number_of_qubits, "XX", topology ) expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[4][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RZ(params[4][i + number_of_qubits], i) ) expected_fifth_layer = Circuit(expected_pycircuit) expected_sixth_layer = get_entangling_layer( params[5], number_of_qubits, "XX", topology ) expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RX(params[6][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RZ(params[6][i + number_of_qubits], i) ) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RX(params[6][i + 2 * number_of_qubits], i) ) expected_seventh_layer = Circuit(expected_pycircuit) expected_eigth_layer = get_entangling_layer( params[7], number_of_qubits, "XX", topology ) expected_pycircuit = Program() for i in range(number_of_qubits): expected_pycircuit += Program(pyquil.gates.RZ(params[8][i], i)) for i in range(number_of_qubits): expected_pycircuit += Program( pyquil.gates.RX(params[8][i + number_of_qubits], i) ) expected_ninth_layer = Circuit(expected_pycircuit) expected_circuit = ( expected_first_layer + expected_second_layer + expected_third_layer + expected_fourth_layer + expected_fifth_layer + expected_sixth_layer + expected_seventh_layer + expected_eigth_layer + expected_ninth_layer ) params = np.concatenate(params) # When circuit = ansatz.get_executable_circuit(params) # Then assert circuit == expected_circuit