Source code for qlauncher.problems.problem_formulations.bqm
1import ast
2import numpy as np
3from pyqubo import Spin
4from qlauncher.base import adapter, formatter
5from qlauncher.problems.problem_initialization import Raw
6
7
[docs]
8@adapter('qubo', 'bqm')
9def qubo_to_bqm(qubo_with_offset) -> dict:
10 qubo, offset = qubo_with_offset
11 bqm, _ = QUBOMatrix(qubo, offset).qubo_matrix_into_bqm()
12 return bqm
13
14
[docs]
15class QUBOMatrix:
16 def __init__(self, qubo_matrix, offset):
17 self.qubo_matrix = qubo_matrix
18 self.offset = offset
19
20 if type(self.qubo_matrix) == str:
21 self.qubo_matrix = np.array(ast.literal_eval(self.qubo_matrix))
22
23 self.symetric = True
24 self._check_if_symetric()
25
26 def _check_if_symetric(self):
27 """
28 Function to check if matrix is symetric
29 """
30 self.symetric = (self.qubo_matrix.transpose()
31 == self.qubo_matrix).all()
32 if not self.symetric:
33 self.qubo_matrix = self._remove_lower_triangle(self.qubo_matrix)
34
35 def _remove_lower_triangle(self, matrix):
36 """
37 Function to remove lower triangle from matrix
38 """
39 for i in range(len(matrix)):
40 for j in range(len(matrix)):
41 if i > j:
42 matrix[i][j] = 0
43 return matrix
44
45 def _get_values_and_qubits(self, matrix):
46 """
47 Function to get values and qubits from matrix in form of dictionary
48 where keys are indexes of qubits and values are values of matrix
49 The function does not take into account zeros in matrix
50 Example:
51 matrix = [[0,1,2],[1,0,3],[2,3,0]]
52 result = {(0,1):1, (0,2):2, (1,0):1, (1,2):3, (2,0):2, (2,1):3}
53 Function also return second value which is the number of qubits
54 """
55 result = {
56 (x, y): c for y, r in enumerate(matrix) for x, c in enumerate(r) if c != 0
57 }
58 return result, len(matrix)
59
[docs]
60 def qubo_matrix_into_bqm(self):
61 values_and_qubits, number_of_qubits = self._get_values_and_qubits(
62 self.qubo_matrix
63 )
64 qubits = [Spin(f"x{i}") for i in range(number_of_qubits)]
65 H = 0
66 for (x, y), value in values_and_qubits.items():
67 if self.symetric:
68 H += value / len(set((x, y))) * qubits[x] * qubits[y]
69 else:
70 H += value * qubits[x] * qubits[y]
71 model = H.compile()
72 bqm = model.to_bqm()
73 bqm.offset += self.offset
74 return bqm, model
75
76
[docs]
77@formatter(Raw, 'bqm')
78def Rawbqm(problem: Raw):
79 return problem.instance