def prepare(_, circuit, key, value, ancilla, extra): for i in range(len(value)): for j in range(len(key) - 1): controlled_ry(circuit, 1 / 2**len(value) * 2 * np.pi * 2**(i + 1), [key[j], key[j + 1], value[i]], extra, ancilla[0]) # sum on powers of 2 iqft(circuit, [value[i] for i in range(len(value))])
def prepare(f, circuit, key, value, ancilla, extra): # controlled rotations only n powers of 2 for i in range(len(value)): for j in range(len(key)): controlled_ry(circuit, 1 / 2**len(value) * 2 * np.pi * 2**(i + 1) * f[j], [key[j], value[i]], extra, ancilla[0]) # sum on powers of 2 iqft(circuit, [value[i] for i in range(len(value))])
def prepare(f, circuit, key, value, ancilla, extra): for i in range(len(value)): for k in range(2**len(key)): on_match_ry(len(key), k, circuit, 1 / 2**len(value) * 2 * np.pi * 2**(i + 1) * f[k], [key[j] for j in range(0, len(key))] + [value[i]], extra, ancilla) iqft(circuit, [value[i] for i in range(len(value))])
def prepare(d, circuit, key, value, ancilla, extra): for i in range(len(value)): if d.get(-1, 0) != 0: cry(1/2 ** len(value) * 2 * np.pi * 2 ** (i + 1) * d[-1], circuit, value[i], ancilla[0]) for j in range(len(key)): if d.get(j, 0) != 0: controlled_ry(circuit, 1/2 ** len(value) * 2 * np.pi * 2 ** (i + 1) * d[j], [key[j], value[i]], extra, ancilla[0]) # sum on powers of 2 for i in range(len(value)): for k, v in d.items(): if isinstance(k, tuple): controlled_ry(circuit, 1/2 ** len(value) * 2 * np.pi * 2 ** (i+1) * v, [key[k[0]], key[k[1]]] + [value[i]], extra, ancilla) # cry(1/2 ** len(value) * 2 * np.pi * 2 * -1, circuit, value[0], ancilla[0]) # flips 0 sign bit to 1 # circuit.u1(1/2 ** len(value) * 2 * np.pi * 1, value[0]) # controlled_X(circuit, [value[0]] + [ value[i] for i in range(len(value) - bit, len(value))], extra, value[len(value) - bit]) iqft(circuit, [value[i] for i in range(len(value))])
def __build_circuit_count(self, n_qbits, c_qbits, f, oracle): key = QuantumRegister(n_qbits) value = QuantumRegister(c_qbits) ancilla = QuantumRegister(1) extra = QuantumRegister(6) precision = QuantumRegister(self.precision_bits) circuit = QuantumCircuit(precision, key, value, ancilla, extra) # TODO make arguments def prepare_once(): circuit.h(key) circuit.h(value) circuit.h(precision) # eigenvector for Ry circuit.rx(np.pi / 2, ancilla[0]) circuit.z(ancilla[0]) circuit.x(ancilla[0]) def unprepare_once(): circuit.rx(-np.pi / 2, ancilla[0]) # amplitude estimation (counting) algorithm prepare_once() for i in range(len(precision)): for _ in range(2**i): # oracle self.prepare(f, circuit, key, value, ancilla, extra) if oracle is not None: oracle(circuit, [precision[i]], value, extra, ancilla) self.unprepare(f, circuit, key, value, ancilla, extra) # diffusion diffusion(circuit, [precision[i]], [key[i] for i in range(len(key))], extra) # if f(0) = 0 # diffusion(circuit, [precision[i]], [key[i] for i in range(len(key))] + [value[i] for i in range(len(value))], extra) # inverse fourier tranform iqft(circuit, [precision[i] for i in range(len(precision))]) unprepare_once() return circuit