def create_grover(oracle_type, oracle_method): # Build the circuit if oracle_method=="log": algorithm = Grover(LogicalExpressionOracle(oracle_type),num_iterations=num_iterations) oracle_circuit = Grover(LogicalExpressionOracle(oracle_type)).construct_circuit() else: algorithm = Grover(TruthTableOracle(oracle_type),num_iterations=num_iterations) oracle_circuit = Grover(TruthTableOracle(oracle_type)).construct_circuit() display(oracle_circuit.draw(output="mpl")) display(algorithm) return(algorithm)
class byskit(): def __init__(self, backend, parents, child, evd=None): self.backend = backend self.parents = parents self.child = child self.n = int(np.shape(parents)[0] / 2) self.n_child = np.shape(child)[1] self.ctrl = QuantumRegister(self.n, 'ctrl') self.anc = QuantumRegister(self.n - 1, 'anc') self.tgt = QuantumRegister(self.n_child, 'tgt') if evd != None: self.oracle = QuantumRegister(evd, 'oracle') self.circ = QuantumCircuit(self.ctrl, self.anc, self.tgt, self.oracle) else: self.circ = QuantumCircuit(self.ctrl, self.anc, self.tgt) #self.c_ctrl = ClassicalRegister(self.n, 'c_ctrl') #self.c_tgt = ClassicalRegister(self.n_child, 'c_tgt') self.parent_init() self.child_init() def parent_init(self): for i in range(self.n): theta = self.calc_theta(self.parents[2 * i], self.parents[2 * i + 1]) self.circ.ry(theta, i) self.circ.barrier() def child_init(self): self.a = np.arange(0, 2**self.n) self.gates = [] for i in self.a: s = str(np.binary_repr(i, width=self.n)) self.gates.append(s) for i in range(2**self.n): self.xgate(self.gates[i]) for j in range(self.n_child): theta = self.calc_theta(self.child[2 * i + 1, j], self.child[2 * i, j]) self.cn_ry(theta, j) self.xgate(self.gates[i]) self.circ.barrier() def xgate(self, gate): for index, item in enumerate(gate): if int(item) == 0: self.circ.x(index) #RY gates def cn_ry(self, theta, target): # compute self.circ.ccx(self.ctrl[0], self.ctrl[1], self.anc[0]) for i in range(2, self.n): self.circ.ccx(self.ctrl[i], self.anc[i - 2], self.anc[i - 1]) # copy self.circ.cry(theta, self.anc[self.n - 2], self.tgt[target]) # uncompute for i in range(self.n - 1, 1, -1): self.circ.ccx(self.ctrl[i], self.anc[i - 2], self.anc[i - 1]) self.circ.ccx(self.ctrl[0], self.ctrl[1], self.anc[0]) def calc_theta(self, p1, p0): return 2 * np.arctan(np.sqrt((p1) / (p0))) def plot(self): self.circ.draw(output='mpl') plt.show() def execute_circ(self): self.circ.measure_all() results = execute(self.circ, self.backend, shots=4321) return results def rejection_sampling(self, evidence, shots=1000, amplitude_amplification=False): # Run job many times to get multiple samples samples_list = [] self.n_samples = shots if amplitude_amplification == True: self.amplitude_amplification(evidence) self.circ.measure_all() #self.circ.measure((self.ctrl, self.tgt),(self.c_ctrl, self.c_tgt)) for i in range(self.n_samples): job = execute(self.circ, backend=self.backend, shots=1) result = list(job.result().get_counts(self.circ).keys())[0] accept = True for e in evidence: if result[evidence[e]['n']] == evidence[e]['state']: pass else: accept = False if accept == True: #print('Accepted result ', result) samples_list.append(result) print() print(self.n_samples, 'samples drawn:', len(samples_list), 'samples accepted,', self.n_samples - len(samples_list), 'samples rejected.') print('Percentage of samples rejected: ', 100 * (1 - (len(samples_list) / self.n_samples)), '%') return samples_list def evaluate(self, samples_list, observations): p_o = 0 for sample in samples_list: accept = True for o in observations: if sample[observations[o]['n']] == observations[o]['state']: pass else: accept = False if accept == True: #print('Observation true given evidence') p_o += 1 p_o /= len(samples_list) print('Probabilty of observations given evidence = ', p_o) return p_o def amplitude_amplification(self, evidence): self.state_preparation = self.circ self.oracle = QuantumCircuit(self.ctrl, self.anc, self.tgt) for index, e in enumerate(evidence): if evidence[e]['state'] == '1': self.oracle.z([evidence[e]['n']]) self.grover_op = Grover(self.oracle, state_preparation=self.state_preparation) self.grover_op.draw() def oracle(self): pass def u_gate(self): pass
class byskit(): def __init__(self, backend, network, loaded_net, evd=None): self.backend = backend self.network = network self.net_keys = [key for key in self.network] self.loaded_net = loaded_net self.reg = {} self.create_circ() self.root_init() child_index = np.array([0, 0]) parent_index = np.array([0, 0]) for index in range(len(self.net_keys) - 1): parent_key = self.net_keys[index] child_key = self.net_keys[index + 1] if parent_key != 'root': parent_index = np.array([ parent_index[1], parent_index[1] + self.network[self.net_keys[index + 1]] ]) child_index = np.array([ child_index[1], child_index[1] + self.network[self.net_keys[index + 1]] ]) self.child_init(parent_key, parent_index, child_key, child_index) def create_circ(self): self.n_anc = 0 self.n_tgt = 0 for key in self.network: if key == 'root': n = self.network['root'] self.reg['cntrl'] = QuantumRegister(self.network['root'], 'cntrl') else: self.n_anc = max(n - 1, self.n_anc) self.n_tgt += self.network[key] n = self.network[key] self.reg['anc'] = QuantumRegister(self.n_anc, 'anc') self.reg['tgt'] = QuantumRegister(self.n_tgt, 'tgt') self.circ = QuantumCircuit(self.reg['cntrl'], self.reg['anc'], self.reg['tgt']) def root_init(self): for i in range(self.network['root']): theta = self.calc_theta(self.loaded_net['root'][2 * i], self.loaded_net['root'][2 * i + 1]) self.circ.ry(theta, i) self.circ.barrier() def child_init(self, parent_key, parent_index, child_key, child_index): parent_index = parent_index[0] child_index = child_index[0] self.a = np.arange(0, 2**self.network[parent_key]) self.gates = [] for i in self.a: s = str(np.binary_repr(i, width=self.network[parent_key])) self.gates.append(s) for i in range(2**self.network[parent_key]): self.xgate(self.gates[i], parent_index) for j in range(self.network[child_key]): theta = self.calc_theta( self.loaded_net[child_key][2 * i + 1, j], self.loaded_net[child_key][2 * i, j]) self.cn_ry(theta, j, parent_key, parent_index, child_key, child_index) self.xgate(self.gates[i], parent_index) self.circ.barrier() def xgate(self, gate, parent_index): for index, item in enumerate(gate): if int(item) == 0: self.circ.x(index + parent_index) #RY gates def cn_ry(self, theta, target, parent_key, parent_index, child_key, child_index): # compute if parent_key == 'root': self.circ.ccx(self.reg['cntrl'][0], self.reg['cntrl'][1], self.reg['anc'][0]) for i in range(2, self.network[parent_key]): self.circ.ccx(self.reg['cntrl'][i], self.reg['anc'][i - 2], self.reg['anc'][i - 1]) # copy self.circ.cry(theta, self.reg['anc'][self.network[parent_key] - 2], self.reg['tgt'][target]) # uncompute for i in range(self.network[parent_key] - 1, 1, -1): self.circ.ccx(self.reg['cntrl'][i], self.reg['anc'][i - 2], self.reg['anc'][i - 1]) self.circ.ccx(self.reg['cntrl'][0], self.reg['cntrl'][1], self.reg['anc'][0]) else: self.circ.ccx(self.reg['tgt'][parent_index + 0], self.reg['tgt'][parent_index + 1], self.reg['anc'][0]) for i in range(2, self.network[parent_key]): self.circ.ccx(self.reg['tgt'][parent_index + i], self.reg['anc'][i - 2], self.reg['anc'][i - 1]) # copy self.circ.cry(theta, self.reg['anc'][self.network[parent_key] - 2], self.reg['tgt'][child_index + target]) # uncompute for i in range(self.network[parent_key] - 1, 1, -1): self.circ.ccx(self.reg['tgt'][parent_index + i], self.reg['anc'][i - 2], self.reg['anc'][i - 1]) self.circ.ccx(self.reg['tgt'][parent_index + 0], self.reg['tgt'][parent_index + 1], self.reg['anc'][0]) def calc_theta(self, p1, p0): return 2 * np.arctan(np.sqrt((p1) / (p0))) def plot(self): self.circ.draw(output='mpl') plt.show() def execute_circ(self): self.circ.measure_all() results = execute(self.circ, self.backend, shots=4321) return results def rejection_sampling(self, evidence, shots=5000, amplitude_amplification=False): # Run job many times to get multiple samples samples_list = [] self.n_samples = shots if amplitude_amplification == True: self.amplitude_amplification(evidence) self.circ.measure_all() for i in range(self.n_samples): job = execute(self.circ, backend=self.backend, shots=1) result = list(job.result().get_counts(self.circ).keys())[0] accept = True for e in evidence: if result[evidence[e]['n']] == evidence[e]['state']: pass else: accept = False if accept == True: #print('Accepted result ', result) samples_list.append(result) print() print(self.n_samples, 'samples drawn:', len(samples_list), 'samples accepted,', self.n_samples - len(samples_list), 'samples rejected.') print('Percentage of samples rejected: ', 100 * (1 - (len(samples_list) / self.n_samples)), '%') return samples_list def evaluate(self, samples_list, observations): p_o = 0 for sample in samples_list: accept = True for o in observations: if sample[observations[o]['n']] == observations[o]['state']: pass else: accept = False if accept == True: #print('Observation true given evidence') p_o += 1 p_o /= len(samples_list) print('Probabilty of observations given evidence = ', p_o) return p_o def amplitude_amplification(self, evidence): self.state_preparation = self.circ self.oracle = QuantumCircuit(self.ctrl, self.anc, self.tgt) for index, e in enumerate(evidence): if evidence[e]['state'] == '1': self.oracle.z([evidence[e]['n']]) self.grover_op = Grover(self.oracle, state_preparation=self.state_preparation) self.grover_op.draw() def oracle(self): pass def u_gate(self): pass