def test_circuit_on_qubits_with_varlayer_execution(backend, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) thetas = np.random.random([2, 4]) smallc = Circuit(4) smallc.add(gates.VariationalLayer(range(4), [(0, 1), (2, 3)], gates.RX, gates.CNOT, thetas[0])) largec = Circuit(8, accelerators=accelerators) largec.add(smallc.on_qubits(*range(0, 8, 2))) largec.add(gates.VariationalLayer(range(1, 8, 2), [(1, 3), (5, 7)], gates.RY, gates.CZ, thetas[1])) targetc = Circuit(8) targetc.add(gates.VariationalLayer(range(0, 8, 2), [(0, 2), (4, 6)], gates.RX, gates.CNOT, thetas[0])) targetc.add(gates.VariationalLayer(range(1, 8, 2), [(1, 3), (5, 7)], gates.RY, gates.CZ, thetas[1])) assert largec.depth == targetc.depth np.testing.assert_allclose(largec(), targetc()) qibo.set_backend(original_backend)
def test_set_parameters_with_variationallayer(backend, accelerators, nqubits): """Check updating parameters of variational layer.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = np.random.random(nqubits) c = Circuit(nqubits, accelerators) pairs = [(i, i + 1) for i in range(0, nqubits - 1, 2)] c.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta)) target_c = Circuit(nqubits) target_c.add((gates.RY(i, theta[i]) for i in range(nqubits))) target_c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) np.testing.assert_allclose(c(), target_c()) # Test setting VariationalLayer using a list new_theta = np.random.random(nqubits) c.set_parameters([np.copy(new_theta)]) target_c.set_parameters(np.copy(new_theta)) np.testing.assert_allclose(c(), target_c()) # Test setting VariationalLayer using an array new_theta = np.random.random(nqubits) c.set_parameters(np.copy(new_theta)) target_c.set_parameters(np.copy(new_theta)) np.testing.assert_allclose(c(), target_c()) qibo.set_backend(original_backend)
def test_set_parameters_with_double_variationallayer(backend, accelerators, nqubits, trainable): """Check updating parameters of variational layer.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = np.random.random((3, nqubits)) c = Circuit(nqubits, accelerators) pairs = [(i, i + 1) for i in range(0, nqubits - 1, 2)] c.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[0], theta[1], trainable=trainable)) c.add((gates.RX(i, theta[2, i]) for i in range(nqubits))) target_c = Circuit(nqubits) target_c.add((gates.RY(i, theta[0, i]) for i in range(nqubits))) target_c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_c.add((gates.RY(i, theta[1, i]) for i in range(nqubits))) target_c.add((gates.RX(i, theta[2, i]) for i in range(nqubits))) np.testing.assert_allclose(c(), target_c()) new_theta = np.random.random(3 * nqubits) if trainable: c.set_parameters(np.copy(new_theta)) else: c.set_parameters(np.copy(new_theta[2 * nqubits:])) new_theta[:2 * nqubits] = theta[:2].ravel() target_c.set_parameters(np.copy(new_theta)) np.testing.assert_allclose(c(), target_c()) qibo.set_backend(original_backend)
def test_variational_layer_density_matrix(backend, nqubits): from qibo.models import Circuit theta = 2 * np.pi * np.random.random(nqubits) c = Circuit(nqubits, density_matrix=True) c.add((gates.RY(i, t) for i, t in enumerate(theta))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_state = c() pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) c = Circuit(nqubits, density_matrix=True) c.add(gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta)) final_state = c() K.assert_allclose(target_state, final_state) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta) gate.density_matrix = True final_state = gate(c.get_initial_state()) K.assert_allclose(target_state, final_state)
def test_variational_layer_construct_unitary(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) pairs = list((i, i + 1) for i in range(0, 5, 2)) theta = 2 * np.pi * np.random.random(6) gate = gates.VariationalLayer(range(6), pairs, gates.RY, gates.CZ, theta) with pytest.raises(ValueError): gate.construct_unitary() qibo.set_backend(original_backend)
def test_circuit_add_layer(backend, nqubits, accelerators): c = Circuit(nqubits, accelerators) qubits = list(range(nqubits)) pairs = [(2 * i, 2 * i + 1) for i in range(nqubits // 2)] params = nqubits * [0.1] c.add(gates.VariationalLayer(qubits, pairs, gates.RY, gates.CZ, params)) assert len(c.queue) == nqubits // 2 + nqubits % 2 for gate in c.queue: assert isinstance(gate, gates.Unitary)
def test_variational_layer_dagger(backend, nqubits): theta = 2 * np.pi * np.random.random((2, nqubits)) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[0], theta[1]) c = Circuit(nqubits) c.add((gate, gate.dagger())) initial_state = random_state(nqubits) final_state = c(np.copy(initial_state)) K.assert_allclose(final_state, initial_state)
def test_construct_unitary_errors(backend): qibo.set_backend(backend) gate = gates.M(0) with pytest.raises(ValueError): matrix = gate.unitary pairs = list((i, i + 1) for i in range(0, 5, 2)) theta = 2 * np.pi * np.random.random(6) gate = gates.VariationalLayer(range(6), pairs, gates.RY, gates.CZ, theta) with pytest.raises(ValueError): matrix = gate.unitary
def test_variational_layer(backend, nqubits): theta = 2 * np.pi * np.random.random(nqubits) gatelist = [gates.RY(i, t) for i, t in enumerate(theta)] gatelist.extend(gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2)) target_state = apply_gates(gatelist, nqubits=nqubits) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta) final_state = apply_gates([gate], nqubits=nqubits) K.assert_allclose(target_state, final_state)
def test_variational_layer(backend, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random(nqubits) c = models.Circuit(nqubits, density_matrix=True) c.add((gates.RY(i, t) for i, t in enumerate(theta))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_state = c() pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) c = models.Circuit(nqubits, density_matrix=True) c.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta)) final_state = c() np.testing.assert_allclose(target_state, final_state) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta) gate.density_matrix = True final_state = gate(c.get_initial_state()) np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def varlayer_circuit(nqubits, nlayers): """Creates variational circuit using ``VariationalLayer`` gate.""" circuit = models.Circuit(nqubits) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) theta = np.zeros(nqubits) for l in range(nlayers): circuit.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta, theta)) circuit.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) circuit.add(gates.CZ(0, nqubits - 1)) circuit.add((gates.RY(i, theta) for i in range(nqubits))) return circuit
def test_variational_layer_errors(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(6) pairs = list((i, i + 1) for i in range(0, 5, 2)) with pytest.raises(ValueError): c.add(gates.VariationalLayer(range(6), pairs, gates.RY, gates.CZ, np.zeros(6), np.zeros(7))) with pytest.raises(ValueError): c.add(gates.VariationalLayer(range(7), pairs, gates.RY, gates.CZ, np.zeros(7), np.zeros(7))) with pytest.raises(ValueError): c.add(gates.VariationalLayer(range(10), pairs, gates.RY, gates.CZ, np.zeros(10), np.zeros(10))) gate = gates.VariationalLayer(range(6), pairs, gates.RY, gates.CZ, np.zeros(6), np.zeros(6)) np.testing.assert_allclose(gate.parameter, np.zeros(12)) qibo.set_backend(original_backend)
def test_variational_two_layers(backend, accelerators, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random(2 * nqubits) theta_iter = iter(theta) c = Circuit(nqubits) c.add((gates.RY(i, next(theta_iter)) for i in range(nqubits))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) c.add((gates.RY(i, next(theta_iter)) for i in range(nqubits))) c.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) c.add(gates.CZ(0, nqubits - 1)) target_state = c().numpy() c = Circuit(nqubits, accelerators) theta = theta.reshape((2, nqubits)) pairs1 = list((i, i + 1) for i in range(0, nqubits - 1, 2)) pairs2 = list((i, i + 1) for i in range(1, nqubits - 2, 2)) pairs2.append((0, nqubits - 1)) c.add( gates.VariationalLayer(range(nqubits), pairs1, gates.RY, gates.CZ, theta[0])) c.add( gates.VariationalLayer(range(nqubits), pairs2, gates.RY, gates.CZ, theta[1])) final_state = c().numpy() np.testing.assert_allclose(target_state, final_state) c = Circuit(nqubits, accelerators) theta = theta.reshape((2, nqubits)) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) c.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[0], theta[1])) c.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) c.add(gates.CZ(0, nqubits - 1)) final_state = c().numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def OptimizedVariationalCircuit(nqubits, nlayers=1, theta_values=None): if theta_values is None: theta = 2 * np.pi * np.random.random((2 * nlayers, nqubits)) else: theta = theta_values.reshape((2 * nlayers, nqubits)) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) for l in range(nlayers): yield gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[2 * l], theta[2 * l + 1]) for i in range(1, nqubits - 2, 2): yield gates.CZ(i, i + 1) yield gates.CZ(0, nqubits - 1)
def test_variational_layer_dagger(backend, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random((2, nqubits)) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta[0], theta[1]) c = Circuit(nqubits) c.add((gate, gate.dagger())) initial_state = utils.random_numpy_state(nqubits) final_state = c(np.copy(initial_state)).numpy() np.testing.assert_allclose(final_state, initial_state) qibo.set_backend(original_backend)
def test_variational_layer_call(nqubits): original_backend = qibo.get_backend() qibo.set_backend("custom") theta = 2 * np.pi * np.random.random(nqubits) c = Circuit(nqubits) c.add((gates.RY(i, t) for i, t in enumerate(theta))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_state = c().numpy() pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) gate = gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta) final_state = gate(c._default_initial_state()).numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def test_circuit_add_layer(backend, nqubits, accelerators): original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(nqubits, accelerators) qubits = list(range(nqubits)) pairs = [(2 * i, 2 * i + 1) for i in range(nqubits // 2)] params = nqubits * [0.1] c.add(gates.VariationalLayer(qubits, pairs, gates.RY, gates.CZ, params)) assert len(c.queue) == nqubits // 2 + nqubits % 2 if backend == "custom": target_gate_cls = gates.Unitary else: from qibo.core.gates import Unitary as target_gate_cls for gate in c.queue: assert isinstance(gate, target_gate_cls) qibo.set_backend(original_backend)
def test_variational_one_layer(backend, accelerators, nqubits): original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 2 * np.pi * np.random.random(nqubits) c = Circuit(nqubits) c.add((gates.RY(i, t) for i, t in enumerate(theta))) c.add((gates.CZ(i, i + 1) for i in range(0, nqubits - 1, 2))) target_state = c().numpy() c = Circuit(nqubits, accelerators) pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) c.add(gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, theta)) final_state = c().numpy() np.testing.assert_allclose(target_state, final_state) qibo.set_backend(original_backend)
def AAVQE(nqubits, layers, maxsteps, T_max, initial_parameters, easy_hamiltonian, problem_hamiltonian): """Implements the Adiabatically Assisted Variational Quantum Eigensolver (AAVQE). Args: nqubits (int): number of quantum bits. layers (int): number of ansatz layers. maxsteps (int): number of maximum iterations on each adiabatic step. T_max (int): number of maximum adiabatic steps. initial_parameters (array or list): values of the initial parameters. easy_hamiltonian (qibo.hamiltonians.Hamiltonian): initial Hamiltonian object. problem_hamiltonian (qibo.hamiltonians.Hamiltonian): problem Hamiltonian object. Returns: Groundstate energy of the problem Hamiltonian and best set of parameters. """ # Create variational circuit pairs = list((i, i + 1) for i in range(0, nqubits - 1, 2)) circuit = models.Circuit(nqubits) for l in range(layers): circuit.add( gates.VariationalLayer(range(nqubits), pairs, gates.RY, gates.CZ, np.zeros(nqubits), np.zeros(nqubits))) circuit.add((gates.CZ(i, i + 1) for i in range(1, nqubits - 2, 2))) circuit.add(gates.CZ(0, nqubits - 1)) circuit.add((gates.RY(i, theta=0) for i in range(nqubits))) for t in range(T_max + 1): s = t / T_max print('s =', s) hamiltonian = (1 - s) * easy_hamiltonian + s * problem_hamiltonian vqe = models.VQE(circuit, hamiltonian) energy, params = vqe.minimize(initial_parameters, method='Nelder-Mead', options={'maxfev': maxsteps}, compile=False) initial_parameters = params return energy, params