def anneal(C_i, C_ij, mu, sigma, l, strength_scale, energy_fraction, ngauges, max_excited_states): #Initialising h and J as dictionnaries h = {} J = {} for i in range(len(C_i)): h_i = -2 * sigma[i] * C_i[i] for j in range(len(C_ij[0])): if j > i: J[(i, j)] = float(2 * C_ij[i][j] * sigma[i] * sigma[j]) h_i += 2 * (sigma[i] * C_ij[i][j] * mu[j]) h[i] = h_i #applying cutoff print("Number of J before : " + str(len(J))) #J before cutoff float_vals = [] for i in J.values(): float_vals.append(i) cutoff = np.percentile(float_vals, AUGMENT_CUTOFF_PERCENTILE) to_delete = [] for k, v in J.items(): if v < cutoff: to_delete.append(k) for k in to_delete: del J[k] print("Number of J after : " + str(len(J))) # J after cutof new_Q = {} isingpartial = {} if FIXING_VARIABLES: #Optimising heuristically the number of coupling terms Q, _ = dimod.ising_to_qubo(h, J, offset=0.0) bqm = dimod.BinaryQuadraticModel.from_qubo(Q, offset=0.0) simple = dimod.fix_variables(bqm, sampling_mode=False) if simple == {}: new_Q = Q else: Q_indices = [] for i in Q: if i in simple.keys(): continue else: Q_indices.append(i) new_Q = {key: Q[key] for key in Q_indices} print('new length', len(new_Q)) isingpartial = simple if (not FIXING_VARIABLES) or len(new_Q) > 0: mapping = [] offset = 0 for i in range(len(C_i)): if i in isingpartial: mapping.append(None) offset += 1 else: mapping.append(i - offset) if FIXING_VARIABLES: new_Q_mapped = {} for (first, second), val in new_Q.items(): new_Q_mapped[(mapping[first], mapping[second])] = val h, J, _ = dimod.qubo_to_ising(new_Q_mapped) #Run gauges qaresults = [] print("Number of variables to anneal :" + str(len(h))) for g in range(ngauges): #Finding embedding qaresult = [] embedded = False for attempt in range(5): a = np.sign(np.random.rand(len(h)) - 0.5) float_h = [] for i in h.values(): float_h.append(i) h_gauge = float_h * a J_gauge = {} for i in range(len(h)): for j in range(len(h)): if (i, j) in J: J_gauge[(i, j)] = J[(i, j)] * a[i] * a[j] try: print("Trying to find embeding") sampler = EmbeddingComposite( DWaveSampler(token='secret_token')) embedded = True break except ValueError: # no embedding found print('no embedding found') embedded = False continue if not embedded: continue print("emebeding found") print("Quantum annealing") try_again = True while try_again: try: #Annealing, saving energy and sample list sampleset = sampler.sample_ising( h_gauge, J_gauge, chain_strength=strength_scale, num_reads=200, annealing_time=20) try_again = False except: print('runtime or ioerror, trying again') time.sleep(10) try_again = True print("Quantum done") qaresult.append(sampleset.record[0][0].tolist()) qaresult = np.asarray(qaresult) qaresult = qaresult * a qaresults[g * nreads:(g + 1) * nreads] = qaresult full_strings = np.zeros((len(qaresults), len(C_i))) full_strings = np.asarray(full_strings) qaresults = np.asarray(qaresults) if FIXING_VARIABLES: j = 0 for i in range(len(C_i)): if i in isingpartial: full_strings[:, i] = 2 * isingpartial[i] - 1 else: full_strings[:, i] = qaresults[:, j] j += 1 else: full_strings = qaresults s = np.asarray(full_strings) energies = np.zeros(len(qaresults)) s[np.where(s > 1)] = 1.0 s[np.where(s < -1)] = -1.0 bits = len(s[0]) for i in range(bits): energies += 2 * s[:, i] * (-sigma[i] * C_i[i]) for j in range(bits): if j > i: energies += 2 * s[:, i] * s[:, j] * sigma[i] * sigma[ j] * C_ij[i][j] energies += 2 * s[:, i] * sigma[i] * C_ij[i][j] * mu[j] unique_energies, unique_indices = np.unique(energies, return_index=True) ground_energy = np.amin(unique_energies) if ground_energy < 0: threshold_energy = (1 - energy_fraction) * ground_energy else: threshold_energy = (1 + energy_fraction) * ground_energy lowest = np.where(unique_energies < threshold_energy) unique_indices = unique_indices[lowest] if len(unique_indices) > max_excited_states: sorted_indices = np.argsort( energies[unique_indices])[-max_excited_states:] unique_indices = unique_indices[sorted_indices] print("unique indices : ", unique_indices) print(type(unique_indices[0])) print(type(full_strings)) final_answers = full_strings[unique_indices] print('number of selected excited states', len(final_answers)) return final_answers else: final_answer = [] print("Evrything resolved by FIXING_VARIABLES") for i in range(len(C_i)): if i in isingpartial: final_answer.append(2 * isingpartial[i] - 1) final_answer = np.array(final_answer) return np.array([final_answer])
def test_typical(self): h = {i: v for i, v in enumerate([-5, -4, -3, -2, -1, 0, 1, 2, 3, 4])} j = { (0, 5): 2, (0, 8): 4, (1, 4): -5, (1, 7): 1, (2, 0): 5, (2, 1): 4, (3, 0): -1, (3, 6): -3, (3, 8): 3, (4, 0): 2, (4, 7): 3, (4, 9): 3, (5, 1): 3, (6, 5): -4, (6, 7): -4, (7, 1): -4, (7, 8): 3, (8, 2): -4, (8, 3): -3, (8, 6): -5, (8, 7): -4, (9, 0): 4, (9, 1): -1, (9, 4): -5, (9, 7): 3 } q, offset = ising_to_qubo(h, j) # norm_q = normalized_matrix(q) ans = { (0, 0): -42, (0, 2): 20, (0, 3): -4, (0, 4): 8, (0, 5): 8, (0, 8): 16, (0, 9): 16, (1, 1): -4, (1, 2): 16, (1, 4): -20, (1, 5): 12, (1, 7): -12, (1, 9): -4, (2, 2): -16, (2, 8): -16, (3, 3): 4, (3, 6): -12, (4, 4): 2, (4, 7): 12, (4, 9): -8, (5, 5): -2, (5, 6): -16, (6, 6): 34, (6, 7): -16, (6, 8): -20, (7, 7): 8, (7, 8): -4, (7, 9): 12, (8, 8): 18 } for (u, v), bias in normalized_matrix(q).items(): self.assertIn((u, v), ans) self.assertEqual(bias, ans[(u, v)]) self.assertEqual(offset, 2)
def test_no_zeros(self): q, offset = ising_to_qubo({0: 0, 0: 0, 0: 0}, {(0, 0): 0, (4, 5): 0}) self.assertEqual(q, {(0, 0): 0.0}) self.assertEqual(offset, 0)
def test_j_diag(self): q, offset = ising_to_qubo({}, {(0, 0): 1, (300, 300): 99}) self.assertEqual(q, {(0, 0): 0.0, (300, 300): 0.0}) self.assertEqual(offset, 100)
def test_trivial(self): q, offset = ising_to_qubo({}, {}) self.assertEqual(q, {}) self.assertEqual(offset, 0)