def solve(self, k): self.initialize(k) if self.non_basic_idx == self.n + 1: self.logger.info('Found a fixed point.') self.fixed_point = 0 triangle_vertices = self.triangle.get_all_vertices() for i, weight in enumerate(self.weights): self.fixed_point += weight * np.array(triangle_vertices[i]) self.fixed_point = splx.SimplexPoint(self.fixed_point) return self.fixed_point cnt = 1 while True: self.logger.info('Iteration {0}, Current triangle: {1}'.format( cnt, self.triangle.get_all_vertices())) self.move() self.pivot() cnt += 1 if self.non_basic_idx == self.n + 1: break self.logger.info('Found a fixed point.') self.fixed_point = 0 triangle_vertices = self.triangle.get_all_vertices() for i, weight in enumerate(self.weights): self.fixed_point += weight * np.array(triangle_vertices[i]) self.fixed_point = splx.SimplexPoint(self.fixed_point) return self.fixed_point
def initialize(self, k): b = self.b while True: x0 = splx.get_random_simplex_point(self.n) tmp = [] for i, spike in enumerate(b): if spike >= 0: continue tmp.append(-x0[i] / spike) theta = min(tmp) x0 = splx.SimplexPoint(x0 + theta * b) triangle = splx.get_covering_triangle(x0, k) triangle_vertices = triangle.get_all_vertices() L = np.zeros(shape=(self.n + 2, self.n + 1)) for i in range(0, self.n + 1): L[:, i] = list( np.array(self.f(splx.SimplexPoint(triangle_vertices[i]))) - np.array(splx.SimplexPoint(triangle_vertices[i]))) + [1] d = np.array(list(b) + [1]) d.shape = (self.n + 2, 1) m = np.array([0 for _ in range(0, self.n + 1)] + [1]) L_ = np.concatenate([L, d], axis=1) pivot_idx = None for i in [self.n + 1] + list(range(0, self.n + 1)): sub_L_ = np.delete(np.delete(L_, i, axis=1), 0, axis=0) try: v = np.linalg.solve(sub_L_, m[1:]) except: continue if all([w >= 0 for w in v]): pivot_idx = i if pivot_idx == self.n + 1: self.slack_weight = 0 self.weights = v else: self.slack_weight = v[self.n] self.weights = np.delete(list(np.insert(v, i, 0)), self.n + 1) print(self.weights) break if pivot_idx is not None: break self.triangle = triangle self.non_basic_idx = pivot_idx self.L_ = L_ self.L = L return triangle_vertices, pivot_idx
def f(s: splx.SimplexPoint): """ This is a rotation. """ if s.n != 2: raise RuntimeError('dimension does not match!') return splx.SimplexPoint([s[1], s[2], s[0]])
def f(s: splx.SimplexPoint): """ For a given 2-simplex point (x0, x1, x2), this function gives (sqrt(x1), 1-sqrt(x1), 0). """ if s.n != 2: raise RuntimeError('dimension does not match!') return splx.SimplexPoint([np.sqrt(s[1]), 1 - np.sqrt(s[1]), 0])
def solve_traversal(self, k): all_triangles = splx.get_all_triangles(self.n, k) for triangle in all_triangles: triangle_vertices = triangle.get_all_vertices() L = np.zeros(shape=(self.n + 2, self.n + 1)) for i in range(0, self.n + 1): L[:, i] = list( np.array(self.f(splx.SimplexPoint(triangle_vertices[i]))) - np.array(splx.SimplexPoint(triangle_vertices[i]))) + [1] m = np.array([0 for _ in range(0, self.n + 1)] + [1]) sub_L = np.delete(L, 0, axis=0) v = np.linalg.solve(sub_L, m[1:]) if all([c >= 0 for c in v]): self.logger.info('Found a fixed point.') fixed_point = 0 for i, weight in enumerate(v): fixed_point += weight * np.array(triangle_vertices[i]) fixed_point = splx.SimplexPoint(fixed_point) print(fixed_point)
def f(sp: splx.SimplexPoint): """ Input is a simplex point, we first transform it into a probability distribution, and treat it as I to solve the mfg. The return is again a simplex point. """ major_stopping_dist = model.get_random_initial_dist() # minor_stopping_dist = model.get_random_initial_dist() minor_stopping_dist = utils.distribution.Distribution([ i * model.T / model.time_num_grids for i in range(0, model.time_num_grids + 1) ], sp) solver = GameSolver( model, major_stopping_dist, minor_stopping_dist, num_max_iter=10, num_mc=1000, precision=0.05, ) solver.update_() return splx.SimplexPoint(solver.minor_stopping_dist.pdf.values)
def move(self): """ Given the triangle and the non-basic index, move to the adjacent triangle. """ self.logger.info('Moving to the next triangle...') U = splx.get_U(self.n) if self.non_basic_idx == 0: new_v = splx.SimplexPoint( np.array(self.triangle.v) + 1 / self.triangle.k * U[:, self.triangle.permutation[0]]) new_permutation = self.triangle.permutation[1:] + [ self.triangle.permutation[0] ] self.triangle = splx.Triangle(new_v, new_permutation, self.triangle.k) self.non_basic_idx = self.n non_basic_vertex = splx.SimplexPoint( self.triangle.get_all_vertices()[self.non_basic_idx]) l = np.array( list( np.array(self.f(non_basic_vertex)) - np.array(non_basic_vertex)) + [1]) l.shape = (self.n + 2, 1) self.L = np.delete(self.L, 0, axis=1) self.L = np.concatenate([self.L, l], axis=1) self.weights = list(np.delete(self.weights, 0)) self.weights = self.weights + [0] elif self.non_basic_idx == self.n: new_v = splx.SimplexPoint( np.array(self.triangle.v) - 1 / self.triangle.k * U[:, self.triangle.permutation[-1]]) new_permutation = [self.triangle.permutation[-1] ] + self.triangle.permutation[:( len(self.triangle.permutation) - 1)] self.triangle = splx.Triangle(new_v, new_permutation, self.triangle.k) self.non_basic_idx = 0 non_basic_vertex = splx.SimplexPoint( self.triangle.get_all_vertices()[self.non_basic_idx]) l = np.array( list( np.array(self.f(non_basic_vertex)) - np.array(non_basic_vertex)) + [1]) l.shape = (self.n + 2, 1) self.L = np.delete(self.L, self.n, axis=1) self.L = np.concatenate([l, self.L], axis=1) self.weights = list(np.delete(self.weights, self.n)) self.weights = [0] + self.weights else: new_v = self.triangle.v new_permutation = self.triangle.permutation front = self.triangle.permutation[self.non_basic_idx - 1] back = self.triangle.permutation[self.non_basic_idx] new_permutation[self.non_basic_idx - 1] = back new_permutation[self.non_basic_idx] = front self.triangle = splx.Triangle(new_v, new_permutation, self.triangle.k) non_basic_vertex = splx.SimplexPoint( self.triangle.get_all_vertices()[self.non_basic_idx]) l = list( np.array(self.f(non_basic_vertex)) - np.array(non_basic_vertex)) + [1] self.L[:, self.non_basic_idx] = l