class Trapez(IntegrationSolver): def __init__(self, a, b, t_max, t, r, printing=False, printing_step=100, correction=False): super().__init__(a, b, t_max, t, r, printing, printing_step) self.P = (self.u - self.a * self.t * 0.5).inverse() * (self.u + self.a * self.t * 0.5) self.Q = (self.u - self.a * self.t * 0.5).inverse() * self.t * 0.5 * self.b if self.r_params is False and correction is False: self.r = 2 * self.r def change_r(self, t): self.r = Matrix(self.n, 1).set_value(t) + Matrix(self.n, 1).set_value(t + self.t) def step_predict(self, x_current, t): if self.r_params: self.change_r(t) return self.P * x_current + self.Q * self.r def step_correct(self, x_current, x_aproximated, t): if self.r_params: self.r = self.r.set_value(t - self.t) a = self.f(x_current) self.r = self.r.set_value(t) b = self.f(x_aproximated) return x_current + 0.5*self.t*(a + b) else: return x_current + 0.5*self.t*(self.f(x_current) + self.f(x_aproximated))
def __init__(self, x0, f, e=1e-6, h=1): self.x0 = x0 self.F = f self.e = Matrix(x0.n, x0.m).set_value(e) self.h = Matrix(x0.n, x0.m).set_value(h) self.h_raw = h self.e_raw = e self.dimension = x0.n self.function_calls = 0
def __init__(self, f, e=1e-6, a=None, b=None, h=1, x0=None): self.k = 0.5 * (5**0.5 - 1) self.function = f self.function_calls = 0 if a is None and b is None: self.a, self.b = UnimodalInterval(x0, f, h).calculate() self.x0 = x0 else: self.a = a self.b = b self.e = Matrix(self.a.n, self.a.m).set_value(e) self.h = Matrix(self.a.n, self.a.m).set_value(h)
def __init__(self, x0, f, a=1.3, e=1e-6, g=None, xd=None, xg=None): self.x0 = x0 self.F = f self.a = a self.e = e self.g = g self.xd = xd self.xg = xg self.idx_h = None self.idx_h2 = None self.xc = Matrix(self.x0.n, self.x0.m) self.xr = Matrix(self.x0.n, self.x0.m) self.dimension = self.x0.n self.function_calls = 0 self.points = [self.x0.copy()]
def centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for point in self.points: if point == self.xh: continue self.xc += point self.xc *= 1 / (len(self.points) - 1)
def solve(self, x0): x_current = Matrix().load(x0) self.steps.append(x_current) t = self.t i = 0 r1, r2, r3, r4 = self.r, self.r, self.r, self.r while t <= self.t_max: if self.r_params: r1 = self.r.set_value(t) r2 = self.r.set_value(t + 0.5 * self.t) r3 = self.r.set_value(t + 0.5 * self.t) r4 = self.r.set_value(t + self.t) m1 = self.a * x_current + self.b * r1 m2 = self.a * (x_current + 0.5 * self.t * m1) + self.b * r2 m3 = self.a * (x_current + 0.5 * self.t * m2) + self.b * r3 m4 = self.a * (x_current + self.t * m3) + self.b * r4 x_next = x_current + (self.t / 6) * (m1 + 2 * m2 + 2 * m3 + m4) self.steps.append(x_next) x_current = x_next.copy() if self.printing and i % self.printing_step == 0: print("Iter: {}, x: {}".format(i, x_current)) i += 1 t += self.t return
def centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for idx in range(len(self.points)): if idx == self.idx_h: continue self.xc += self.points[idx] self.xc *= 1 / (len(self.points) - 1)
def __init__(self, x0, f, h=1): self.x0 = x0 self.function = f self.h_raw = h self.h = Matrix(x0.n, x0.m).set_value(h) self.l = self.x0 - self.h self.r = self.x0 + self.h self.function_calls = 0
def find_minimum(self, x, e_i, i): gr = GoldenRatio(lambda y: self.F.f(x + y[0, 0] * e_i), e=self.e_raw, h=self.h_raw, x0=Matrix(1, 1).set_values([[x[i, 0]]])) l, r = gr.calculate() self.function_calls += gr.function_calls return (l + r) * 0.5
def __init__(self, a, b, t_max, t, r, printing=False, printing_step=100): self.a = Matrix().load(a) self.b = Matrix().load(b) self.r_params = False self.check_params(r) if self.r_params is False: self.r = Matrix().load(r) else: self.r = Matrix(self.a.n, 1) self.t_max = t_max self.t = t self.n = self.a.n self.u = Matrix(self.n, self.n).identity() self.printing = printing self.printing_step = printing_step self.steps = [] self.P, self.Q = None, None
def __init__(self, x0, f, e=1e-6, golden_cut=False): self.x0 = x0 self.F = f self.e = Matrix(x0.n, x0.m).set_value(e) self.golden_cut = golden_cut self.e_raw = e self.dimension = x0.n self.function_calls = 0 self.gradient_calls = 0 self.hessian_calls = 0
def calculate(self): x = self.x0.copy() m = 0 while True: xs = x.copy() for i in range(self.dimension): e_i = Matrix(self.dimension, 1) e_i[i, 0] = 1 lam = self.find_minimum(x, e_i, i) x[i, 0] += lam[0, 0] if abs(x - xs) < self.e: break m += 1 return x
def calculate_points(self): for t in range(0, 2 * self.dimension): new_point = Matrix(self.dimension, 1) for idx in range(0, self.dimension): new_point[idx, 0] = self.xd[idx, 0] + random.random() * ( self.xg[idx, 0] - self.xd[idx, 0]) while self.check_implicit_conditions(new_point) is False: new_point = self.move_to_centroid(new_point) self.points.append(new_point) self.tmp_centroid() return
def solve(self, x0): x_current = Matrix().load(x0) self.steps.append(x_current) t = self.t i = 0 while t <= self.t_max: if self.r_params: self.change_r(t) x_next = self.P * x_current + self.Q * self.r x_current = x_next.copy() self.steps.append(x_next) if self.printing and i % self.printing_step == 0: print("Iter: {}, x: {}".format(i, x_current)) t += self.t i += 1 return
def solve(self, x0): x_current = Matrix().load(x0) self.steps.append(x_current) t = self.t i = 0 while t <= self.t_max: x_predicted = self.predictor.step_predict(x_current, t) x_next = self.corrector.step_correct(x_current, x_predicted, t) if self.c_iter > 1: for j in range(self.c_iter-1): x_next = self.corrector.step_correct(x_current, x_next, t) x_current = x_next.copy() self.steps.append(x_next) if self.printing and i % self.printing_step == 0: print("Iter: {}, p: {:.4f}, {:.4f}, c: {:.4f}, {:.4f}".format(i+1, x_predicted[0,0], x_predicted[1,0], x_current[0,0], x_current[1,0])) t += self.t i += 1 return
def __init__(self, x0, f, a=1, b=0.5, g=2, s=0.5, e=1e-6, h=1, print_states=False, print_short=False): self.x0 = x0 self.F = f self.a = a self.b = b self.g = g self.s = s self.e = e self.h = h self.printing = print_states self.printing1 = print_short self.xh = None self.xl = None self.idx_h = None self.idx_l = None self.xc = Matrix(self.x0.n, self.x0.m) self.xe = Matrix(self.x0.n, self.x0.m) self.xr = Matrix(self.x0.n, self.x0.m) self.xk = Matrix(self.x0.n, self.x0.m) self.dimension = self.x0.n self.function_calls = 0 self.points = [self.x0.copy()] for i in range(self.dimension): e_i = self.x0.copy() e_i[i, 0] += h self.points.append(e_i)
def calculate_error(self, gt_list): err = Matrix(self.n, 1) for pred, gt in zip(self.steps, gt_list): err += abs(pred - gt) return err
def change_r(self, t): self.r = Matrix(self.n, 1).set_value(t) + Matrix(self.n, 1).set_value(t + self.t)
def find_minimum(self, x, coeff): gr = GoldenRatio(lambda y: self.F.f(x + y[0, 0] * coeff), x0=Matrix(1, 1).set_value(1)) l, r = gr.calculate() self.function_calls += gr.function_calls return ((l + r) * 0.5)[0, 0]
class Box: def __init__(self, x0, f, a=1.3, e=1e-6, g=None, xd=None, xg=None): self.x0 = x0 self.F = f self.a = a self.e = e self.g = g self.xd = xd self.xg = xg self.idx_h = None self.idx_h2 = None self.xc = Matrix(self.x0.n, self.x0.m) self.xr = Matrix(self.x0.n, self.x0.m) self.dimension = self.x0.n self.function_calls = 0 self.points = [self.x0.copy()] def check_explicit_conditions(self, x): for idx in range(self.dimension): if not (self.xd[idx, 0] <= x[idx, 0] <= self.xg[idx, 0]): return False return True def check_implicit_conditions(self, x): for g_i in self.g: if g_i(x) < 0: return False return True def find_h(self): max_value = -math.inf f_xh2 = 0 for idx, point in enumerate(self.points): value = self.F.f(point) self.function_calls += 1 if value > max_value: f_xh2 = max_value max_value = value self.idx_h2 = self.idx_h self.idx_h = idx return f_xh2 def calculate_points(self): for t in range(0, 2 * self.dimension): new_point = Matrix(self.dimension, 1) for idx in range(0, self.dimension): new_point[idx, 0] = self.xd[idx, 0] + random.random() * ( self.xg[idx, 0] - self.xd[idx, 0]) while self.check_implicit_conditions(new_point) is False: new_point = self.move_to_centroid(new_point) self.points.append(new_point) self.tmp_centroid() return def tmp_centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for idx in range(len(self.points)): self.xc += self.points[idx] self.xc *= 1 / (len(self.points)) def centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for idx in range(len(self.points)): if idx == self.idx_h: continue self.xc += self.points[idx] self.xc *= 1 / (len(self.points) - 1) def reflection(self): self.xr = (1 + self.a) * self.xc - self.a * self.points[self.idx_h] def move_to_centroid(self, point): return 0.5 * (self.xc + point) def stopping_condition(self): for idx in range(self.dimension): if abs(self.xc[idx, 0] - self.points[self.idx_h][idx, 0]) < self.e: return True return False def calculate(self): if not (self.check_explicit_conditions( self.x0)) or not (self.check_implicit_conditions(self.x0)): print("pocetna nisu zadovoljena") return None self.xc = self.x0.copy() self.calculate_points() min_f = None i = 0 while i < 150: f_h = self.find_h() self.centroid() self.reflection() for idx in range(0, self.dimension): if self.xr[idx, 0] < self.xd[idx, 0]: self.xr[idx, 0] = self.xd[idx, 0] elif self.xr[idx, 0] > self.xg[idx, 0]: self.xr[idx, 0] = self.xg[idx, 0] while self.check_implicit_conditions(self.xr) is False: self.xr = self.move_to_centroid(self.xr) if self.F.f(self.xr) >= f_h: self.xr = self.move_to_centroid(self.xr) self.points[self.idx_h] = self.xr.copy() if self.stopping_condition(): break f_xc = self.F.f(self.xc) if min_f is None: min_f = f_xc elif f_xc < min_f: min_f = f_xc i = 0 else: i += 1 return self.xc
class Simplex: def __init__(self, x0, f, a=1, b=0.5, g=2, s=0.5, e=1e-6, h=1, print_states=False, print_short=False): self.x0 = x0 self.F = f self.a = a self.b = b self.g = g self.s = s self.e = e self.h = h self.printing = print_states self.printing1 = print_short self.xh = None self.xl = None self.idx_h = None self.idx_l = None self.xc = Matrix(self.x0.n, self.x0.m) self.xe = Matrix(self.x0.n, self.x0.m) self.xr = Matrix(self.x0.n, self.x0.m) self.xk = Matrix(self.x0.n, self.x0.m) self.dimension = self.x0.n self.function_calls = 0 self.points = [self.x0.copy()] for i in range(self.dimension): e_i = self.x0.copy() e_i[i, 0] += h self.points.append(e_i) def calculate(self): i = 0 while True: flag = False f_xh, f_xl = self.find_h_l() self.centroid() f_xc = self.F(self.xc) if self.printing1: print("F(xc) = {}, za xc >>\n{}".format(f_xc, self.xc)) self.reflection() f_xr = self.F(self.xr) self.function_calls += 2 if self.printing: print("\n\nIteracija:{}, Početni simpleks je >>".format(i), end='') for p in self.points: print("{} ".format(p[0, 0]), end='') print('') print( "\txh: {}, f(xh):{}, xl:{}, f(xl):{}, xc: {}, f(xc): {}, xr:{}, f(xr):{}" .format(self.xh[0, 0], f_xh, self.xl[0, 0], f_xl, self.xc[0, 0], f_xc, self.xr[0, 0], f_xr)) if f_xr < f_xl: self.expansion() if self.printing: print("\tIzračunata ekspanzija, xe:{}, f(xe):{}".format( self.xe[0, 0], self.F.f(self.xe))) if self.F(self.xe) < f_xl: self.points[self.idx_h] = self.xe.copy() self.xh = self.xe.copy() else: self.points[self.idx_h] = self.xr.copy() self.xh = self.xr.copy() self.function_calls += 1 else: for point in self.points: if point == self.xh: continue self.function_calls += 1 if f_xr <= self.F(point): flag = True break if flag: self.points[self.idx_h] = self.xr.copy() self.xh = self.xr.copy() continue else: if f_xr < f_xh: self.points[self.idx_h] = self.xr.copy() self.xh = self.xr.copy() self.contraction() if self.printing: print( "\tIzračunata kontrakcija, xk:{}, f(xk):{}".format( self.xk[0, 0], self.F(self.xk))) if self.F(self.xk) < f_xh: self.points[self.idx_h] = self.xk.copy() self.xh = self.xk.copy() else: self.move_points() if self.printing: print("\tTočke su pomaknute, novi simpleks je >>", end='') for p in self.points: print("\t{} ".format(p[0, 0]), end='') print('') self.function_calls += 1 if self.printing: print("\tSimpleks na kraju iteracije je >>", end='') for p in self.points: print("\t{} ".format(p[0, 0]), end='') print('') if self.stop_condition(f_xc) <= self.e: break i += 1 return self.xc def stop_condition(self, f_xc): result = 0 for point in self.points: result += (self.F(point) - f_xc)**2 self.function_calls += 1 result /= len(self.points) a = math.sqrt(result) return a def find_h_l(self): max_value = -math.inf min_value = math.inf f_xh, f_xl = 0, 0 for idx, point in enumerate(self.points): value = self.F(point) self.function_calls += 1 if value > max_value: max_value = value self.xh = point.copy() self.idx_h = idx f_xh = value if value < min_value: min_value = value self.xl = point.copy() self.idx_l = idx f_xl = value return f_xh, f_xl def centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for point in self.points: if point == self.xh: continue self.xc += point self.xc *= 1 / (len(self.points) - 1) def reflection(self): self.xr = (1 + self.a) * self.xc - self.a * self.xh def expansion(self): self.xe = (1 - self.g) * self.xc + self.g * self.xr def contraction(self): self.xk = (1 - self.b) * self.xc + self.b * self.xh def move_points(self): for i in range(len(self.points)): self.points[i] = self.s * (self.points[i] + self.xl)
def tmp_centroid(self): self.xc = Matrix(self.x0.n, self.x0.m) for idx in range(len(self.points)): self.xc += self.points[idx] self.xc *= 1 / (len(self.points))