Source code for mermin_on_qiskit.hypergraphstates

from qiskit import *


[docs]def circuit_creation(n, hyperedges): """ Creates an empty circuit with the number of qubits required. :param int n: The number of qubits of which depends the number of wires to create. :param list[list[int]] hyperedges: A list containing the lists of the vertices which are linked by an hyperedge. :returns: QuantumCircuit -- A circuit with the required number of quantum wires and classical wires. """ created = False i = 0 qubits = 0 while not created and i < len(hyperedges): hyperedge = hyperedges[i] if len(hyperedge) > 3: qubits = 2 * n - 2 created = True i += 1 if not created: qubits = n circuit = QuantumCircuit(qubits, n) return circuit
[docs]def circuit_initialisation(n, hyperedges): r""" Creates an empty circuit with the number of qubits required and places the circuit in the initial state before adding gates for calculations. Places and Hadamard gate on every main (non additional) qubits wire. This is needed in order to place the qubits in a `|+>` state which is `(|0> + |1>) / sqrt(2)`. :param int n: The number of qubits of which depends the number of wires to create. :param list[list[int]] hyperedges: A list containing the lists of the vertices which are linked by an hyperedge. :returns: QuantumCircuit -- The created and initialized circuit. """ circuit = circuit_creation(n, hyperedges) circuit.h(range(n)) return circuit
[docs]def edges_layout(n, hyperedges, circuit): """ Disposes all the gates corresponding to the edges. In fact, for a two-vertices edge, there not much to do, as for a three-vertices edge, too. For more an edge of than three vertices, things are a little different. First, Toffoli gates are used to link qubits two by two. The target qubit here is an auxiliary qubit. Then, the last link is a simple CZ. But all the Toffoli gates that we put create an entanglement which is removed by replacing exactly the same gates again after the CZ. :param int n: The number of qubits. :param list[list[int] hyperedges: The list of the vertices which are linked by an hyperedge. :param QuantumCircuit circuit: The circuit that will be modified. :return: None """ for hyperedge in hyperedges: if len(hyperedge) == 2: circuit.cz(hyperedge[0], hyperedge[1]) if len(hyperedge) == 3: # The target qubit is the third one circuit.h(hyperedge[2]) circuit.toffoli(*hyperedge) circuit.h(hyperedge[2]) if len(hyperedge) > 3: # Here, the process is different. We'll place many Toffoli gates to # form the hypergraph-state which creates an entanglement. So, we # place new Toffoli gates again for cancel the entanglement vertex_index = 0 maximum = len(hyperedge) - 1 qubit_aux = n circuit.toffoli(hyperedge[vertex_index], hyperedge[vertex_index + 1], qubit_aux) vertex_index += 2 while vertex_index < maximum: circuit.toffoli(hyperedge[vertex_index], qubit_aux, qubit_aux + 1) qubit_aux += 1 vertex_index += 1 circuit.cz(qubit_aux, hyperedge[vertex_index]) qubit_aux -= 1 vertex_index -= 1 while maximum > 2: circuit.toffoli(qubit_aux - 1, hyperedge[vertex_index], qubit_aux) qubit_aux -= 1 vertex_index -= 1 maximum -= 1 circuit.toffoli(hyperedge[vertex_index], hyperedge[vertex_index - 1], qubit_aux)