def test_failover_offline(self, MockClient): if sys.version_info.major <= 2 or sys.version_info.minor < 6: raise unittest.SkipTest( "need mock features only available in 3.6+") sampler = DWaveSampler(failover=True) mocksolver = sampler.solver edgelist = sampler.edgelist # call once ss = sampler.sample_ising({}, {}) self.assertIs(mocksolver, sampler.solver) # still same solver # one of the sample methods was called self.assertEqual( sampler.solver.sample_ising.call_count + sampler.solver.sample_qubo.call_count, 1) # add a side-effect sampler.solver.sample_ising.side_effect = SolverOfflineError sampler.solver.sample_qubo.side_effect = SolverOfflineError # and make sure get_solver makes a new mock solver sampler.client.get_solver.reset_mock(return_value=True) ss = sampler.sample_ising({}, {}) self.assertIsNot(mocksolver, sampler.solver) # new solver self.assertIsNot(edgelist, sampler.edgelist) # also should be new
def test_failover_false(self, MockClient): sampler = DWaveSampler(failover=False) sampler.solver.sample_ising.side_effect = SolverOfflineError sampler.solver.sample_qubo.side_effect = SolverOfflineError with self.assertRaises(SolverOfflineError): sampler.sample_ising({}, {})
def test_failover_notfound_noretry(self, MockClient): sampler = DWaveSampler(failover=True, retry_interval=-1) mocksolver = sampler.solver # add a side-effect sampler.solver.sample_ising.side_effect = SolverOfflineError sampler.solver.sample_qubo.side_effect = SolverOfflineError # and make sure get_solver makes a new mock solver sampler.client.get_solver.side_effect = SolverNotFoundError with self.assertRaises(SolverNotFoundError): sampler.sample_ising({}, {})
def solve_ising_dwave(hii, Jij): config_file = '/media/sf_QWorld/QWorld/QA_DeNovoAsb/dwcloud.conf' client = Client.from_config(config_file, profile='aritra') solver = client.get_solver( ) # Available QPUs: DW_2000Q_2_1 (2038 qubits), DW_2000Q_5 (2030 qubits) dwsampler = DWaveSampler(config_file=config_file) edgelist = solver.edges adjdict = edgelist_to_adjacency(edgelist) embed = minorminer.find_embedding(Jij.keys(), edgelist) [h_qpu, j_qpu] = embed_ising(hii, Jij, embed, adjdict) response_qpt = dwsampler.sample_ising(h_qpu, j_qpu, num_reads=solver.max_num_reads()) client.close() bqm = dimod.BinaryQuadraticModel.from_ising(hii, Jij) unembedded = unembed_sampleset(response_qpt, embed, bqm, chain_break_method=majority_vote) print("Maximum Sampled Configurations from D-Wave\t===>") solnsMaxSample = sorted(unembedded.record, key=lambda x: -x[2]) for i in range(0, 10): print(solnsMaxSample[i]) print("Minimum Energy Configurations from D-Wave\t===>") solnsMinEnergy = sorted(unembedded.record, key=lambda x: +x[1]) for i in range(0, 10): print(solnsMinEnergy[i])
if (qubit_1 in qubits) and (qubit_2 in qubits) and ( coupler in couplers): # let's ensure both are available in our system print('Qubits {} and {} and their coupler {} are available'.format( qubit_1, qubit_2, coupler)) # Define a problem: Force the qubits to be spin-up by setting h_0 = h_4 = -1 and have a FM coupling between them. We expect to get samples with spin up (1) qubits and an energy of -1 + -1 + -1 = -3. # H = h_1 * s_1 + h_2 * s_2 + J_{1,2} * s_1 * s_2 # h1 and h2 are biases on individual qubits and J_{1,2} is the coupling term h = {qubit_1: -1, qubit_2: -1} # force the qubits to be spin-up J = { tuple(coupler): -1 } # we expect to get samples with spin up (1) qubits and an energy of -1 + -1 + -1 = -3 solution = solver.sample_ising( h, J, num_reads=10) # ask for a solution with 10 samples (reads): print('Solution:', solution) print('\nsamples in dict format\n' + str(list(solution.samples()))) # print('\nsamples in matrix format\n' + str(list(solution.samples_matrix))) # AttributeError: 'SampleSet' object has no attribute 'samples_matrix' print('\nenergies of samples\n' + str(list(solution.data_vectors))) print('\ntiming information\n' + str(list(solution.info))) # Response = rec.array([([1, 1], -3., 10)]
if not embedding: raise ValueError("no embedding found") #Create a complete Ising model on a QPU target_h, target_J = embed_ising(h, J, embedding, target_adjacency) # print('__________________') # print('Linear coeff on QPU:', target_h) # print('Quadratic coeff on QPU:', target_J) # print('__________________') # Set parameters for calculations. num_reas is a number of experiments runs = 4 response = sampler.sample_ising(target_h, target_J, num_reads=runs, answer_mode='histogram', annealing_time = 1000) #Get a SampleSet with spins and energies (WARNING: results are for the task, embedded on QPU) # print('Resulting spins on QPU:') # print(response) # print('__________________') #Return to the original spins: unembedding = unembed_sampleset(response, embedding, dimod.BinaryQuadraticModel.from_ising({}, J)) # print('Resulting spins in terms of original task:') # print(unembedding) # print('__________________') # plt.hist(unembedding.record.energy,rwidth=1,align='left') # plt.show() print(unembedding)
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # https://docs.ocean.dwavesys.com/en/latest/overview/dwavesys.html#querying-available-solvers from dwave.system.samplers import DWaveSampler sampler = DWaveSampler() print('\nsampler.parameters', sampler.parameters, sep='\n') print('\nsampler.properties.keys()', sampler.properties.keys(), sep='\n') print('\nresp1', sampler.sample_ising({0: 0.0}, {}, num_reads=1), sep='\n') print('\nresp2', sampler.sample_ising({0: 2.0}, {}), sep='\n')
from dwave.system.samplers import DWaveSampler #sampler = DWaveSampler(solver={'qpu': True}) solver = DWaveSampler() print("Connected to sampler", solver.solver.id) qubits = solver.properties['qubits'] couplers = solver.properties['couplers'] qubit_1 = 0 qubit_2 = 4 coupler = [qubit_1, qubit_2] if (qubit_1 in qubits) and \ (qubit_2 in qubits) and \ (coupler in couplers): print('Qubits {} and {} and their coupler {} are available'.format( qubit_1, qubit_2, coupler)) h = {qubit_1: -1, qubit_2: -1} J = {tuple(coupler): -1} solution = solver.sample_ising(h, J, num_reads=10) solution
# To see exactly how often each chain is breaking in a standard run on the QPU, we will first run our Ising problem on the QPU using the basic `embed_ising` method. # We will use the optional parameter `chain_strength` within `embed_ising`, and will set this value to $2.0$ for our comparison. # To use this tool, we provide the graph minor embedding discovered above to create and embedded version. # Then send this embedded ising problem over to the QPU using `sample_ising`. from dwave.embedding import embed_ising embedded_h, embedded_J = embed_ising(h, J, embedding, dwave_sampler.adjacency, chain_strength=2.0) reads = 1000 fixed_response = dwave_sampler.sample_ising(embedded_h, embedded_J, num_reads=reads) energies = fixed_response.record.energy print("QPU call complete using", fixed_response.info['timing']['qpu_access_time'] / 1000000.0, "seconds of QPU time.\n") # Next we will look at the frequency that chains broke in our samples. # This will be our metric to explore the advantages of `VirtualGraphComposite`. from dwave.embedding import chain_break_frequency chain_break_frequency = chain_break_frequency(fixed_response, embedding) for key, val in chain_break_frequency.items(): print("Chain", key, "broke in", val * 100, "percent of samples.") # Let's visualize these results by plotting each chain against the percentage of samples in which it broke.
def find_loop(unit_size=8, i0=0, j0=0, use_qpu=True): ''' dwaveの各セルを頂点として、頂点をつなげるループを 見つけようとするモデルを実行する。 結果は、エネルギー最小値にならないため 期待した結果にはならない。 今後のマシンの精度向上に期待。 または、どうにかして頑健なグラフ構造にすべきか。 ※注意:マシンは個体ごとにところどころ壊れているので、使用するセルを以下の引数で指定する。 Args: unit_size: セルの正方形の辺の長さ i0: セルの縦方向のオフセット j0: セルの横方向のオフセット use_qpu: qpuを使うか指定する ''' qpu_unit_size = 16 C16 = dnx.chimera_graph(qpu_unit_size) h, J = V(unit_size=unit_size, i0=i0, j0=j0) #print(h) #print(J) if use_qpu: sampler = DWaveSampler() samples = sampler.sample_ising(h, J, num_reads=10, annealing_time=20) if 0: count = 0 for s,e,o in samples.data(['sample', 'energy', 'num_occurrences']): print(e, o) print_chimera_simple(s) samples = sampler.sample_ising(h, J, num_reads=100, anneal_schedule = [[0.0,1.0],[20.0,0.0],[30.0,0.3],[35.0,0.3],[40.0,1.0]], reinitialize_state=False, initial_state=s) count += 1 if count >= 1 : break else: classical_sampler = neal.SimulatedAnnealingSampler() sampler = dimod.StructureComposite(classical_sampler, C16.nodes, C16.edges) samples = sampler.sample_ising(h, J, num_reads=10) count = 0 for s,e,o in samples.data(['sample', 'energy', 'num_occurrences']): print(e, o) print_chimera_simple(s) count += 1 if count >= 10 : break
class DictRep(ProbRep): """ A concrete class that represents problems on the D-Wave as a dictionary of values. """ def __init__(self, H, qpu, vartype, encoding): """ Class that takes a dictionary representation of an ising-hamiltonian and submits problem to a quantum annealer qpu: string specifies quantum processing unit to be used during calculation--referring to name specifying this information in dwave config file vartype: string QUBO or Ising (all case variants acceptable) encoding: string logical or direct. If logical, embeds onto chip under the hood. If direct, assumes manual embedding and tries to put directly onto chip as is. H: dict The hamiltonian represented as a dict of the form {(0, 0): h0, (0, 1): J01, ...} OR {(0, 0): 'h0', (0, 1): 'J0', (1, 1): 'h1', ...} """ # poplate run information super().__init__(qpu, vartype, encoding) # create a set of regex rules to parse h/J string keys in H # also creates a "rules" dictionary to relate qubit weights to relevant factor self.hvrule = re.compile('h[0-9]*') self.Jvrule = re.compile('J[0-9]*') self.weight_rules = {} # create list of qubits/ couplers and # dicts that map indepndent params to # all qubits/ couplers that have that value self.H = H self.qubits = [] self.params_to_qubits = {} self.couplers = [] self.params_to_couplers = {} for key, value in H.items(): if key[0] == key[1]: self.qubits.append(key[0]) if type(value) != str: div_idx = -1 else: div_idx = value.find('/') if div_idx == -1: self.weight_rules[key[0]] = 1 else: self.weight_rules[key[0]] = float(value[div_idx + 1:]) value = value[:div_idx] self.params_to_qubits.setdefault(value, []).append(key[0]) else: self.couplers.append(key) if type(value) != str: div_idx = -1 else: div_idx = value.find('/') if div_idx == -1: self.weight_rules[key] = 1 else: self.weight_rules[key] = float(value[div_idx + 1:]) value = value[:div_idx] self.params_to_couplers.setdefault(value, []).append(key) self.nqubits = len(self.qubits) self.Hsize = 2**(self.nqubits) if qpu == 'dwave': try: # let OCEAN handle embedding if encoding == "logical": # encode several times on graph # based on qubits encoded if len(self.qubits) <= 4: self.sampler = EmbeddingComposite( TilingComposite(DWaveSampler(), 1, 1, 4)) else: self.sampler = EmbeddingComposite(DWaveSampler()) # otherwise, assume 1-1 else: self.sampler = DWaveSampler() except: raise ConnectionError( "Cannot connect to DWave sampler. Have you created a DWave config file using 'dwave config create'?" ) elif qpu == 'test': self.sampler = dimod.SimulatedAnnealingSampler() elif qpu == 'numerical': self.processordata = loadAandB() self.graph = nx.Graph() self.graph.add_edges_from(self.couplers) self.data = pd.DataFrame() # save values/ metadata self.H = copy.deepcopy(H) if encoding == 'direct': self.wqubits = self.sampler.properties['qubits'] self.wcouplers = self.sampler.properties['couplers'] def save_config(self, fname, config_data={}): """ Saves Hamiltonian configuration for future use """ # if config data not supplied, at least dump Hamiltonian if config_data == {}: config_data = {'H': self.H} with open(fname + ".yml", 'w') as yamloutput: yaml.dump(config_data, yamloutput) def tile_H(self): pqubits = self.qubits pcouplers = self.couplers wqubits = self.wqubits wcouplers = self.wcouplers H = copy.deepcopy(self.H) for unitcell in range(1, 16 * 16): # create list of qubits/couplers that should be working in this unit cell unit_qubits = [q for q in range(8 * unitcell, 8 * (unitcell + 1))] unit_couplers = [[q, q + (4 - q % 4) + i] for q in unit_qubits[:4] for i in range(4)] # ensure that all qubits and couplers are working if all(q in wqubits for q in unit_qubits) and all(c in wcouplers for c in unit_couplers): # init_state.extend(init_state[:]) # copy the initial state # if so, create copies of H on other unit cells for q in unit_qubits: if (q % 8) in pqubits: H[(q, q)] = H[(q % 8, q % 8)] for c in unit_couplers: if (c[0] % 8, c[1] % 8) in pcouplers: H[tuple(c)] = H[(c[0] % 8, c[1] % 8)] # else: #init_state.extend([3 for q in range(len(unit_qubits))]) #self.init_state = init_state self.H = H self.qubits = [] self.params_to_qubits = {} self.couplers = [] self.params_to_couplers = {} for key, value in H.items(): if key[0] == key[1]: self.qubits.append(key[0]) self.params_to_qubits.setdefault(value, []).append(key[0]) else: self.couplers.append(key) self.params_to_couplers.setdefault(value, []).append(key) def populate_parameters(self, parameters): # generate all independent combinations of parameters self.params = [] self.values = [] for key, value in parameters.items(): self.params.append(key) self.values.append(value) self.combos = list(itertools.product(*self.values)) # format pandas DataFrame # columns = self.params[:] # columns.extend(['energy', 'state']) self.data = pd.DataFrame() self.data.H = str(self.H) self.data.vartype = self.vartype self.data.encoding = self.encoding return def call_annealer(self, **kwargs): """ Calls qpu on problem encoded by H. cull: bool if true, only outputs lowest energy states, otherwise shows all results """ # parse the input data # cull = kwargs.get('cull', False) # only takes lowest energy data s_to_hx = kwargs.get('s_to_hx', '') # relates s to transverse-field bias spoint = kwargs.get( 'spoint', 0) # can start sampling data midway through if interuptted # if H.values() only contains floats, # run sinlge problem as is if all( type(value) == int or type(value) == float for value in self.H.values()): if self.vartype == 'ising': h, J = get_dwaveH(self.H, 'ising') response = self.sampler.sample_ising(h, J) return response elif self.vartype == 'qubo': H = get_dwaveH(self.H, 'vartype') response = self.sampler.sample_ising(H) return response # otherwise, run a parameter sweep for combo in self.combos[spoint::]: # init single run's data/inputs rundata = {} runh = {} runJ = {} optional_args = {} count = 0 # map params to values in combo for param in self.params: rundata[param] = combo[count] # if param is qubit param if self.hvrule.match(param): for qubit in self.params_to_qubits[param]: runh[qubit] = combo[count] / self.weight_rules[qubit] elif self.Jvrule.match(param): for coupler in self.params_to_couplers[param]: runJ[coupler] = combo[count] / self.weight_rules[ coupler] elif param == 'anneal_schedule': anneal_schedule = combo[count] optional_args['anneal_schedule'] = anneal_schedule # if transverse field terms, get hx if s_to_hx: hx = s_to_hx[anneal_schedule[1][1]] rundata['hx'] = hx elif param == 'num_reads': num_reads = combo[count] optional_args['num_reads'] = num_reads elif param == 'initial_state': initial_state = combo[count] optional_args['initial_state'] = initial_state elif param == 'reinitialize_state': reinitialize_state = combo[count] optional_args['reinitialize_state'] = reinitialize_state count += 1 # run the sim and collect data if self.qpu == 'dwave': response = self.sampler.sample_ising(h=runh, J=runJ, **optional_args) for energy, state, num in response.data( fields=['energy', 'sample', 'num_occurrences']): rundata['energy'] = energy rundata['state'] = tuple(state[key] for key in sorted(state.keys())) for n in range(num): self.data = self.data.append(rundata, ignore_index=True) elif self.qpu == 'test': bqm = dimod.BinaryQuadraticModel.from_ising(h=runh, J=runJ) response = self.sampler.sample(bqm, num_reads=num_reads) for energy, state in response.data( fields=['energy', 'sample']): rundata['energy'] = energy rundata['state'] = tuple(state[key] for key in sorted(state.keys())) self.data = self.data.append(rundata, ignore_index=True) elif self.qpu == 'numerical': continue return self.data def visualize_graph(self): G = nx.Graph() G.add_edges_from(self.couplers) nx.draw_networkx(G) return G def save_data(self, filename): self.data.to_csv(filename, index=False) def get_state_plot(self, figsize=(12, 8), filename=None, title='Distribution of Final States'): data = self.data ncount = len(data) plt.figure(figsize=figsize) ax = sns.countplot(x="state", data=data) plt.title(title) plt.xlabel('State') # Make twin axis ax2 = ax.twinx() # Switch so count axis is on right, frequency on left ax2.yaxis.tick_left() ax.yaxis.tick_right() # Also switch the labels over ax.yaxis.set_label_position('right') ax2.yaxis.set_label_position('left') ax2.set_ylabel('Frequency [%]') for p in ax.patches: x = p.get_bbox().get_points()[:, 0] y = p.get_bbox().get_points()[1, 1] ax.annotate('{:.1f}%'.format(100. * y / ncount), (x.mean(), y), ha='center', va='bottom') # set the alignment of the text # Use a LinearLocator to ensure the correct number of ticks ax.yaxis.set_major_locator(ticker.LinearLocator(11)) # Fix the frequency range to 0-100 ax2.set_ylim(0, 100) ax.set_ylim(0, ncount) # And use a MultipleLocator to ensure a tick spacing of 10 ax2.yaxis.set_major_locator(ticker.MultipleLocator(10)) # Need to turn the grid on ax2 off, otherwise the gridlines end up on top of the bars # ax2.grid(None) if filename: plt.savefig(filename, dpi=300) return plt def get_ferro_diagram(self, xparam, yparam, divideby=None, title=''): """ Plot the probability that output states are ferromagnetic on a contour plot with xaxis as xparam/divdeby and yaxis as yparam/divideby. """ df = self.data # obtain denominator of expression (if constant value is used across-the-board) if divideby: denom = abs(df[divideby].unique()[0]) xlabel = xparam + '/|' + divideby + '|' ylabel = yparam + '/|' + divideby + '|' else: denom = 1 xlabel = xparam ylabel = yparam xs = df[xparam].unique() ys = df[yparam].unique() pfm_meshgrid = [] # iterate over trials and obtain pFM for given xparam and yparam for y in ys: pfms = [] for x in xs: # get length of unique elements in state bitstrings lubs = [ len(set(state)) for state in df.loc[(df[yparam] == y) & (df[xparam] == x)]['state'] ] pfms.append(lubs.count(1) / len(lubs)) pfm_meshgrid.append(pfms) X, Y = np.meshgrid(xs / denom, ys / denom) # plot the figure plt.figure() plt.title(title) plt.contourf(X, Y, pfm_meshgrid, np.arange(0, 1.2, .2), cmap='viridis', extent=(-4, 4, 0, 4)) cbar = plt.colorbar(ticks=np.arange(0, 1.2, .2)) cbar.ax.set_title('$P_{FM}$') plt.clim(0, 1) plt.xlabel(xlabel) plt.ylabel(ylabel) return plt def diag_H(self): """ Returns probability of each state. """ numericH = get_numeric_H(self) HZ = numericH['HZ'] gs = gs_calculator(HZ) num_qubits = len(self.qubits) Hsize = 2**(num_qubits) probs = np.array([abs(gs[i].flatten()[0])**2 for i in range(Hsize)]) return probs def nf_anneal(self, schedule): """ Performs a numeric forward anneal on H using QuTip. inputs: --------- schedule - a numeric anneal schedule defined with anneal length outputs: --------- probs - probability of each output state as a list ordered in canconically w.r.t. tensor product """ times, svals = schedule # create a numeric representation of H ABfuncs = time_interpolation(schedule, self.processordata) numericH = get_numeric_H(self) A = ABfuncs['A(t)'] B = ABfuncs['B(t)'] HX = numericH['HX'] HZ = numericH['HZ'] # "Analytic" or function H(t) analH = lambda t: A(t) * HX + B(t) * HZ # Define list_H for QuTiP listH = [[HX, A], [HZ, B]] # perform a numerical forward anneal on H results = qt.sesolve(listH, gs_calculator(analH(0)), times) probs = np.array([ abs(results.states[-1][i].flatten()[0])**2 for i in range(self.Hsize) ]) return probs def nr_anneal(self, schedule, init_state): """ Performs a numeric reverse anneal on H using QuTip. inputs: --------- schedule - a numeric anneal schedule init_state - the starting state for the reverse anneal listed as string or list e.g. '111' or [010] outputs: --------- probs - probability of each output state as a list ordered in canconically w.r.t. tensor product """ times, svals = schedule # create a numeric representation of H ABfuncs = time_interpolation(schedule, self.processordata) numericH = get_numeric_H(self) A = ABfuncs['A(t)'] B = ABfuncs['B(t)'] HX = numericH['HX'] HZ = numericH['HZ'] # Define list_H for QuTiP listH = [[HX, A], [HZ, B]] # create a valid QuTip initial state qubit_states = [qts.ket([int(i)]) for i in init_state] QuTip_init_state = qt.tensor(*qubit_states) # perform a numerical reverse anneal on H results = qt.sesolve(listH, QuTip_init_state, times) probs = np.array([ abs(results.states[-1][i].flatten()[0])**2 for i in range(self.Hsize) ]) return probs def frem_anneal(self, schedules, partition, HR_init_state): """ Performs a numeric FREM anneal on H using QuTip. inputs: --------- schedules - a numeric annealing schedules [reverse, forward] partition - a parition of H in the form [HR, HF] init_state - the starting state for the reverse anneal listed as string or list e.g. '111' or [010] outputs: --------- probs - probability of each output state as a list ordered in canconically w.r.t. tensor product """ # retrieve useful quantities from input data f_sch, r_sch = schedules times = f_sch[0] HR = DictRep(H=partition['HR'], qpu='numerical', vartype='ising', encoding='logical') HF = DictRep(H=partition['HF'], qpu='numerical', vartype='ising', encoding='logical') Rqubits = partition['Rqubits'] # prepare the initial state statelist = [] fidx = 0 ridx = 0 for qubit in self.qubits: # if part of HR, give assigned value by user if qubit in Rqubits: statelist.append(qts.ket(HR_init_state[ridx])) ridx += 1 # otherwise, put in equal superposition (i.e. gs of x-basis) else: xstate = (qts.ket('0') - qts.ket('1')).unit() statelist.append(xstate) fidx += 1 init_state = qto.tensor(*statelist) # Create the numeric Hamiltonian for HR ABfuncs = time_interpolation(r_sch, self.processordata) numericH = get_numeric_H(HR) A = ABfuncs['A(t)'] B = ABfuncs['B(t)'] HX = numericH['HX'] HZ = numericH['HZ'] # Define list_H for QuTiP listHR = [[HX, A], [HZ, B]] # create the numeric Hamiltonian for HF ABfuncs = time_interpolation(f_sch, self.processordata) numericH = get_numeric_H(HF) A = ABfuncs['A(t)'] B = ABfuncs['B(t)'] HX = numericH['HX'] HZ = numericH['HZ'] # "Analytic" or function H(t) analHF = lambda t: A(t) * HX + B(t) * HZ # Define list_H for QuTiP listHF = [[HX, A], [HZ, B]] # create the total Hamitlontian of HF + HR list_totH = listHR + listHF # run the numerical simulation and find probabilities of each state frem_results = qt.sesolve(list_totH, init_state, times) probs = np.array([ abs(frem_results.states[-1][i].flatten()[0])**2 for i in range(self.Hsize) ]) return probs def frem_comparison(self, T, sval, ftr): """ Performs FREM algorithm and compares it to direct forward annealing. inputs: --------- T: total anneal time sval: svalue to go to in reverse annealing/ frem anneal ftr: the ratio of time spent in reverse and forward in frem outputs: --------- KL_div - the KL divergence of forward and FREM annealing w.r.t. diagonalization """ f_sch = make_numeric_schedule(.1, **{'direction': 'forward', 'ta': T}) r_sch = make_numeric_schedule( .1, **{ 'direction': 'reverse', 'ta': ftr * T, 'sa': sval, 'tq': (1 - ftr) * T }) # first, do direct diag on H # then extract non-zero entires ("gs" entries) dprobs = self.diag_H() nonzeroidxs = np.nonzero(dprobs) gs_dprobs = dprobs[nonzeroidxs] # perform forward anneal fprobs = self.nf_anneal(f_sch) gs_fprobs = fprobs[nonzeroidxs] # next, find a random partition of H into HR/HF partition = random_partition(self) # get qubits that belong to HR Rqubits = partition['Rqubits'] # find the most probable state of Rqubits from forward anneal init_state = ml_measurement(fprobs, self.nqubits) # perform reverse anneal using initial state guess rprobs = self.nr_anneal(r_sch, init_state) gs_rprobs = rprobs[nonzeroidxs] # find initial state of sub-system (i.e. Rqubits) sub_system_state = [] for (idx, qs) in enumerate(init_state): if idx in Rqubits: sub_system_state.append(qs) sub_init_state = ''.join([str(i) for i in sub_system_state]) # perform FREM anneal fremprobs = self.frem_anneal([f_sch, r_sch], partition, sub_init_state) gs_fremprobs = fremprobs[nonzeroidxs] # save data in a pandas dataframe fdata = { 'method': 'forward', 'T': T, 's': sval, 'ftr': ftr, 'part_size': self.nqubits, 'probs': fprobs, 'KL_div': entropy(dprobs, fprobs), 'gs_KL_div': entropy(gs_dprobs, gs_fprobs), 'gs_prob': sum(gs_fprobs) } rdata = { 'method': 'reverse', 'T': T, 's': sval, 'ftr': ftr, 'part_size': self.nqubits, 'probs': rprobs, 'KL_div': entropy(dprobs, rprobs), 'gs_KL_div': entropy(gs_dprobs, gs_rprobs), 'gs_prob': sum(gs_rprobs) } fremdata = { 'method': 'frem', 'T': T, 's': sval, 'ftr': ftr, 'part_size': len(Rqubits), 'probs': fremprobs, 'KL_div': entropy(dprobs, fremprobs), 'gs_KL_div': entropy(gs_dprobs, gs_fremprobs), 'gs_prob': sum(gs_fremprobs) } self.data = self.data.append(fdata, ignore_index=True) self.data = self.data.append(rdata, ignore_index=True) self.data = self.data.append(fremdata, ignore_index=True) return {'fdata': fdata, 'rdata': rdata, 'fremdata': fremdata} def sudden_anneal_test(self): pass def get_QUBO_rep(self): pass def get_Ising_rep(self): pass
raise ValueError("no embedding found") #Create a complete Ising model on a QPU target_h, target_J = embed_ising(h, J, embedding, target_adjacency) # print('__________________') # print('Linear coeff on QPU:', target_h) # print('Quadratic coeff on QPU:', target_J) # print('__________________') # Set parameters for calculations. num_reas is a number of experiments runs = 30 schedule = [[0.0, 0.0], [10.1, 0.1], [10.3, 0.3], [100.0, 1.0]] response = sampler.sample_ising(target_h, target_J, num_reads=runs, answer_mode='histogram', anneal_schedule=schedule) #Get a SampleSet with spins and energies (WARNING: results are for the task, embedded on QPU) # print('Resulting spins on QPU:') # print(response) # print('__________________') #Return to the original spins: unembedding = unembed_sampleset(response, embedding, dimod.BinaryQuadraticModel.from_ising({}, J)) # print('Resulting spins in terms of original task:') # print(unembedding) # print('__________________') # plt.hist(unembedding.record.energy,rwidth=1,align='left') # plt.show()