def hubo_simulated_annealing(bhom: BinaryHigherOrderModel, state: list, schedule: list, var_type): adj_dict = bhom.adj_dict() state = np.array(state) if SPIN == cast_var_type(var_type): for beta, mc_steps in schedule: for _ in range(mc_steps): for i in bhom.indices: de = -2 * state[i] * np.sum([ d * np.prod(state[_inds]) for _inds, d in adj_dict[i] ]) de += -2 * state[i] * bhom.interactions[0][i] if de < 0 or np.random.uniform(0, 1) < np.exp(-beta * de): state[i] *= -1 return state elif BINARY == cast_var_type(var_type): for beta, mc_steps in schedule: for _ in range(mc_steps): for i in bhom.indices: de = (1 - 2 * state[i]) * np.sum([ d * np.prod(state[_inds]) for _inds, d in adj_dict[i] ]) de += (1 - 2 * state[i]) * bhom.interactions[0][i] if de <= 0 or np.random.uniform(0, 1) < np.exp(-beta * de): state[i] = 0 if state[i] == 1 else 1 return state else: raise ValueError("var_type should be SPIN or BINARY")
def __init__(self, h=None, J=None, Q=None, var_type=openjij.SPIN): self.var_type = openjij.cast_var_type(var_type) if self.var_type == openjij.SPIN: if (h is None) or (J is None): raise ValueError('Input h and J.') self.linear = h self.quad = J elif self.var_type == openjij.BINARY: if not isinstance(Q, dict) or Q is None: raise ValueError('Q should be dictionary.') self.linear = {} self.quad = {} for (i, j), qij in Q.items(): if i == j: self.linear[i] = qij else: self.quad[(i, j)] = qij index_set = set(self.linear.keys()) for v1, v2 in self.quad.keys(): index_set.add(v1) index_set.add(v2) self.indices = list(index_set) if var_type == openjij.SPIN: self.energy_bias = 0.0 else: # BINARY self.energy_bias = (sum(list(self.linear.values())) * 2 + sum(list(self.quad.values())))/4 self._interaction_matrix = None # calculated at interactions() self.size = len(self.indices)
def __init__(self, machine_type, h=None, J=None, Q=None, king_graph=None, var_type=openjij.SPIN): """ The constructor reformat interactions to Web API format (ising king graph), and validates that the interaction is in King Graph. ---------- machine_type : int choose 'ASIC' or 'FPGA' king_graph : list of list represents ising or QUBO interaction. Each spins are decided by 2-d corrdinate x, y. Quadratic term [x1, y1, x2, y2, value] Linear term [x1, y1, x1, y1, value] """ var_type = openjij.cast_var_type(var_type) # set parameter ranges self.machine_type = machine_type if self.machine_type == "ASIC": self.xrange = [0, 351+1] self.yrange = [0, 175+1] self.prange = [-3, 3] elif self.machine_type == "FPGA": self.xrange = [0, 79+1] self.yrange = [0, 79+1] self.prange = [-127, 127] else: raise ValueError('machine type should be ASIC or FPGA') # convert format h, J, Q and initilize BQM if king_graph is not None: h, J, Q = self._convert_to_BQM_format(king_graph, var_type) super().__init__(h=h, J=J, Q=Q, var_type=var_type) # reformat to ising king graph (which is Web API format) if king_graph is not None and var_type == openjij.SPIN: self._ising_king_graph = king_graph elif var_type == openjij.SPIN: self._ising_king_graph = [] for index, h in self.linear.items(): x, y = self._convert_to_xy(index) self._ising_king_graph.append([x,y ,x,y, h]) for (i, j), J in self.quad.items(): x1, y1 = self._convert_to_xy(i) x2, y2 = self._convert_to_xy(j) self._ising_king_graph.append([x1, y1, x2, y2, J]) else: ising_int = self.ising_interactions() sys_size = len(ising_int) self._ising_king_graph = [] for i in range(sys_size): for j in range(i, sys_size): if ising_int[i][j] == 0: continue x1, y1 = self._convert_to_xy(self.indices[i]) x2, y2 = self._convert_to_xy(self.indices[j]) self._ising_king_graph.append([x1, y1, x2, y2, ising_int[i][j]]) self._validation_ising_king_graph()
def __init__(self, var_type, indices): self.states = [] self.energies = [] self.var_type = openjij.cast_var_type(var_type) self.q_states = [] self.q_energies = [] self.indices = indices self.min_samples = {} self.info = {}
def hubo_sa_sampling(bhom, var_type, schedule, schedule_info, num_sweeps=100, num_reads=1, init_state=None, seed=None): variables = list(cast_var_type(var_type).value) init_state = init_state if init_state else np.random.choice( variables, len(bhom.indices)) execution_time = [] states, energies = [], [] @measure_time def exec_sampling(): for _ in range(num_reads): _exec_time, state = measure_time(hubo_simulated_annealing)( bhom, init_state, schedule, var_type=var_type) execution_time.append(_exec_time) states.append(state) energies.append(bhom.calc_energy(state)) sampling_time, _ = exec_sampling() response = openjij.Response.from_samples((states, bhom.indices), var_type, energies, info={}) response.info['sampling_time'] = sampling_time * 10**6 # micro sec response.info['execution_time'] = np.mean( execution_time) * 10**6 # micro sec response.info['list_exec_times'] = np.array( execution_time) * 10**6 # micro sec #response.update_ising_states_energies( # response.states, response.energies) response.info['schedule'] = schedule_info return response
def test_cast(self): spin_var = oj.cast_var_type('SPIN') self.assertEqual(spin_var, oj.SPIN) binary_var = oj.cast_var_type('BINARY') self.assertEqual(binary_var, oj.BINARY)
def test_variable_type(self): spin = oj.cast_var_type('SPIN') self.assertEqual(spin, oj.SPIN) binary = oj.cast_var_type('BINARY') self.assertEqual(binary, oj.BINARY)
def __init__(self, linear: dict = None, quadratic: dict = None, offset: float = 0.0, king_graph=None, var_type=openjij.SPIN, machine_type: str = ''): """__init__. Args: linear (dict): linear biases quadratic (dict): quadratic biases offset (float): offset king_graph: represents ising or QUBO interaction. Each spins are decided by 2-d corrdinate x, y. Quadratic term [x1, y1, x2, y2, value] Linear term [x1, y1, x1, y1, value] var_type: 'SPIN' or 'BINARY' machine_type (str): choose 'ASIC' or 'FPGA' """ var_type = openjij.cast_var_type(var_type) # set parameter ranges self.machine_type = machine_type if self.machine_type == "ASIC": self.xrange = [0, 351 + 1] self.yrange = [0, 175 + 1] self.prange = [-3, 3] elif self.machine_type == "FPGA": self.xrange = [0, 79 + 1] self.yrange = [0, 79 + 1] self.prange = [-127, 127] else: raise ValueError('machine type should be ASIC or FPGA') # convert format h, J, Q and initilize BQM if king_graph is not None: linear, quadratic = self._convert_to_BQM_format( king_graph, var_type) super().__init__(linear, quadratic, offset=offset, var_type=var_type) # reformat to ising king graph (which is Web API format) if king_graph is not None and var_type == openjij.SPIN: self._ising_king_graph = king_graph else: # generate Ising h and J and create ising_king_graph format lin, quad, _ = self.to_ising() self._ising_king_graph = [] for index, h in lin.items(): if h != 0: x, y = self._convert_to_xy(index) self._ising_king_graph.append([x, y, x, y, h]) for (i, j), J in quad.items(): if J != 0: x1, y1 = self._convert_to_xy(i) x2, y2 = self._convert_to_xy(j) self._ising_king_graph.append([x1, y1, x2, y2, J]) self._validation_ising_king_graph()