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])
Beispiel #2
0
    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)
Beispiel #3
0
 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)
Beispiel #4
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)
Beispiel #5
0
 def test_trivial(self):
     q, offset = ising_to_qubo({}, {})
     self.assertEqual(q, {})
     self.assertEqual(offset, 0)