[docs]
1class Binary:
2 ''' It's not the same as Binary, it just replicate "spin" calculation "Binary" from pyqubo '''
3 def __init__(self, value:str):
4 if isinstance(value, str):
5 self.data = {value: 0.5}
6 self.data['__free__'] = 0.5
7 elif isinstance(value, int):
8 self.data = {'__free__': value}
9 elif isinstance(value, dict):
10 self.data = value
11 elif isinstance(value, Binary):
12 self.data = value.data.copy()
13 else:
14 raise TypeError(f'Unsupported type: {type(value)}')
15 self.variables:list = []
16
17 def __str__(self):
18 return str(self.data)
19
20 def __add__(self, other):
21 data = self.data.copy()
22 if isinstance(other, str):
23 if other in data:
24 data[other] += 1
25 else:
26 data[other] = 1
27 elif isinstance(other, int):
28 if '__free__' in data:
29 data['__free__'] += other
30 else:
31 data['__free__'] = other
32 elif isinstance(other, float):
33 if '__free__' in data:
34 data['__free__'] += other
35 else:
36 data['__free__'] = other
37 elif isinstance(other, dict):
38 for key, value in other.items():
39 if key in data:
40 data[key] += value
41 else:
42 data[key] = value
43 elif isinstance(other, Binary):
44 for key, value in other.data.items():
45 if key in data:
46 data[key] += value
47 else:
48 data[key] = value
49 else:
50 raise TypeError(f'Unsupported type: {type(other)}')
51 return Binary(data)
52
53 def __radd__(self, other):
54 data = self.data.copy()
55 if isinstance(other, str):
56 if other in data:
57 data[other] += 1
58 else:
59 data[other] = 1
60 elif isinstance(other, int):
61 if '__free__' in data:
62 data['__free__'] += other
63 else:
64 data['__free__'] = other
65 elif isinstance(other, float):
66 if '__free__' in data:
67 data['__free__'] += other
68 else:
69 data['__free__'] = other
70 elif isinstance(other, dict):
71 for key, value in other.items():
72 if key in data:
73 data[key] += value
74 else:
75 data[key] = value
76 elif isinstance(other, Binary):
77 for key, value in other.data.items():
78 if key in data:
79 data[key] += value
80 else:
81 data[key] = value
82 else:
83 raise TypeError(f'Unsupported type: {type(other)}')
84 return Binary(data)
85
86 def __sub__(self, other):
87 data = self.data.copy()
88 if isinstance(other, str):
89 if other in data:
90 data[other] -= 1
91 if data[other] == 0:
92 del data[other]
93 else:
94 data[other] = -1
95 elif isinstance(other, int):
96 if '__free__' in data:
97 data['__free__'] -= other
98 if data['__free__'] == 0:
99 del data['__free__']
100 else:
101 data['__free__'] = -other
102 elif isinstance(other, float):
103 if '__free__' in data:
104 data['__free__'] -= other
105 if data['__free__'] == 0:
106 del data['__free__']
107 else:
108 data['__free__'] = -other
109 elif isinstance(other, dict):
110 for key, value in other.items():
111 if key in data:
112 data[key] -= value
113 if data[key] == 0:
114 del data[key]
115 else:
116 data[key] = -value
117 elif isinstance(other, Binary):
118 for key, value in other.data.items():
119 if key in data:
120 data[key] -= value
121 if data[key] == 0:
122 del data[key]
123 else:
124 data[key] = -value
125 else:
126 raise TypeError(f'Unsupported type: {type(other)}')
127 return Binary(data)
128
129 def __rsub__(self, other):
130 return Binary(other) - self
131
132 def __neg__(self):
133 data = {}
134 for key, value in self.data.items():
135 data[key] = -value
136 return Binary(data)
137
138 def __mul__(self, other):
139 data = {}
140 if isinstance(other, str):
141 for key, value in self.data.items():
142 if key == other:
143 if '__free__' in data:
144 data['__free__'] += value
145 else:
146 data['__free__'] = value
147 else:
148 data[key, other] = value
149 elif isinstance(other, int):
150 for key, value in self.data.items():
151 data[key] = value * other
152 elif isinstance(other, float):
153 for key, value in self.data.items():
154 data[key] = value * other
155 elif isinstance(other, dict):
156 for key, value in self.data.items():
157 for key2, value2 in other.items():
158 data[key, key2] = value * value2
159 elif isinstance(other, Binary):
160 for key, value in self.data.items():
161 for key2, value2 in other.data.items():
162 if key == key2:
163 if '__free__' in data:
164 data['__free__'] += value * value2
165 else:
166 data['__free__'] = value * value2
167 else:
168 data[key, key2] = value * value2
169 else:
170 raise TypeError(f'Unsupported type: {type(other)}')
171 return Binary(data)
172
173 def __rmul__(self, other):
174 data = {}
175 if isinstance(other, str):
176 for key, value in self.data.items():
177 if key == other:
178 if '__free__' in data:
179 data['__free__'] += value
180 else:
181 data['__free__'] = value
182 else:
183 data[key, other] = value
184 elif isinstance(other, int):
185 for key, value in self.data.items():
186 data[key] = value * other
187 elif isinstance(other, float):
188 for key, value in self.data.items():
189 data[key] = value * other
190 elif isinstance(other, dict):
191 for key, value in self.data.items():
192 for key2, value2 in other.items():
193 data[key, key2] = value * value2
194 elif isinstance(other, Binary):
195 for key, value in self.data.items():
196 for key2, value2 in other.data.items():
197 if key == key2:
198 if '__free__' in data:
199 data['__free__'] += value * value2
200 else:
201 data['__free__'] = value * value2
202 else:
203 data[key, key2] = value * value2
204 else:
205 raise TypeError(f'Unsupported type: {type(other)}')
206 return Binary(data)
207
208 def __pow__(self, other):
209 data = self.data.copy()
210 new_data = {}
211 if isinstance(other, int) and other >= 0:
212 if other == 0:
213 return Binary({'__free__': 1})
214 elif other == 1:
215 return Binary(data)
216 elif other == 2:
217 return Binary(data) * Binary(data)
218
219 else:
220 raise TypeError(f'Unsupported type: {type(other)}')
221 return Binary(data)
222
223 def __truediv__(self, other):
224 return self * (1 / other)
225
[docs]
226 def calculate(self):
227
228 for key, value in self.data.copy().items():
229 if isinstance(key, tuple):
230 if key[0] == '__free__':
231 if key[1] in self.data:
232 self.data[key[1]] += value
233 else:
234 self.data[key[1]] = value
235 del self.data[key]
236 elif key[1] == '__free__':
237 if key[0] in self.data:
238 self.data[key[0]] += value
239 else:
240 self.data[key[0]] = value
241 del self.data[key]
242 energy = 0
243 if '__free__' in self.data:
244 energy = self.data['__free__']
245 del self.data['__free__']
246
247 linear_dict = {}
248 quadratic_dict = {}
249 for key, value in self.data.items():
250 if isinstance(key, str):
251 linear_dict[key] = value
252 elif isinstance(key, tuple):
253 if (key[1], key[0]) in quadratic_dict:
254 quadratic_dict[(key[1], key[0])] += value
255 else:
256 quadratic_dict[key] = value
257 else:
258 raise TypeError(f'Unsupported type: {type(key)}')
259
260 # order quadratic
261 for key, value in quadratic_dict.copy().items():
262 if key[0] > key[1]:
263 quadratic_dict[(key[1], key[0])] = value
264 del quadratic_dict[key]
265 self.variables = list(linear_dict.keys())
266 class spin:
267 linear = linear_dict
268 quadratic = quadratic_dict
269 offset = energy
270 self.spin = spin
271 return linear_dict, quadratic_dict, energy
272
[docs]
273 def compile(self):
274 self.calculate()
275 return self
276
[docs]
277 def to_bqm(self):
278 return self