def shor_factor(n): """Shor's factorization algorithm. Args: n: Integer >=2 to factor. Returns: If n is composite, a non-trivial factor of n. If n is prime, returns 1. Raises: ValueError if n is <= 1. """ if n <= 1: raise ValueError('n must be at least 2') if is_prime(n): return 1 if n % 2 == 0: return 2 # even numbers > 2 are trivial # Need to check that n is not a power of an integer for algorithm to work root = int_root(n) if root != -1: return root # choose m s.t. n^2 <= 2^m < 2*n^2 # log2(n^2) <= m <= log2(2 * n^2) = 1 + log2(n^2) m = ceil(log(n**2, 2)) ny = ceil(log(n - 1, 2)) # number of qubits in output of function f I = QuantumGate(eye(2**ny)) H = kron(hadamard_gate(m), I) MAX_ITER = 10 niter = 0 while True: a = n - 1 # arbitrary integer coprime to n # Initialize a system of qubits long enough to represent the integers 0 # to 2^m - 1 alongside an integer up to n - 1, then apply Hadamard gate # to the first m qubits to create a uniform superposition. q = QubitSystem(m + ny) H * q # Apply the function f(x) = a^x (mod n) to the system f = lambda x: pow(a, x, n) Uf = function_gate(f, m, ny) Uf * q # Find the period of f via quantum Fourier transform qft(q) r = 1. / q.measure() # period = 1 / frequency niter += 1 if niter >= MAX_ITER or (r % 2 == 0 and (a**(r / 2)) % n != -1): break return gcd(a**(r / 2) + 1, n)
def test_function_gate(self): f = lambda x: x >> 2 m, k = 4, 2 Uf = function_gate(f, m, k) # Initial state - M-bit binary string for 6 plus random K-bit register q = QubitSystem(m + k, 0b011010) # Expected output state: first M bits unchanged, followed by initial # string added to f(x) mod 2 (where x = first M bits) Uf * q self.assertEqual(q.measure(), 0b011011)