def h(self, qubit_index): """Applies the Hadamard transformation to a qubit. Args: qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["H"], qubit_index)
def s(self, qubit_index): """Applies the π/4 phase gate to a qubit. Args: qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["S"], qubit_index)
def t_dagger(self, qubit_index): """Applies the adjoint of T gate to a qubit. Args: qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["TDagger"], qubit_index)
def id(self, qubit_index): """Applies the Identity gate to a qubit. Args: qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["Id"], qubit_index)
def cnot(self, control_index, target_index): """Applies the controlled-NOT(CNOT) gate to a pair of qubits. Args: control_index: Index of the control qubit, starts from 0. target_index: Index of the target qubit, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["X"], target_index, [control_index])
def ccnot(self, control_index_1, control_index_2, target_index): """Applies the CCNOT(toffoli) gate to three qubits. Args: control_index_1: Index of the first control qubit, starts from 0. control_index_2: Index of the second control qubit, starts from 0. target_index: Index of the target qubit, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["X"], target_index, [control_index_1, control_index_2])
def reset(self, qubit_index): """Reset a qubit to |0>. When the qubit is entangled with other qubits, those qubits would also collapse with the role of quantum measurement. Args: qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ measure_result = _measure(self.amplitudes, [qubit_index]) _collapse(self.amplitudes, [qubit_index], measure_result) if measure_result[0] == "1": _apply_gate(self.amplitudes, self._single_qubit_gates["X"], qubit_index)
def multi_controlled_gate(self, gate, qubit_index, control_index_list): """Applies a specific gate to a qubit with controls of other qubits. Args: gate: Specific gate to be executed. comes from "X, Y, Z, H, S, T, Id, SDagger, TDagger". qubit_index: Index of the target qubit, starts from 0. control_index_list: List of indices of the control qubits, the index in this list should starts from 0. """ assert gate in self._single_qubit_gates.keys(), \ 'Gate should be one from "X, Y, Z, H, S, T, Id, SDagger, TDagger"' _apply_gate(self.amplitudes, self._single_qubit_gates[gate], qubit_index, control_index_list)
def rz(self, theta, qubit_index): """Applies the RZ gate to a qubit. The RZ gate manipulates a qubit as a rotation with an angle theta about Z-axis. Args: theta: Angle about which the qubit is to be rotated. qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ a = np.exp(-1j * theta / 2) d = np.exp(1j * theta / 2) gate_matrix = np.array([[a, 0], [0, d]]) _apply_gate(self.amplitudes, gate_matrix, qubit_index)
def measure_x(self, qubit_index): """Performs a measurement of a single qubit in Pauli X basis. Args: qubit_index: Index of qubit to be measured, starts from 0. Returns: "0" or "1" as type string. Represent the state |0> and |1> . """ _apply_gate(self.amplitudes, self._single_qubit_gates["H"], qubit_index) measure_result = _measure(self.amplitudes, [qubit_index]) _collapse(self.amplitudes, [qubit_index], measure_result) _apply_gate(self.amplitudes, self._single_qubit_gates["H"], qubit_index) return measure_result[0]
def ry(self, theta, qubit_index): """Applies the RY gate to a qubit. The RY gate manipulates a qubit as a rotation with an angle theta about Y-axis. Args: theta: Angle about which the qubit is to be rotated. qubit_index: Index of qubit to which the gate should be applied, starts from 0. """ a = np.cos(theta / 2) b = -np.sin(theta / 2) c = np.sin(theta / 2) d = np.cos(theta / 2) gate_matrix = np.array([[a, b], [c, d]]) _apply_gate(self.amplitudes, gate_matrix, qubit_index)
def multi_controlled_rz(self, theta, qubit_index, control_index_list): """Applies the RZ gate to a qubit with controls of other qubits. The RZ gate manipulates a qubit as a rotation with an angle theta about Z-axis. Args: theta: Angle about which the qubit is to be rotated. qubit_index: Index of the target qubit, starts from 0. control_index_list: List of indices of the control qubits, the index in this list should starts from 0. """ a = np.exp(-1j * theta / 2) d = np.exp(1j * theta / 2) gate_matrix = np.array([[a, 0], [0, d]]) _apply_gate(self.amplitudes, gate_matrix, qubit_index, control_index_list)
def swap(self, qubit_1_index, qubit_2_index): """Applies the SWAP gate to a pair of qubits. Args: qubit_1_index: Index of the first qubit to be swapped, starts from 0. qubit_2_index: Index of the first qubit to be swapped, starts from 0. """ _apply_gate(self.amplitudes, self._single_qubit_gates["X"], qubit_2_index, [qubit_1_index]) _apply_gate(self.amplitudes, self._single_qubit_gates["X"], qubit_1_index, [qubit_2_index]) _apply_gate(self.amplitudes, self._single_qubit_gates["X"], qubit_2_index, [qubit_1_index])