def test_circuit_set_parameters_with_dictionary(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.X(0)) c.add(gates.X(2)) c.add(gates.U1(0, theta=0)) c.add(gates.RZ(1, theta=0)) c.add(gates.CZ(1, 2)) c.add(gates.CU1(0, 2, theta=0)) c.add(gates.H(2)) c.add(gates.Unitary(np.eye(2), 1)) final_state = c() params = [0.123, 0.456, 0.789, np.random.random((2, 2))] target_c = Circuit(3, accelerators) target_c.add(gates.X(0)) target_c.add(gates.X(2)) target_c.add(gates.U1(0, theta=params[0])) target_c.add(gates.RZ(1, theta=params[1])) target_c.add(gates.CZ(1, 2)) target_c.add(gates.CU1(0, 2, theta=params[2])) target_c.add(gates.H(2)) target_c.add(gates.Unitary(params[3], 1)) param_dict = {c.queue[i]: p for i, p in zip([2, 3, 5, 7], params)} c.set_parameters(param_dict) np.testing.assert_allclose(c(), target_c()) qibo.set_backend(original_backend)
def test_circuit_set_parameters_with_dictionary(backend, accelerators, trainable): """Check updating parameters of circuit with list.""" original_backend = qibo.get_backend() qibo.set_backend(backend) params = [0.123, 0.456, 0.789, np.random.random((2, 2))] c1 = Circuit(3, accelerators) c1.add(gates.X(0)) c1.add(gates.X(2)) if trainable: c1.add(gates.U1(0, theta=0, trainable=trainable)) else: c1.add(gates.U1(0, theta=params[0], trainable=trainable)) c2 = Circuit(3, accelerators) c2.add(gates.RZ(1, theta=0)) c2.add(gates.CZ(1, 2)) c2.add(gates.CU1(0, 2, theta=0)) c2.add(gates.H(2)) if trainable: c2.add(gates.Unitary(np.eye(2), 1, trainable=trainable)) else: c2.add(gates.Unitary(params[3], 1, trainable=trainable)) c = c1 + c2 final_state = c() target_c = Circuit(3, accelerators) target_c.add(gates.X(0)) target_c.add(gates.X(2)) target_c.add(gates.U1(0, theta=params[0])) target_c.add(gates.RZ(1, theta=params[1])) target_c.add(gates.CZ(1, 2)) target_c.add(gates.CU1(0, 2, theta=params[2])) target_c.add(gates.H(2)) target_c.add(gates.Unitary(params[3], 1)) if trainable: params_dict = {c.queue[i]: p for i, p in zip([2, 3, 5, 7], params)} else: params_dict = {c.queue[3]: params[1], c.queue[5]: params[2]} c.set_parameters(params_dict) np.testing.assert_allclose(c(), target_c()) # test not passing all parametrized gates target_c = Circuit(3, accelerators) target_c.add(gates.X(0)) target_c.add(gates.X(2)) target_c.add(gates.U1(0, theta=params[0])) target_c.add(gates.RZ(1, theta=params[1])) target_c.add(gates.CZ(1, 2)) target_c.add(gates.CU1(0, 2, theta=0.7891)) target_c.add(gates.H(2)) target_c.add(gates.Unitary(params[3], 1)) c.set_parameters({c.queue[5]: 0.7891}) np.testing.assert_allclose(c(), target_c()) qibo.set_backend(original_backend)
def test_copied_circuit_execution(backend, accelerators, deep): """Check that circuit copy execution is equivalent to original circuit.""" theta = 0.1234 c1 = Circuit(4, accelerators) c1.add([gates.X(0), gates.X(1), gates.CU1(0, 1, theta)]) c1.add([gates.H(2), gates.H(3), gates.CU1(2, 3, theta)]) if not deep and accelerators is not None: with pytest.raises(ValueError): c2 = c1.copy(deep) else: c2 = c1.copy(deep) K.assert_allclose(c2(), c1())
def test_circuit_vs_gate_execution(backend, compile): """Check consistency between executing circuit and stand alone gates.""" from qibo import K original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 target_c = Circuit(2) target_c.add(gates.X(0)) target_c.add(gates.X(1)) target_c.add(gates.CU1(0, 1, theta)) target_result = target_c() # custom circuit def custom_circuit(initial_state, theta): l1 = gates.X(0)(initial_state) l2 = gates.X(1)(l1) o = gates.CU1(0, 1, theta)(l2) return o initial_state = target_c.get_initial_state() if compile: c = K.compile(custom_circuit) else: c = custom_circuit if backend == "custom" and compile: with pytest.raises(NotImplementedError): result = c(initial_state, theta) else: result = c(initial_state, theta) np.testing.assert_allclose(result, target_result) qibo.set_backend(original_backend)
def _DistributedQFT(nqubits: int, accelerators: Optional[Dict[str, int]] = None, memory_device: str = "/CPU:0") -> DistributedCircuit: """QFT with the order of gates optimized for reduced multi-device communication.""" import numpy as np from qibo import gates circuit = Circuit(nqubits, accelerators, memory_device) icrit = nqubits // 2 + nqubits % 2 if accelerators is not None: circuit.global_qubits = range(circuit.nlocal, nqubits) if icrit < circuit.nglobal: raise_error( NotImplementedError, "Cannot implement QFT for {} qubits " "using {} global qubits." "".format(nqubits, circuit.nglobal)) for i1 in range(nqubits): if i1 < icrit: i1eff = i1 else: i1eff = nqubits - i1 - 1 circuit.add(gates.SWAP(i1, i1eff)) circuit.add(gates.H(i1eff)) for i2 in range(i1 + 1, nqubits): theta = np.pi / 2**(i2 - i1) circuit.add(gates.CU1(i2, i1eff, theta)) return circuit
def _DistributedQFT(nqubits, accelerators=None): """QFT with the order of gates optimized for reduced multi-device communication.""" from qibo import gates circuit = Circuit(nqubits, accelerators) icrit = nqubits // 2 + nqubits % 2 if accelerators is not None: circuit.global_qubits = range(circuit.nlocal, nqubits) # pylint: disable=E1101 if icrit < circuit.nglobal: # pylint: disable=E1101 raise_error(NotImplementedError, "Cannot implement QFT for {} qubits " "using {} global qubits." "".format(nqubits, circuit.nglobal)) # pylint: disable=E1101 for i1 in range(nqubits): if i1 < icrit: i1eff = i1 else: i1eff = nqubits - i1 - 1 circuit.add(gates.SWAP(i1, i1eff)) circuit.add(gates.H(i1eff)) for i2 in range(i1 + 1, nqubits): theta = math.pi / 2 ** (i2 - i1) circuit.add(gates.CU1(i2, i1eff, theta)) return circuit
def test_circuit_vs_gate_execution(backend, compile): """Check consistency between executing circuit and stand alone gates.""" from qibo import K theta = 0.1234 target_c = Circuit(2) target_c.add(gates.X(0)) target_c.add(gates.X(1)) target_c.add(gates.CU1(0, 1, theta)) target_result = target_c() # custom circuit def custom_circuit(initial_state, theta): l1 = gates.X(0)(initial_state) l2 = gates.X(1)(l1) o = gates.CU1(0, 1, theta)(l2) return o initial_state = target_c.get_initial_state() if compile: c = K.compile(custom_circuit) else: c = custom_circuit result = c(initial_state, theta) K.assert_allclose(result, target_result)
def test_cu1_cirq(): c1 = Circuit(2) c1.add(gates.RX(0, 0.1234)) c1.add(gates.RZ(1, 0.4321)) c1.add(gates.CU1(0, 1, 0.567)) # catches unknown gate "cu1" with pytest.raises(exception.QasmException): c2 = circuit_from_qasm(c1.to_qasm())
def QFT(nqubits: int, with_swaps: bool = True, accelerators: Optional[Dict[str, int]] = None, memory_device: str = "/CPU:0") -> Circuit: """Creates a circuit that implements the Quantum Fourier Transform. Args: nqubits (int): Number of qubits in the circuit. with_swaps (bool): Use SWAP gates at the end of the circuit so that the qubit order in the final state is the same as the initial state. accelerators (dict): Accelerator device dictionary in order to use a distributed circuit If ``None`` a simple (non-distributed) circuit will be used. memory_device (str): Device to use for memory in case a distributed circuit is used. Ignored for non-distributed circuits. Returns: A qibo.models.Circuit that implements the Quantum Fourier Transform. Example: :: import numpy as np from qibo.models import QFT nqubits = 6 c = QFT(nqubits) # Random normalized initial state vector init_state = np.random.random(2 ** nqubits) + 1j * np.random.random(2 ** nqubits) init_state = init_state / np.sqrt((np.abs(init_state)**2).sum()) # Execute the circuit final_state = c(init_state) """ if accelerators is not None: if not with_swaps: raise_error(NotImplementedError, "Distributed QFT is only implemented " "with SWAPs.") return _DistributedQFT(nqubits, accelerators, memory_device) import numpy as np from qibo import gates circuit = Circuit(nqubits) for i1 in range(nqubits): circuit.add(gates.H(i1)) for i2 in range(i1 + 1, nqubits): theta = np.pi / 2**(i2 - i1) circuit.add(gates.CU1(i2, i1, theta)) if with_swaps: for i in range(nqubits // 2): circuit.add(gates.SWAP(i, nqubits - i - 1)) return circuit
def test_construct_unitary(backend): original_backend = qibo.get_backend() qibo.set_backend(backend) target_matrix = np.array([[1, 1], [1, -1]]) / np.sqrt(2) np.testing.assert_allclose(gates.H(0).unitary, target_matrix) target_matrix = np.array([[0, 1], [1, 0]]) np.testing.assert_allclose(gates.X(0).unitary, target_matrix) target_matrix = np.array([[0, -1j], [1j, 0]]) np.testing.assert_allclose(gates.Y(0).unitary, target_matrix) target_matrix = np.array([[1, 0], [0, -1]]) np.testing.assert_allclose(gates.Z(1).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]]) np.testing.assert_allclose(gates.CNOT(0, 1).unitary, target_matrix) target_matrix = np.diag([1, 1, 1, -1]) np.testing.assert_allclose(gates.CZ(1, 3).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) np.testing.assert_allclose(gates.SWAP(2, 4).unitary, target_matrix) target_matrix = np.array([[1, 0, 0, 0, 0, 0, 0, 0], [0, 1, 0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0], [0, 0, 0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1], [0, 0, 0, 0, 0, 0, 1, 0]]) np.testing.assert_allclose(gates.TOFFOLI(1, 2, 3).unitary, target_matrix) theta = 0.1234 target_matrix = np.array([[np.cos(theta / 2.0), -1j * np.sin(theta / 2.0)], [-1j * np.sin(theta / 2.0), np.cos(theta / 2.0)]]) np.testing.assert_allclose(gates.RX(0, theta).unitary, target_matrix) target_matrix = np.array([[np.cos(theta / 2.0), -np.sin(theta / 2.0)], [np.sin(theta / 2.0), np.cos(theta / 2.0)]]) np.testing.assert_allclose(gates.RY(0, theta).unitary, target_matrix) target_matrix = np.diag( [np.exp(-1j * theta / 2.0), np.exp(1j * theta / 2.0)]) np.testing.assert_allclose(gates.RZ(0, theta).unitary, target_matrix) target_matrix = np.diag([1, np.exp(1j * theta)]) np.testing.assert_allclose(gates.U1(0, theta).unitary, target_matrix) target_matrix = np.diag([1, 1, 1, np.exp(1j * theta)]) np.testing.assert_allclose(gates.CU1(0, 1, theta).unitary, target_matrix) from qibo import matrices target_matrix = np.array([[1, 0, 0, 0], [0, 0, 1, 0], [0, 1, 0, 0], [0, 0, 0, 1]]) np.testing.assert_allclose(matrices.SWAP, target_matrix) qibo.set_backend(original_backend)
def test_cu1(): c = Circuit(2) c.add(gates.RX(0, 0.1234)) c.add(gates.RZ(1, 0.4321)) c.add(gates.CU1(0, 1, 0.567)) target = f"""// Generated by QIBO {__version__} OPENQASM 2.0; include "qelib1.inc"; qreg q[2]; rx(0.1234) q[0]; rz(0.4321) q[1]; cu1(0.567) q[0],q[1];""" assert_strings_equal(c.to_qasm(), target)
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_cu1gate_application_twoqubit(backend): """Check applying two qubit gate to three qubit density matrix.""" theta = 0.1234 nqubits = 3 initial_rho = random_density_matrix(nqubits) gate = gates.CU1(0, 1, theta=theta) gate.density_matrix = True final_rho = gate(np.copy(initial_rho)) matrix = np.eye(4, dtype=np.complex128) matrix[3, 3] = np.exp(1j * theta) matrix = np.kron(matrix, np.eye(2)) target_rho = matrix.dot(initial_rho).dot(matrix.T.conj()) K.assert_allclose(final_rho, target_rho)
def i_qft(q): """(Inverse) Quantum Fourier Transform on a quantum register. Args: q (list): quantum register where the QFT is applied. Returns: generator with the required quantum gates applied on the quantum circuit. """ for i in range(len(q) // 2): yield gates.SWAP(i, len(q) - i - 1) for i1 in reversed(range(len(q))): for i2 in reversed(range(i1 + 1, len(q))): theta = np.pi / 2 ** (i2 - i1) yield gates.CU1(q[i2], q[i1], -theta) yield gates.H(q[i1])
def test_from_qasm_parametrized_gates(): import numpy as np target = """OPENQASM 2.0; qreg q[2]; rx(0.1234) q[0]; rz(0.4321) q[1]; cu1(0.567) q[0],q[1];""" c = Circuit.from_qasm(target) assert c.depth == 2 assert isinstance(c.queue[0], gates.RX) assert isinstance(c.queue[1], gates.RZ) assert isinstance(c.queue[2], gates.CU1) c2 = Circuit(2) c2.add([gates.RX(0, 0.1234), gates.RZ(1, 0.4321), gates.CU1(0, 1, 0.567)]) np.testing.assert_allclose(c2().numpy(), c().numpy())
def SupremacyLikeCircuit(nqubits: int, nlayers: int): one_qubit_gates = ["RX", "RY", "RZ"] d = 1 for l in range(nlayers): for i in range(nqubits): gate = getattr(gates, one_qubit_gates[int(np.random.randint(0, len(one_qubit_gates)))]) yield gate(i, np.pi / 2.0) for i in range(nqubits): yield gates.CU1(i, (i + d) % nqubits, np.pi / 6.0) d += 1 if d > nqubits - 1: d = 1 for i in range(nqubits): gate = getattr(gates, one_qubit_gates[int(np.random.randint(0, len(one_qubit_gates)))]) yield gate(i, np.pi / 2.0) yield gates.M(i)
def test_circuit_copy(backend, accelerators, deep): """Check that circuit copy execution is equivalent to original circuit.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c1 = Circuit(2, accelerators) c1.add([gates.X(0), gates.X(1), gates.CU1(0, 1, theta)]) if not deep and accelerators is not None: with pytest.raises(ValueError): c2 = c1.copy(deep) else: c2 = c1.copy(deep) target_state = c1.execute().numpy() final_state = c2.execute().numpy() np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_cu1(backend, accelerators): """Check CU1 gate is working properly on |11>.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(2, accelerators) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.CU1(0, 1, theta)) final_state = c.execute().numpy() phase = np.exp(1j * theta) target_state = np.zeros_like(final_state) target_state[3] = phase np.testing.assert_allclose(final_state, target_state) qibo.set_backend(original_backend)
def test_cu1gate_application_twoqubit(backend): """Check applying two qubit gate to three qubit density matrix.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 nqubits = 3 initial_rho = random_density_matrix(nqubits) gate = gates.CU1(0, 1, theta=theta) final_rho = gate(initial_rho.reshape(2 * nqubits * (2,)), is_density_matrix=True).numpy().reshape(initial_rho.shape) matrix = np.eye(4, dtype=np.complex128) matrix[3, 3] = np.exp(1j * theta) matrix = np.kron(matrix, np.eye(2)) target_rho = matrix.dot(initial_rho).dot(matrix.T.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_circuit(backend): """Check passing density matrix as initial state to circuit.""" original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 initial_rho = random_density_matrix(3) c = models.Circuit(3) c.add(gates.X(2)) c.add(gates.CU1(0, 1, theta=theta)) final_rho = c(initial_rho).numpy().reshape(initial_rho.shape) m1 = np.kron(np.eye(4), np.array([[0, 1], [1, 0]])) m2 = np.eye(4, dtype=np.complex128) m2[3, 3] = np.exp(1j * theta) m2 = np.kron(m2, np.eye(2)) target_rho = m1.dot(initial_rho).dot(m1) target_rho = m2.dot(target_rho).dot(m2.T.conj()) np.testing.assert_allclose(final_rho, target_rho) qibo.set_backend(original_backend)
def test_ugates(): c = Circuit(3) c.add(gates.RX(0, 0.1)) c.add(gates.RZ(1, 0.4)) c.add(gates.U2(2, 0.5, 0.6)) c.add(gates.CU1(0, 1, 0.7)) c.add(gates.CU3(2, 1, 0.2, 0.3, 0.4)) target = f"""// Generated by QIBO {__version__} OPENQASM 2.0; include "qelib1.inc"; qreg q[3]; rx(0.1) q[0]; rz(0.4) q[1]; u2(0.5, 0.6) q[2]; cu1(0.7) q[0],q[1]; cu3(0.2, 0.3, 0.4) q[2],q[1];""" assert_strings_equal(c.to_qasm(), target) c = Circuit(2) c.add(gates.CU2(0, 1, 0.1, 0.2)) with pytest.raises(ValueError): target = c.to_qasm()
def test_custom_circuit(backend): """Check consistency between Circuit and custom circuits""" import tensorflow as tf original_backend = qibo.get_backend() qibo.set_backend(backend) theta = 0.1234 c = Circuit(2) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.CU1(0, 1, theta)) r1 = c.execute().numpy() # custom circuit def custom_circuit(initial_state, theta): l1 = gates.X(0)(initial_state) l2 = gates.X(1)(l1) o = gates.CU1(0, 1, theta)(l2) return o init2 = c._default_initial_state() init3 = c._default_initial_state() if backend != "custom": init2 = tf.reshape(init2, (2, 2)) init3 = tf.reshape(init3, (2, 2)) r2 = custom_circuit(init2, theta).numpy().ravel() np.testing.assert_allclose(r1, r2) tf_custom_circuit = tf.function(custom_circuit) if backend == "custom": with pytest.raises(NotImplementedError): r3 = tf_custom_circuit(init3, theta).numpy().ravel() else: r3 = tf_custom_circuit(init3, theta).numpy().ravel() np.testing.assert_allclose(r2, r3) qibo.set_backend(original_backend)
def create_circuit(theta = 0.1234): c = Circuit(2) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.CU1(0, 1, theta)) return c
def run_circuit(initial_state): c = Circuit(2) c.add(gates.X(0)) c.add(gates.X(1)) c.add(gates.CU1(0, 1, theta)) return c.execute(initial_state)
def ansatz_Fourier(layers, qubits=1): """Fourier Ansatz implementation. It is composed by 3 parameters per layer and qubit: U3(a, b, c) Ry(x) || U3(a, b, c) Ry(log x). Args: layers (int): number of layers. qubits (int): number of qubits. Returns: The circuit, the rotation function and the total number of parameters. """ circuit = Circuit(qubits) for l in range(layers - 1): for q in range(qubits): for _ in range(2): circuit.add(gates.RY(q, theta=0)) circuit.add(gates.RZ(q, theta=0)) circuit.add(gates.RY(q, theta=0)) if qubits > 1: for q in range(0, qubits, 2): circuit.add(gates.CU1(q, q + 1, theta=0)) if qubits > 2: for q in range(1, qubits + 1, 2): circuit.add(gates.CU1(q, (q + 1) % qubits, theta=0)) for q in range(qubits): for _ in range(2): circuit.add(gates.RY(q, theta=0)) circuit.add(gates.RZ(q, theta=0)) circuit.add(gates.RY(q, theta=0)) def rotation(theta, x): p = circuit.get_parameters() i = 0 j = 0 for l in range(layers - 1): for q in range(qubits): p[i] = map_to(x) p[i + 1:i + 3] = theta[j:j + 2] i += 3 j += 2 p[i] = .5 * maplog_to(x) p[i + 1:i + 3] = theta[j:j + 2] i += 3 j += 2 if qubits > 1: for q in range(0, qubits, 2): p[i] = theta[j] i += 1 j += 1 if qubits > 2: for q in range(1, qubits + 1, 2): p[i] = theta[j] i += 1 j += 1 for q in range(qubits): p[i] = .5 * map_to(x) p[i + 1:i + 3] = theta[j:j + 2] i += 3 j += 2 p[i] = .5 * maplog_to(x) p[i + 1:i + 3] = theta[j:j + 2] i += 3 j += 2 return p nparams = 4 * layers * qubits + \ (layers - 1) * int(K.np.ceil(qubits / 2)) * \ (int(qubits > 1) + int(qubits > 2)) return circuit, rotation, nparams
def ansatz_Weighted(layers, qubits=1): """Fourier Ansatz implementation. 4 parameters per layer and qubit: Ry(wx + a), Rz(v log(x) + b) Args: layers (int): number of layers. qubits (int): number of qubits. Returns: The circuit, the rotation function and the total number of parameters. """ circuit = Circuit(qubits) for _ in range(layers - 1): for q in range(qubits): circuit.add(gates.RY(q, theta=0)) circuit.add(gates.RZ(q, theta=0)) if qubits > 1: for q in range(0, qubits, 2): circuit.add(gates.CU1(q, (q + 1) % qubits, theta=0)) if qubits > 2: for q in range(1, qubits + 1, 2): circuit.add(gates.CU1(q, (q + 1) % qubits, theta=0)) for q in range(qubits): circuit.add(gates.RY(q, theta=0)) circuit.add(gates.RZ(q, theta=0)) def rotation(theta, x): p = circuit.get_parameters() i = 0 j = 0 for l in range(layers - 1): for q in range(qubits): p[i] = theta[j] + theta[j + 1] * map_to(x) p[i + 1] = theta[j + 2] + theta[j + 3] * maplog_to(x) i += 2 j += 4 if qubits > 1: for q in range(0, qubits, 2): p[i] = theta[j] i += 1 j += 1 if qubits > 2: for q in range(1, qubits + 1, 2): p[i] = theta[j] i += 1 j += 1 for q in range(qubits): p[i] = theta[j] + theta[j + 1] * map_to(x) p[i + 1] = theta[j + 2] + theta[j + 3] * maplog_to(x) i += 2 j += 4 return p nparams = 4 * layers * qubits + \ (layers - 1) * int(K.np.ceil(qubits / 2)) * \ (int(qubits > 1) + int(qubits > 2)) return circuit, rotation, nparams
def custom_circuit(initial_state, theta): l1 = gates.X(0)(initial_state) l2 = gates.X(1)(l1) o = gates.CU1(0, 1, theta)(l2) return o