def __init__(self): """ Initializes the gate to its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ def subtract(a, b): return (a, b - a) BasicMathGate.__init__(self, subtract)
def test_limited_capability_engine_arithmetic(): default_eng = LimitedCapabilityEngine() eng = LimitedCapabilityEngine(allow_arithmetic=True) m = MainEngine(backend=DummyEngine(), engine_list=[eng]) q = m.allocate_qureg(5) inc = BasicMathGate(lambda x: x + 1) assert not default_eng.is_available(inc.generate_command(q)) assert eng.is_available(inc.generate_command(q))
def __init__(self, a): """ Initializes the gate to the base of which the inverse needs to be found Args: base (int): base of which the inverse needs to be found for modular multiplication It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ def extended_gcd(a, b): # calculates the gcd and the coefficients of Bezout's identity lastremainder, remainder = abs(a), abs(b) x, lastx, y, lasty = 0, 1, 1, 0 while remainder != 0: lastremainder, (quotient, remainder) = remainder, divmod( lastremainder, remainder) x, lastx = lastx - quotient * x, x y, lasty = lasty - quotient * y, y return lastremainder, lastx, lasty def find_inverse(value, mod): # if the gcd is not equal to one, the value does not have an inverse. # if it is, the inverse is the first Bezout coefficient modulus mod (gcd, x, y) = extended_gcd(value, mod) if gcd != 1: return 'undefined' return x % mod def mod(exponent, modulus, val): # does not change the val if it is bigger than the modulus (this # would be irreversible) or if the modulus = 0 (division by 0 not # possible) base = a if exponent == 0 or modulus == 0 or val >= modulus: return (exponent, modulus, val) else: base = base inverse = find_inverse(base, modulus) if inverse == 'undefined': return (exponent, modulus, val) exp = exponent while (exp > 0): # if exp is odd, multiply inverse with val if ((exp & 1) != 0): val = (val * inverse) % modulus # square the inverse (base) inverse = (inverse * inverse) % modulus # binary shift exp >>= 1 return (exponent, modulus, val) BasicMathGate.__init__(self, mod) self.a = a
def __init__(self, a): """ Initializes the gate to the number to add. Args: a (int): Number to add to a quantum register. It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ BasicMathGate.__init__(self, lambda x: ((x + a), )) self.a = a
def __init__(self): """ Initializes the gate to its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ def compare(a, b, c): if b < a: if c == 0: c = 1 else: c = 0 return (a, b, c) BasicMathGate.__init__(self, compare)
def __init__(self): """ Initializes the gate to its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ def mod(modulus, val): if modulus == 0 or val >= modulus: return (modulus, val) if val == 0: return (modulus, modulus - 1) else: return (modulus, val - 1) BasicMathGate.__init__(self, mod)
def __init__(self, a, N): """ Initializes the gate to the number to add modulo N. Args: a (int): Number to add to a quantum register (0 <= a < N). N (int): Number modulo which the addition is carried out. It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ BasicMathGate.__init__(self, lambda x: ((x + a) % N, )) self.a = a self.N = N
def test_simulator_is_available(sim): backend = DummyEngine(save_commands=True) eng = MainEngine(backend, []) qubit = eng.allocate_qubit() Measure | qubit BasicMathGate(lambda x: x) | qubit del qubit assert len(backend.received_commands) == 4 # Test that allocate, measure, basic math, and deallocate are available. for cmd in backend.received_commands: assert sim.is_available(cmd) new_cmd = backend.received_commands[-1] new_cmd.gate = Mock1QubitGate() assert sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 new_cmd.gate = Mock2QubitGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 new_cmd.gate = MockNoMatrixGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 1 eng = MainEngine(sim, []) qubit1 = eng.allocate_qubit() qubit2 = eng.allocate_qubit() with pytest.raises(Exception): Mock2QubitGate() | (qubit1, qubit2)
def test_simulator_is_available(sim): backend = DummyEngine(save_commands=True) eng = MainEngine(backend, []) qubit = eng.allocate_qubit() Measure | qubit BasicMathGate(lambda x: x) | qubit qubit[0].__del__() assert len(backend.received_commands) == 4 # Test that allocate, measure, basic math, and deallocate are available. for cmd in backend.received_commands: assert sim.is_available(cmd) new_cmd = backend.received_commands[-1] new_cmd.gate = Mock1QubitGate() assert sim.is_available(new_cmd) assert new_cmd.gate.cnt == 4 new_cmd.gate = Mock6QubitGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 4 new_cmd.gate = MockNoMatrixGate() assert not sim.is_available(new_cmd) assert new_cmd.gate.cnt == 7
def __init__(self, a): """ Initializes the gate to the base to be used for modular exponentiation. Args: base (int): base for the modular exponentiation. It also initializes its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. Example: .. code-block:: python MultiplyModN(2) | (qureg1, qureg2, qureg3) """ def mod(exponent, modulus, val): # does not change the val if it is bigger than the modulus (this # would be irreversible) or if the modulus = 0 (division by 0 not # possible) if modulus == 0 or val >= modulus: return (exponent, modulus, val) else: # repeated squaring algorithm base = a exp = exponent while (exp > 0): # if exp is odd, multiply inverse with val if ((exp & 1) != 0): val = (val * base) % modulus # square the base base = (base * base) % modulus # binary shift exp >>= 1 return (exponent, modulus, val) BasicMathGate.__init__(self, mod) self.a = a
def __init__(self): BasicMathGate.__init__(self, lambda x, y: (x, y - x))
def __init__(self, amount): BasicMathGate.__init__(self, lambda x: (x + amount, ))
def __init__(self): def do_not_call(*_): raise AssertionError() BasicGateEx.__init__(self) BasicMathGate.__init__(self, do_not_call)
def __init__(self): BasicMathGate.__init__(self, lambda x: (x + 2, ))
def zoo_profile(): """Generate and display the zoo of quantum gates.""" # create a main compiler engine with a drawing backend drawing_engine = CircuitDrawer() locations = {0: 1, 1: 2, 2: 0, 3: 3} drawing_engine.set_qubit_locations(locations) main_eng = MainEngine(drawing_engine) qureg = main_eng.allocate_qureg(4) # define a zoo of gates te_gate = TimeEvolution(0.5, 0.1 * QubitOperator('X0 Y2')) def add(x, y): return x, y + 1 zoo = [ (X, 3), (Y, 2), (Z, 0), (Rx(0.5), 2), (Ry(0.5), 1), (Rz(0.5), 1), (Ph(0.5), 0), (S, 3), (T, 2), (H, 1), (Toffoli, (0, 1, 2)), (Barrier, None), (Swap, (0, 3)), (SqrtSwap, (0, 1)), (get_inverse(SqrtSwap), (2, 3)), (SqrtX, 2), (C(get_inverse(SqrtX)), (0, 2)), (C(Ry(0.5)), (2, 3)), (CNOT, (2, 1)), (Entangle, None), (te_gate, None), (QFT, None), (Tensor(H), None), (BasicMathGate(add), (2, 3)), (All(Measure), None), ] # apply them for gate, pos in zoo: if pos is None: gate | qureg elif isinstance(pos, tuple): gate | tuple(qureg[i] for i in pos) else: gate | qureg[pos] main_eng.flush() # generate latex code to draw the circuit s = drawing_engine.get_latex() prefix = 'zoo' with open('{}.tex'.format(prefix), 'w') as f: f.write(s) # compile latex source code and open pdf file os.system('pdflatex {}.tex'.format(prefix)) openfile('{}.pdf'.format(prefix))
def shor(N): # Check if number is even if N % 2 == 0: print('Even number.') return 2 # Step 1: Chose 1 < a < N uniformly at random a = np.random.randint(2,N) # Step 2: Compute b = gcd(a,N). If b > 1, output b and stop b = gcd(a,N) if b > 1: print('Factor found by guessing:', b) return b # Step 3: Find the order r of a modulo N for f(x) = a^x mod N # Quantum Part: using approximate periodicity to find r m = int(np.ceil(np.log2(N**2))) # Size of first register M = 2**m # M is the smallest power of 2 greater than N^2 n = int(np.ceil(np.log2(N-1))) # Size of second register - need to represent 0 to N-1 # Check we can simulate on our local simulator if m + n > 28: # 28 qubits = 4GB of RAM print('Number of qubits required =', m+n, 'which is too large to simulate.') return 0 engine = MainEngine() # Initialise registers reg_1 = engine.allocate_qureg(m) reg_2 = engine.allocate_qureg(n) # Apply QFT to first register All(H) | reg_1 # Define the oracle O_f|x>|y> = |x>|y + f(x)> where + is bitwise XOR def O_f(x,y) : return (x, y^pow(a,x,N)) # Apply oracle to both registers BasicMathGate(O_f) | (reg_1, reg_2) # Measure the second register All(Measure) | reg_2 # Apply the QFT to the first register #QFT | reg_1 for i in reversed(range(m)): H | reg_1[i] for d in range(1,i+1): C(R(np.pi/(2**d))) | (reg_1[i-d], reg_1[i]) for i in range(int(m/2)): Swap | (reg_1[i], reg_1[m-i-1]) # Measure the first register All(Measure) | reg_1 # Run the approximate peridicity algorithm engine.flush() # Determine output y of algorithm y = 0 for i in range(m): y = y + 2**i*int(reg_1[i]) # Use continued fraction expansion of z = y/M to find r r = Fraction(y,M).limit_denominator(N).denominator # If r is odd the algorithm fails if r % 2 == 1: print('Order r found is odd: algorithm failed') return 0 # Step 4: Find factor of N s = gcd(a**(r//2)-1, N) if s == 1 or s == N: print('Factor found is 1 or', N,': algorithm failed') return N print('Factor found by Shor\'s algorithm is', s, 'using', m+n, 'qubits') return s
def shor(N): # Check if number is even if N % 2 == 0: print('Even number.') return 2 # Step 1: Chose 1 < a < N uniformly at random a = np.random.randint(2, N) #a = 11 # Step 2: Compute b = gcd(a,N). If b > 1, output b and stop b = gcd(a, N) if b > 1: print('Factor found by guessing:', b) return b # Step 3: Find the order r of a modulo N for f(x) = a^x mod N # Quantum Part: using approximate periodicity to find r m = int(np.ceil(np.log2(N**2))) # Size of first register M = 2**m # M is the smallest power of 2 greater than N^2 n = int(np.ceil( np.log2(N - 1))) # Size of second register - need to represent 0 to N-1 # Check we can simulate on our local simulator if m + n > 28: # 28 qubits = 4GB of RAM print('Number of qubits required =', m + n, 'which is too large to simulate.') return 0 engine = MainEngine() # Initialise registers reg_1 = engine.allocate_qureg(m) reg_2 = engine.allocate_qureg(n) # Apply QFT to first register All(H) | reg_1 # Define the oracle O_f|x>|y> = |x>|y + f(x)> where + is bitwise XOR def O_f(x, y): return (x, y ^ pow(a, x, N)) # Apply oracle to both registers BasicMathGate(O_f) | (reg_1, reg_2) # Measure the second register All(Measure) | reg_2 engine.flush() y = 0 for i in range(n): y = y + 2**i * int(reg_2[i]) Deallocate | reg_2[i] #engine.deallocate_qubit(reg_2[i]) print(y) engine.flush() mapping, wavefunction = engine.backend.cheat() #print(wavefunction) # plt.plot(abs(np.asarray(wavefunction)), '.') # plt.show() fft_wf = fft(wavefunction) plt.plot(abs(fft_wf)) plt.title('FFT') plt.show() # Apply the QFT to the first register QFT | reg_1 for i in range(int(m / 2)): Swap | (reg_1[i], reg_1[m - i - 1]) #qft(reg_1) engine.flush() mapping, wavefunction = engine.backend.cheat() #print(wavefunction) d = np.nonzero(wavefunction) print(d) plt.plot(abs(np.asarray(wavefunction))) plt.title('QFT') plt.show() # wavefunction_reg2 = np.zeros(16) # for k in range(16) : # #wavefunction_reg2[k] = np.sum(wavefunction[256*k: 256*k+255]) # for i in range(256) : wavefunction_reg2[k] += wavefunction[256*k + i] # # wavefunction_reg1 = np.zeros(256) # for k in range(256) : # for i in range(i) : wavefunction_reg1[k] += wavefunction[k + 16*i] # # plt.plot(wavefunction_reg2, '.') # plt.show() # Measure the first register All(Measure) | reg_1 # Run the approximate peridicity algorithm engine.flush() # Determine output y of algorithm y = 0 for i in range(m): y = y + 2**i * int(reg_1[i]) # Use continued fraction expansion of z = y/M to find r r = Fraction(y, M).limit_denominator(N).denominator print(y, r) # If r is odd the algorithm fails if r % 2 == 1: print('Order r found is odd: algorithm failed') return 0 # Step 4: Find factor of N s = gcd(a**(r // 2) - 1, N) if s == 1 or s == N: print('Factor found is 1 or', N, ': algorithm failed') return N print('Factor found by Shor\'s algorithm is', s, 'using', m + n, 'qubits') return s
def __init__(self): """ Initializes the gate to its base class, BasicMathGate, with the corresponding function, so it can be emulated efficiently. """ BasicMathGate.__init__(self, AddQuantum.get_math_function)
def __init__(self): BasicMathGate.__init__(self, subtract)
def __init__(self): BasicMathGate.__init__(self, add)