def rw_circuit(qubits, parameters, X=True): """Circuit that implements the amplitude distributor part of the option pricing algorithm. Args: qubits (int): number of qubits used for the unary basis. paramters (list): values to be introduces into the fSim gates for amplitude distribution. X (bool): whether or not the first X gate is executed. Returns: generator that yield the gates needed for the amplitude distributor circuit """ if qubits % 2 == 0: mid1 = int(qubits / 2) mid0 = int(mid1 - 1) if X: yield gates.X(mid1) yield gates.fSim(mid1, mid0, parameters[mid0] / 2, 0) for i in range(mid0): yield gates.fSim(mid0 - i, mid0 - i - 1, parameters[mid0 - i - 1] / 2, 0) yield gates.fSim(mid1 + i, mid1 + i + 1, parameters[mid1 + i] / 2, 0) else: mid = int((qubits - 1) / 2) if X: yield gates.X(mid) for i in range(mid): yield gates.fSim(mid - i, mid - i - 1, parameters[mid - i - 1] / 2, 0) yield gates.fSim(mid + i, mid + i + 1, parameters[mid + i] / 2, 0)
def test_set_parameters_with_list(backend, trainable): """Check updating parameters of circuit with list.""" params = [0.123, 0.456, (0.789, 0.321)] c = Circuit(3) if trainable: c.add(gates.RX(0, theta=0, trainable=trainable)) else: c.add(gates.RX(0, theta=params[0], trainable=trainable)) c.add(gates.RY(1, theta=0)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0, phi=0)) c.add(gates.H(2)) # execute once final_state = c() target_c = Circuit(3) target_c.add(gates.RX(0, theta=params[0])) target_c.add(gates.RY(1, theta=params[1])) target_c.add(gates.CZ(1, 2)) target_c.add(gates.fSim(0, 2, theta=params[2][0], phi=params[2][1])) target_c.add(gates.H(2)) # Attempt using a flat np.ndarray/list for new_params in (np.random.random(4), list(np.random.random(4))): if trainable: c.set_parameters(new_params) else: new_params[0] = params[0] c.set_parameters(new_params[1:]) target_params = [ new_params[0], new_params[1], (new_params[2], new_params[3]) ] target_c.set_parameters(target_params) K.assert_allclose(c(), target_c())
def test_circuit_set_parameters_with_list(backend, accelerators): """Check updating parameters of circuit with list.""" original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(3, accelerators) c.add(gates.RX(0, theta=0)) c.add(gates.RY(1, theta=0)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0, phi=0)) c.add(gates.H(2)) # execute once final_state = c() params = [0.123, 0.456, (0.789, 0.321)] target_c = Circuit(3) target_c.add(gates.RX(0, theta=params[0])) target_c.add(gates.RY(1, theta=params[1])) target_c.add(gates.CZ(1, 2)) target_c.add(gates.fSim(0, 2, theta=params[2][0], phi=params[2][1])) target_c.add(gates.H(2)) c.set_parameters(params) np.testing.assert_allclose(c(), target_c()) # Attempt using a flat np.ndarray/list for new_params in (np.random.random(4), list(np.random.random(4))): params = [new_params[0], new_params[1], (new_params[2], new_params[3])] target_c.set_parameters(params) c.set_parameters(new_params) np.testing.assert_allclose(c(), target_c()) qibo.set_backend(original_backend)
def test_set_parameters_with_gate_fusion(backend, accelerators): """Check updating parameters of fused circuit.""" original_backend = qibo.get_backend() qibo.set_backend(backend) params = np.random.random(9) c = Circuit(5, accelerators) c.add(gates.RX(0, theta=params[0])) c.add(gates.RY(1, theta=params[1])) c.add(gates.CZ(0, 1)) c.add(gates.RX(2, theta=params[2])) c.add(gates.RY(3, theta=params[3])) c.add(gates.fSim(2, 3, theta=params[4], phi=params[5])) c.add(gates.RX(4, theta=params[6])) c.add(gates.RZ(0, theta=params[7])) c.add(gates.RZ(1, theta=params[8])) fused_c = c.fuse() np.testing.assert_allclose(c(), fused_c()) new_params = np.random.random(9) new_params_list = list(new_params[:4]) new_params_list.append((new_params[4], new_params[5])) new_params_list.extend(new_params[6:]) c.set_parameters(new_params_list) fused_c.set_parameters(new_params_list) np.testing.assert_allclose(c(), fused_c()) qibo.set_backend(original_backend)
def test_set_parameters_with_gate_fusion(backend, trainable): """Check updating parameters of fused circuit.""" params = np.random.random(9) c = Circuit(5) c.add(gates.RX(0, theta=params[0], trainable=trainable)) c.add(gates.RY(1, theta=params[1])) c.add(gates.CZ(0, 1)) c.add(gates.RX(2, theta=params[2])) c.add(gates.RY(3, theta=params[3], trainable=trainable)) c.add(gates.fSim(2, 3, theta=params[4], phi=params[5])) c.add(gates.RX(4, theta=params[6])) c.add(gates.RZ(0, theta=params[7], trainable=trainable)) c.add(gates.RZ(1, theta=params[8])) fused_c = c.fuse() final_state = fused_c() target_state = c() K.assert_allclose(final_state, target_state) if trainable: new_params = np.random.random(9) new_params_list = list(new_params[:4]) new_params_list.append((new_params[4], new_params[5])) new_params_list.extend(new_params[6:]) else: new_params = np.random.random(9) new_params_list = list(new_params[1:3]) new_params_list.append((new_params[4], new_params[5])) new_params_list.append(new_params[6]) new_params_list.append(new_params[8]) c.set_parameters(new_params_list) fused_c.set_parameters(new_params_list) K.assert_allclose(c(), fused_c())
def test_controlled_by_fsim(backend, accelerators): """Check ``controlled_by`` for fSim gate.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 phi = 0.4321 c = Circuit(6, accelerators) c.add((gates.H(i) for i in range(6))) c.add(gates.fSim(5, 3, theta, phi).controlled_by(0, 2, 1)) final_state = c.execute().numpy() target_state = np.ones_like(final_state) / np.sqrt(2**6) rotation = np.array([[np.cos(theta), -1j * np.sin(theta)], [-1j * np.sin(theta), np.cos(theta)]]) matrix = np.eye(4, dtype=target_state.dtype) matrix[1:3, 1:3] = rotation matrix[3, 3] = np.exp(-1j * phi) ids = [56, 57, 60, 61] target_state[ids] = matrix.dot(target_state[ids]) ids = [58, 59, 62, 63] target_state[ids] = matrix.dot(target_state[ids]) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_get_parameters(): c = Circuit(3) c.add(gates.RX(0, theta=0.123)) c.add(gates.RY(1, theta=0.456)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0.789, phi=0.987)) c.add(gates.H(2)) unitary = np.array([[0.123, 0.123], [0.123, 0.123]]) c.add(gates.Unitary(unitary, 1)) params = [0.123, 0.456, (0.789, 0.987), unitary] assert params == c.get_parameters() params = [0.123, 0.456, (0.789, 0.987), unitary] assert params == c.get_parameters() params = { c.queue[0]: 0.123, c.queue[1]: 0.456, c.queue[3]: (0.789, 0.987), c.queue[5]: unitary } assert params == c.get_parameters("dict") params = [0.123, 0.456, 0.789, 0.987] params.extend(unitary.ravel()) assert params == c.get_parameters("flatlist") with pytest.raises(ValueError): c.get_parameters("test")
def test_controlled_by_random(backend, nqubits): """Check controlled_by method on gate.""" from qibo.models import Circuit from qibo.tests.utils import random_state initial_psi = random_state(nqubits) initial_rho = np.outer(initial_psi, initial_psi.conj()) c = Circuit(nqubits, density_matrix=True) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) final_rho = c(np.copy(initial_rho)) c = Circuit(nqubits) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) target_psi = c(np.copy(initial_psi)) target_rho = np.outer(target_psi, np.conj(target_psi)) K.assert_allclose(final_rho, target_rho)
def test_controlled_by_random(backend, nqubits): """Check controlled_by method on gate.""" original_backend = qibo.get_backend() qibo.set_backend(backend) initial_psi = utils.random_numpy_state(nqubits) initial_rho = np.outer(initial_psi, initial_psi.conj()) c = models.Circuit(nqubits, density_matrix=True) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) final_rho = c(np.copy(initial_rho)).numpy() c = models.Circuit(nqubits) c.add(gates.RX(1, theta=0.789).controlled_by(2)) c.add(gates.fSim(0, 2, theta=0.123, phi=0.321).controlled_by(1, 3)) target_psi = c(np.copy(initial_psi)).numpy() target_rho = np.outer(target_psi, target_psi.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_fuse_circuit_two_qubit_gates(backend): """Check circuit fusion in circuit with two-qubit gates only.""" c = Circuit(2) c.add(gates.CNOT(0, 1)) c.add(gates.RX(0, theta=0.1234).controlled_by(1)) c.add(gates.SWAP(0, 1)) c.add(gates.fSim(1, 0, theta=0.1234, phi=0.324)) c.add(gates.RY(1, theta=0.1234).controlled_by(0)) fused_c = c.fuse() K.assert_allclose(fused_c(), c())
def test_fuse_circuit_two_qubit_only(): """Check gate fusion in circuit with two-qubit gates only.""" c = Circuit(2) c.add(gates.CNOT(0, 1)) c.add(gates.RX(0, theta=0.1234).controlled_by(1)) c.add(gates.SWAP(0, 1)) c.add(gates.fSim(1, 0, theta=0.1234, phi=0.324)) c.add(gates.RY(1, theta=0.1234).controlled_by(0)) fused_c = c.fuse() target_state = c() final_state = fused_c() np.testing.assert_allclose(final_state, target_state)
def test_two_qubit_parametrized_gates(backend, nqubits, ndevices): """Check ``CU1`` and ``fSim`` gate.""" theta = 0.1234 phi = 0.4321 targets = random_active_qubits(nqubits, nactive=2) qibo_gate = gates.CU1(*targets, np.pi * theta) cirq_gate = [(cirq.CZPowGate(exponent=theta), targets)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits) targets = random_active_qubits(nqubits, nactive=2) qibo_gate = gates.fSim(*targets, theta, phi) cirq_gate = [(cirq.FSimGate(theta=theta, phi=phi), targets)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices)
def test_fsim(backend): theta = 0.1234 phi = 0.4321 gatelist = [gates.H(0), gates.H(1), gates.fSim(0, 1, theta, phi)] final_state = apply_gates(gatelist, nqubits=2) target_state = np.ones_like(K.to_numpy(final_state)) / 2.0 rotation = np.array([[np.cos(theta), -1j * np.sin(theta)], [-1j * np.sin(theta), np.cos(theta)]]) matrix = np.eye(4, dtype=target_state.dtype) matrix[1:3, 1:3] = rotation matrix[3, 3] = np.exp(-1j * phi) target_state = matrix.dot(target_state) K.assert_allclose(final_state, target_state)
def test_two_qubit_gate_multiplication(backend): theta, phi = 0.1234, 0.5432 gate1 = gates.fSim(0, 1, theta=theta, phi=phi) gate2 = gates.SWAP(0, 1) final_gate = gate1 @ gate2 target_matrix = ( np.array([[1, 0, 0, 0], [0, np.cos(theta), -1j * np.sin(theta), 0], [0, -1j * np.sin(theta), np.cos(theta), 0], [0, 0, 0, np.exp(-1j * phi)]]) @ np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])) K.assert_allclose(final_gate.matrix, target_matrix) # Check that error is raised when target qubits do not agree with pytest.raises(NotImplementedError): final_gate = gate1 @ gates.SWAP(0, 2)
def test_two_qubit_gates_controlled_by(backend, nqubits, ndevices): """Check ``SWAP`` and ``fSim`` gates controlled on arbitrary number of qubits.""" all_qubits = np.arange(nqubits) for _ in range(5): activeq = random_active_qubits(nqubits, nmin=2) qibo_gate = gates.SWAP(*activeq[-2:]).controlled_by(*activeq[:-2]) cirq_gate = [(cirq.SWAP.controlled(len(activeq) - 2), activeq)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices) theta = np.random.random() phi = np.random.random() qibo_gate = gates.fSim(*activeq[-2:], theta, phi).controlled_by(*activeq[:-2]) cirq_gate = [(cirq.FSimGate(theta, phi).controlled(len(activeq) - 2), activeq)] assert_gates_equivalent(qibo_gate, cirq_gate, nqubits, ndevices)
def test_inverse_circuit_execution(backend, accelerators, fuse): c = Circuit(4, accelerators) c.add(gates.RX(0, theta=0.1)) c.add(gates.U2(1, phi=0.2, lam=0.3)) c.add(gates.U3(2, theta=0.1, phi=0.3, lam=0.2)) c.add(gates.CNOT(0, 1)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0.1, phi=0.3)) c.add(gates.CU2(0, 1, phi=0.1, lam=0.1)) if fuse: if accelerators: with pytest.raises(NotImplementedError): c = c.fuse() else: c = c.fuse() invc = c.invert() target_state = np.ones(2**4) / 4 final_state = invc(c(np.copy(target_state))) K.assert_allclose(final_state, target_state)
def test_inverse_circuit_execution(backend, accelerators, fuse): original_backend = qibo.get_backend() qibo.set_backend(backend) c = Circuit(4, accelerators) c.add(gates.RX(0, theta=0.1)) c.add(gates.U2(1, phi=0.2, lam=0.3)) c.add(gates.U3(2, theta=0.1, phi=0.3, lam=0.2)) c.add(gates.CNOT(0, 1)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0.1, phi=0.3)) c.add(gates.CU2(0, 1, phi=0.1, lam=0.1)) if fuse: c = c.fuse() invc = c.invert() target_state = np.ones(2 ** 4) / 4 final_state = invc(c(np.copy(target_state))) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_two_qubit_gate_multiplication(backend): """Check gate multiplication for two-qubit gates.""" import qibo original_backend = qibo.get_backend() qibo.set_backend(backend) theta, phi = 0.1234, 0.5432 gate1 = gates.fSim(0, 1, theta=theta, phi=phi) gate2 = gates.SWAP(0, 1) final_gate = gate1 @ gate2 target_matrix = ( np.array([[1, 0, 0, 0], [0, np.cos(theta), -1j * np.sin(theta), 0], [0, -1j * np.sin(theta), np.cos(theta), 0], [0, 0, 0, np.exp(-1j * phi)]]) @ np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]])) np.testing.assert_allclose(final_gate.unitary, target_matrix) # Check that error is raised when target qubits do not agree with pytest.raises(NotImplementedError): final_gate = gate1 @ gates.SWAP(0, 2) # Reset backend for other tests qibo.set_backend(original_backend)
def test_circuit_set_parameters_errors(): """Check updating parameters errors.""" c = Circuit(2) c.add(gates.RX(0, theta=0.789)) c.add(gates.RX(1, theta=0.789)) c.add(gates.fSim(0, 1, theta=0.123, phi=0.456)) with pytest.raises(ValueError): c.set_parameters({gates.RX(0, theta=1.0): 0.568}) with pytest.raises(ValueError): c.set_parameters([0.12586]) with pytest.raises(ValueError): c.set_parameters(np.random.random(5)) with pytest.raises(ValueError): import tensorflow as tf c.set_parameters(tf.random.uniform((6,), dtype=tf.float64)) with pytest.raises(TypeError): c.set_parameters({0.3568}) fused_c = c.fuse() with pytest.raises(TypeError): fused_c.set_parameters({gates.RX(0, theta=1.0): 0.568})
def test_fsim(backend): """Check fSim gate is working properly on |++>.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 phi = 0.4321 c = Circuit(2) c.add(gates.H(0)) c.add(gates.H(1)) c.add(gates.fSim(0, 1, theta, phi)) final_state = c.execute().numpy() target_state = np.ones_like(final_state) / 2.0 rotation = np.array([[np.cos(theta), -1j * np.sin(theta)], [-1j * np.sin(theta), np.cos(theta)]]) matrix = np.eye(4, dtype=target_state.dtype) matrix[1:3, 1:3] = rotation matrix[3, 3] = np.exp(-1j * phi) target_state = matrix.dot(target_state) np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_get_parameters(trainable, include_not_trainable): c = Circuit(3) c.add(gates.RX(0, theta=0.123)) c.add(gates.RY(1, theta=0.456, trainable=trainable)) c.add(gates.CZ(1, 2)) c.add(gates.fSim(0, 2, theta=0.789, phi=0.987, trainable=trainable)) c.add(gates.H(2)) unitary = np.array([[0.123, 0.123], [0.123, 0.123]]) c.add(gates.Unitary(unitary, 1)) if trainable or include_not_trainable: params = { "list": [0.123, 0.456, (0.789, 0.987), unitary], "dict": { c.queue[0]: 0.123, c.queue[1]: 0.456, c.queue[3]: (0.789, 0.987), c.queue[5]: unitary }, "flatlist": [0.123, 0.456, 0.789, 0.987] } else: params = { "list": [0.123, unitary], "dict": { c.queue[0]: 0.123, c.queue[5]: unitary }, "flatlist": [0.123] } params["flatlist"].extend(unitary.ravel()) for fmt, prm in params.items(): assert c.get_parameters(fmt, include_not_trainable) == prm with pytest.raises(ValueError): c.get_parameters("test")