Advertisement
mrAnderson33

mopt

Dec 12th, 2018
142
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.92 KB | None | 0 0
  1. import sys
  2. import math
  3. import numpy
  4.  
  5. class function:
  6.     a = [1.11, 0.6404, 0.0844, 1.064, -0.5425, 0.826, -0.7579, -0.3042, -0.4513]
  7.     x0 = [1, 1, 1]
  8.     epsilon = 0.000001
  9.  
  10.     def calculate(self, x1, x2, x3):
  11.         return self.a[0] * x1 * x1 + 2 * self.a[1] * x1 * x2 + 2 * self.a[2] * x1 * x3 + self.a[3] * x2 * x2 + 2 * self.a[4] * x2 * x3 + self.a[5] * x3 * x3 + 2 * self.a[6] * x1 + 2 * self.a[7] * x2 + 2 * self.a[8] * x3
  12.  
  13.     def dFdx1(self, x):
  14.         return 2 * self.a[0] * x[0] + 2 * self.a[1] * x[1] + 2 * self.a[2] * x[2] + 2 * self.a[6]
  15.     def dFdx1dx1(self):
  16.         return 2 * self.a[0]
  17.     def dFdx1dx2(self):
  18.         return 2 * self.a[1]
  19.     def dFdx1dx3(self):
  20.         return 2 * self.a[2]
  21.     def dFdx2(self, x):
  22.         return 2 * self.a[1] * x[0] + 2 * self.a[3] * x[1] + 2 * self.a[4] * x[2] + 2 * self.a[7]
  23.     def dFdx2dx2(self):
  24.         return 2 * self.a[3]
  25.     def dFdx2dx3(self):
  26.         return 2 * self.a[4]
  27.     def dFdx3(self, x):
  28.         return 2 * self.a[2] * x[0] + 2 * self.a[4] * x[1] + 2 * self.a[5] * x[2] + 2 * self.a[8]
  29.     def dFdx3dx3(self):
  30.         return 2 * self.a[5]
  31.  
  32.     def Jacobi(self, x):
  33.         return [-self.dFdx1(x), -self.dFdx2(x), -self.dFdx3(x)]
  34.     def CountAlpha(self, x, h):
  35.         f2 = [[self.dFdx1dx1(), self.dFdx1dx2(), self.dFdx1dx3()],
  36.               [self.dFdx1dx2(), self.dFdx2dx2(), self.dFdx2dx3()],
  37.               [self.dFdx1dx3(), self.dFdx2dx3(), self.dFdx3dx3()]]
  38.         h_copy = h[:]
  39.         res = [0, 0, 0]
  40.         for i in range(0, 3):
  41.             for j in range(0, 3):
  42.                 res[i] += h_copy[j] * f2[i][j]
  43.         return -(self.dFdx1(x) * h[0] + self.dFdx2(x) * h[1] + self. dFdx3(x) * h[2]) / (h[0] * res[0] + h[1] * res[1] + h[2] * res[2])
  44.  
  45.     def MethodNewtonSubFunction(self, h):
  46.         res = [0, 0, 0]
  47.         iJacobi = [[self.dFdx1dx1(), self.dFdx1dx2(), self.dFdx1dx3()],
  48.                    [self.dFdx1dx2(), self.dFdx2dx2(), self.dFdx2dx3()],
  49.                    [self.dFdx1dx3(), self.dFdx2dx3(), self.dFdx3dx3()]]
  50.         inverse = numpy.linalg.inv(iJacobi)
  51.         for i in range(0, 3):
  52.             for j in range(0, 3):
  53.                 res[i] += -h[j] * inverse[i][j]
  54.         return res
  55.  
  56.     def CountH(self, x0, x1, h):
  57.         res = [-self.dFdx1(x1), -self.dFdx2(x1), -self.dFdx3(x1)]
  58.         c = (self.dFdx1(x1) * self.dFdx1(x1) + self.dFdx2(x1) * self.dFdx2(x1) + self.dFdx3(x1) * self.dFdx3(x1)) / (self.dFdx1(x0) * self.dFdx1(x0) + self.dFdx2(x0) * self.dFdx2(x0) + self.dFdx3(x0) * self.dFdx3(x0))
  59.         for i in range(0, 3):
  60.             res[i] += h[i] * c
  61.         return res
  62.  
  63.  
  64.     def Spusk(self):
  65.         k = 0
  66.         if (len(self.x0) > 3):
  67.             raise IOError("Исключение")
  68.         res_x = self.x0[:]
  69.         while(True):
  70.             ak = self.CountAlpha(res_x, self.Jacobi(res_x))
  71.             nx1 = res_x[0] - ak * self.dFdx1(res_x)
  72.             nx2 = res_x[1] - ak * self.dFdx2(res_x)
  73.             nx3 = res_x[2] - ak * self.dFdx3(res_x)
  74.             if math.sqrt(math.pow(res_x[0] - nx1, 2) + math.pow(res_x[1] - nx2, 2) + math.pow(res_x[2] - nx3, 2)) < self.epsilon:
  75.                 break
  76.             res_x[0] = nx1
  77.             res_x[1] = nx2
  78.             res_x[2] = nx3
  79.             k += 1
  80.         print('Наискорейший спуск (итерации): ', k)
  81.         return res_x
  82.  
  83.     def MethodNewton(self):
  84.         l = 0
  85.         res_x = self.x0[:]
  86.         i = 0
  87.         while(i != 1):
  88.             multiplying = self.MethodNewtonSubFunction(self.Jacobi(res_x))
  89.             for j in range(0, 3):
  90.                 res_x[j] -= multiplying[j]
  91.             i += 1
  92.             l += 1
  93.         print('Метод Ньютона (итерации): ', l)
  94.         return res_x
  95.  
  96.     def MethodGradienov(self):
  97.         j = 0
  98.         h0 = self.Jacobi(self.x0)
  99.         res_x = self.x0[:]
  100.         a = self.CountAlpha(self.x0, h0)
  101.         for i in range(0, 3):
  102.             x1 = [res_x[0] + a * h0[0], res_x[1] + a * h0[1], res_x[2] + a * h0[2]]
  103.             h0 = self.CountH(res_x, x1, h0)
  104.             res_x = x1[:]
  105.             a = self.CountAlpha(self.x0, h0)
  106.             j += 1
  107.         print('Метод градиентов (итерации)', j)
  108.         return res_x
  109.  
  110. if __name__ == "__main__":
  111.     f = function()
  112.     pointsSp = f.Spusk()
  113.     pointsNewton = f.MethodNewton()
  114.     pointsGradient = f.MethodGradienov()
  115.  
  116.     print('Наискорейший спуск: ')
  117.     print(pointsSp[0], pointsSp[1], pointsSp[2])
  118.     print('F = ', f.calculate(pointsSp[0], pointsSp[1], pointsSp[2]))
  119.  
  120.     print('Метод Ньютона: ')
  121.     print(pointsNewton[0], pointsNewton[1], pointsNewton[2])
  122.     print('F = ', f.calculate(pointsNewton[0], pointsNewton[1], pointsNewton[2]))
  123.  
  124.     print('Сопряженные градиенты: ')
  125.     print(pointsGradient[0], pointsGradient[1], pointsGradient[2])
  126.     print('F = ', f.calculate(pointsGradient[0], pointsGradient[1], pointsGradient[2]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement