def grover_invert(f, y, n): """Grover's algorithm for inverting a general function f that maps a sequence of n bits (represented as an int whose binary representation is the bit sequence) to another sequence of bits. Args: f: Function to invert y: Value of the function at which to evaluate the inverse. Returns: The input x such that f(x) = y. If more than one input suffices, it returns one at random. If no input suffices, returns -1. """ if n <= 0: raise ValueError('n must be positive') Hn = hadamard_gate(n) Ui = _function_oracle(f, y, n) Ud = grover_diffusion_operator(n) MAX_ITER = 50 count = 0 x = None # Repeat until a solution is found or the iteration limit is reached while count < MAX_ITER and (x is None or f(x) != y): q = QubitSystem(n) # system of n bits in state |0> # apply Hadamard gate to create uniform superposition of basis states Hn * q for _ in range(_r(2**n)): Ui * q # apply operator that flips the sign of the matching index Ud * q # apply Grover's diffusion operator x = q.measure() count += 1 return x if f(x) == y else -1
def grover_search(match_text, lst): """Grover's quantum algorithm for searching. Args: match_text: Text to find in the list lst. lst: List of strings to search to find a string matching match_text. Returns: The index i of the item such that lst[i] is the same string as match_text. The lines must match exactly; it is not enough for the text to be contained in the line. If two or more lines match, it will only return one of the line numbers. Returns -1 if no matching line is found, i.e. the algorithm fails to find a solution. """ if len(lst) <= 0: raise ValueError('List must be of positive length') n = len(lst) N = int(ceil(log(n, 2))) # number of qubits needed Hn = hadamard_gate(N) Ui = _search_oracle(match_text, lst) Ud = grover_diffusion_operator(N) MAX_ITER = 50 count = 0 index = n # Repeat until a solution is found or the iteration limit is reached while count < MAX_ITER and (index >= n or lst[index] != match_text): q = QubitSystem(N) # system of log2(n) bits in state |0> # apply Hadamard gate to create uniform superposition of basis states Hn * q for _ in range(_r(2**N)): Ui * q # apply operator that flips the sign of the matching index Ud * q # apply Grover's diffusion operator index = q.measure() count += 1 return index if index < n and lst[index] == match_text else -1