def fromCircuit(circuit, initial_qubit_placement=None, final_qubit_placement=None):
     if isinstance(circuit, TketCircuit):
         circuit = tk_to_pyzx(circuit)
     zphases = {}
     current_parities = mat22partition(Mat2.id(circuit.qubits))
     if initial_qubit_placement is not None:
         current_parities = ["".join([row[i] for i in initial_qubit_placement]) for row in current_parities]
     for gate in circuit.gates:
         parity = current_parities[gate.target]
         if gate.name in ["CNOT", "CX"]:
             # Update current_parities
             control = current_parities[gate.control]
             current_parities[gate.target] = "".join([str((int(i)+int(j))%2) for i,j in zip(control, parity)])
         elif isinstance(gate, ZPhase):
             # Add the T rotation to the phases
             if parity in zphases:
                 zphases[parity] += gate.phase
             else: 
                 zphases[parity] = gate.phase
         else:
             print("Gate not supported!", gate.name)
     def clamp(phase):
         new_phase = phase%2
         if new_phase > 1:
             return new_phase -2
         return new_phase
     zphases = {par:clamp(r) for par, r in zphases.items() if clamp(r) != 0}
     if final_qubit_placement is not None:
         current_parities = [ current_parities[i] for i in final_qubit_placement]
     return PhasePoly(zphases, current_parities)
示例#2
0
 def update_matrix(self):
     self.matrix = Mat2.id(self.n_qubits)
     for gate in self.gates:
         if hasattr(gate, "name") and gate.name == "CNOT":
             self.matrix.row_add(gate.control, gate.target)
         else:
             print("Warning: CNOT tracker can only be used for circuits with only CNOT gates!")
 def to_tket(self):
     if self.out_par != mat22partition(Mat2.id(self.n_qubits)):
         print(self.out_par)
         raise NotImplementedError("The linear transformation part of the phase polynomial cannot yet be transformed into a tket circuit")
     circuit = TketCircuit(self.n_qubits)
     for parity, phase in self.zphases.items():
         qubits = [i for i,s in enumerate(parity) if s == '1']
         circuit.add_pauliexpbox(PauliExpBox([Pauli.Z]*len(qubits), phase), qubits)
     # TODO add the linear combination part with CNOTs
     Transform.DecomposeBoxes().apply(circuit)
     return circuit
示例#4
0
def build_random_parity_map(qubits, n_cnots, circuit=None):
    """
    Builds a random parity map.

    :param qubits: The number of qubits that participate in the parity map
    :param n_cnots: The number of CNOTs in the parity map
    :param circuit: A (list of) circuit object(s) that implements a row_add() method to add the generated CNOT gates [optional]
    :return: a 2D numpy array that represents the parity map.
    """
    if circuit is None:
        circuit = []
    if not isinstance(circuit, list):
        circuit = [circuit]
    g = generate_cnots(qubits=qubits, depth=n_cnots)
    c = Circuit.from_graph(g)
    matrix = Mat2.id(qubits)
    for gate in c.gates:
        matrix.row_add(gate.control, gate.target)
        for c in circuit:
            c.row_add(gate.control, gate.target)
    return matrix.data
def make_random_phase_poly(n_qubits, n_gadgets, return_circuit=False):
    parities = set()
    if n_gadgets > 2**n_qubits:
        n_gadgets=n_qubits^3
    if n_qubits < 26:
        for integer in np.random.choice(2**n_qubits-1, replace=False, size=n_gadgets):
            parities.add(integer+1)
    elif n_qubits < 64:
        while len(parities) < n_gadgets:
            parities.add(np.random.randint(1, 2**n_qubits))
    else:
        while len(parities) < n_gadgets:
            parities.add("".join(np.random.choice(["0", "1"], n_qubits, replace=True)))
    if n_qubits < 64:
        parities = [("{0:{fill}"+str(n_qubits)+"b}").format(integer, fill='0', align='right') for integer in parities]
    zphase_dict = {"".join([str(int(i)) for i in p]):Fraction(1,4) for p in parities}
    out_parities = mat22partition(Mat2.id(n_qubits))
    phase_poly = PhasePoly(zphase_dict, out_parities)
    if return_circuit:
        return route_phase_poly(phase_poly, create_architecture(FULLY_CONNECTED, n_qubits=n_qubits), do_matroid="arianne")
    return phase_poly
示例#6
0
 def __init__(self, n_qubits, **kwargs):
     super().__init__(n_qubits, **kwargs)
     self.matrix = Mat2.id(n_qubits)
     self.row_perm = np.arange(n_qubits)
     self.col_perm = np.arange(n_qubits)
     self.n_qubits = n_qubits
示例#7
0
 def test_inverse(self):
     inv = self.m4.inverse()
     self.assertEqual(inv * self.m4, Mat2.id(5))
     self.assertEqual(self.m4 * inv, Mat2.id(5))