def test_no_state_modification_circuit(self) -> None: """ We apply Sabre on a circuit which doesn't modify the initial state (|0^n> here) and we verify Sabre circuit modifications don't modify the state. """ for nbqbit in range(min_nbqbit, max_nbqbit): prog = Program() qbits = prog.qalloc(nbqbit) random_angles = [ rd.random() * 2 * np.pi for _ in range(3 * nbqbit) ] for i in range(len(qbits)): prog.apply(RX(random_angles[3 * i]), qbits[i]) prog.apply(RX(random_angles[3 * i + 1]), qbits[i]) prog.apply(RX(random_angles[3 * i + 2]), qbits[i]) prog.apply(QFT(nbqbit), qbits) prog.apply(QFT(nbqbit).dag(), qbits) for i in range(len(qbits)): prog.apply(RX(random_angles[3 * i]).dag(), qbits[i]) prog.apply(RX(random_angles[3 * i + 1]).dag(), qbits[i]) prog.apply(RX(random_angles[3 * i + 2]).dag(), qbits[i]) circuit = prog.to_circ(inline=True) for topology in generate_custom_topologies(nbqbit): qpu = Sabre() | (QuameleonPlugin(topology=topology) | PyLinalg()) result = qpu.submit(circuit.to_job()) assert result.raw_data[0].state.int == 0
def generate_qft_circuit(nbqbits: int, inline: bool = True) -> Circuit: """ Creates a quantum circuit composed of an initialization and a QFT applied on all qubits. Args: nbqbits (int): number of qubits in the circuit inline (bool, optional): True to inline the circuit, False otherwise, default True Returns: Circuit: a quantum circuit containing random gates """ # Initialize program and qregister prog = Program() qbits = prog.qalloc(nbqbits) # Qubits initialization (to have a non |0^n> state) for qbit in qbits: prog.apply(H, qbit) prog.apply(Z, qbit) # Apply QFT on all qubits prog.apply(QFT(nbqbits), qbits) return prog.to_circ(inline=inline)
def test_qft(self): """ Testing simulation of inlined/not-inlined QFT """ prog = Program() qbits = prog.qalloc(5) prog.apply(QFT(5), qbits) circuit_default = prog.to_circ() circuit_inlined = prog.to_circ(inline=True) qpu = PyLinalg() psi_d = wavefunction(circuit_default, qpu) psi_i = wavefunction(circuit_inlined, qpu) self.assertAlmostEqual(np.linalg.norm(psi_d - psi_i), 0.)
def build_quantum_program(n: int, x: int) -> Job: """ Creates the quantum circuit used to solve the period-finding problem. :param n: (int) the integer to be factoring :param x: (int) the random number used to solve the period-finding problem :return: (Job) the quantum job to send to the QPU """ # Create the quantum program quantum_program = Program() # Create the two quantum registers nbqbits_reg1 = int(np.trunc(np.log2(n**2))) + 1 nbqbits_reg2 = int(np.trunc(np.log2(n)) + 1) reg1 = quantum_program.qalloc(nbqbits_reg1) reg2 = quantum_program.qalloc(nbqbits_reg2) # Initialize the quantum registers for qbit in reg1: quantum_program.apply(H, qbit) quantum_program.apply(X, reg2[-1]) # Apply modular exponentiation on both registers quantum_program.apply(modular_exp(nbqbits_reg1, nbqbits_reg2, x, n), reg1, reg2) # Apply QFT on reg1 quantum_program.apply(QFT(nbqbits_reg1), reg1) # Build quantum circuit circuit = quantum_program.to_circ(link=[qat.lang.AQASM.qftarith]) # Return the job specifying that reg1 has to measured at the end of the execution of the quantum program return circuit.to_job(qubits=reg1, nbshots=1)