Exemple #1
0
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))
Exemple #2
0
 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
Exemple #3
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)
Exemple #4
0
 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()]
Exemple #5
0
 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)
Exemple #6
0
    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
Exemple #7
0
 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)
Exemple #8
0
 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
Exemple #9
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
Exemple #10
0
 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
Exemple #11
0
 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
Exemple #12
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
Exemple #13
0
    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
Exemple #14
0
 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
Exemple #15
0
 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
Exemple #16
0
 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)
Exemple #17
0
 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
Exemple #18
0
 def change_r(self, t):
     self.r = Matrix(self.n, 1).set_value(t) + Matrix(self.n, 1).set_value(t + self.t)
Exemple #19
0
 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]
Exemple #20
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
Exemple #21
0
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)
Exemple #22
0
 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))