def test_multiqubit_permutation_rules(linkedlist, eng): rules = BasePermutationRules(linkedlist) qureg = eng.allocate_qureg(4) reg1 = qureg[:-1] reg2 = qureg[1:] H = projectq.ops.QubitOperator T = projectq.ops.send_time_evolution left = T(-cmath.pi / 4, H("X0 Z1 Z2")) right = T(-cmath.pi / 4, H("Z0 Z1 Y2")) linkedlist.push_back(left.generate_command(reg1)) linkedlist.push_back(right.generate_command(reg2)) print(linkedlist.head.data) print(linkedlist.back.data) rules.permute(linkedlist.head, linkedlist.back) print(linkedlist.head.data) print(linkedlist.back.data) assert (linkedlist.head.data.gate.time == -cmath.pi / 4) assert (linkedlist.back.data.gate.time == -cmath.pi / 4) # TODO: write more checks for multi qubit operators return
def test_H_X_different_targets(linkedlist, eng): rules = BasePermutationRules(linkedlist) qureg = eng.allocate_qureg(3) H = projectq.ops.H Rx = projectq.ops.X linkedlist.push_back(H.generate_command(qureg[0])) linkedlist.push_back(Rx.generate_command(qureg[1])) rules.permute(linkedlist.head, linkedlist.back) assert (isinstance(linkedlist.head.data.gate, projectq.ops.Rx)) assert (linkedlist.back.data.gate == H) return
def _gate_of_interest(self, node): if (isinstance(node.data.gate, ClassicalInstructionGate) and not isinstance(node.data.gate, FastForwardingGate)): return True if (BasePermutationRules.is_clifford(node.data.gate)): return False return True
def receive(self, command_list): """ Receive commands from the previous engine and cache them. If a flush gate arrives, this engine assumes the circuit is finished and sends the permuted circuit to the next engine. """ for cmd in command_list: if (isinstance(cmd.gate, gates.FlushGate)): # flush gate --> returns the current stabilizers as parity measurements self.perform_simulation() # reset the simulator self._gates = [] self._simulator = CliffordSimulator() self.send([cmd]) elif (isinstance(cmd.gate, gates.AllocateQubitGate)): self._simulator.add_qubit_to_dict(cmd.qubits[0]) self.send([cmd]) # send gate along elif (isinstance(cmd.gate, gates.MeasureGate)): self._simulator.add_stabilizer([(cmd.qubits[0], "Z")]) elif (isinstance(cmd.gate, gates.ClassicalInstructionGate)): return elif (BasePermutationRules.is_clifford(cmd.gate)): self._gates.append(cmd) elif (len(self._gates) == 0): # non-clifford rotation from the beginning of the circuit self.send([cmd]) else: # new command raise TypeError("This gate is not supported")
def test_Rzpi2_Rxpi(linkedlist, eng): rules = BasePermutationRules(linkedlist) qureg = eng.allocate_qureg(3) Rz = projectq.ops.Rz(cmath.pi / 2) Rx = projectq.ops.Rx(cmath.pi) linkedlist.push_back(Rz.generate_command(qureg[0])) linkedlist.push_back(Rx.generate_command(qureg[0])) rules.permute(linkedlist.head, linkedlist.back) assert (isinstance(linkedlist.head.data.gate, projectq.ops.Rx)) assert (isinstance(linkedlist.back.data.gate, projectq.ops.Rz)) assert (abs(linkedlist.back.data.gate.angle - (4 * cmath.pi - cmath.pi / 2)) < _PRECISION) return
def _permutation_required(self, left): if (left == None or isinstance(left.data.gate, AllocateQubitGate) or isinstance(left.data.gate, AllocateDirtyQubitGate)): return False return BasePermutationRules.is_clifford(left.data.gate)
def _gate_of_interest(self, node): if(BasePermutationRules.is_clifford(node.data.gate)): return True return False
def test_control_gates(linkedlist, eng): rules = BasePermutationRules(linkedlist) qureg = eng.allocate_qureg(4) # TODO: write tests return