Advertisement
evgeniya_polyntseva

gradient_d

May 22nd, 2020
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.93 KB | None | 0 0
  1. from sympy import *
  2. import sympy as sym
  3. import math
  4.  
  5. x, y, t = sym.symbols('x y t')
  6.  
  7.  
  8. def interval(func):
  9.     delta = 10 ** (-3)
  10.     x0 = 0
  11.     k = 0
  12.     f1 = func.subs(t, x0)
  13.     f2 = func.subs(t, (x0 + delta))
  14.  
  15.     if f1 >= f2:
  16.         k += 1
  17.         xi = x0 + delta
  18.         h = delta
  19.     else:
  20.         xi = x0 - delta
  21.         h = -delta
  22.     k += 1
  23.     xk = x0
  24.     while (True):
  25.         h *= 2
  26.         xj = xi + h
  27.         f3 = func.subs(t, xi)
  28.         f4 = func.subs(t, xj)
  29.         if f3 > f4:
  30.             k += 1
  31.             xk = xi
  32.             xi += h
  33.             continue
  34.         else:
  35.             if (xk < xj):
  36.                 return (xk, xj)
  37.             else:
  38.                 return (xj, xk)
  39.             break
  40.  
  41.  
  42. def golden_ratio(func):
  43.     inter = interval(func)
  44.     a = inter[0]
  45.     b = inter[1]
  46.     eps = 10 ** (-10)
  47.     coef1 = (3 - math.sqrt(5)) / 2
  48.     coef2 = (math.sqrt(5) - 1) / 2
  49.     i = 1
  50.     x1 = a + coef1 * (b - a)
  51.     x2 = a + coef2 * (b - a)
  52.     f1 = func.subs(t, x1)
  53.     f2 = func.subs(t, x2)
  54.     while True:
  55.         if f1 <= f2:
  56.             b = x2
  57.             x2 = x1
  58.             f2 = f1
  59.             k = 1
  60.         else:
  61.             a = x1
  62.             x1 = x2
  63.             f1 = f2
  64.             k = 2
  65.         if abs(a - b) < eps:
  66.             return (a + b) / 2
  67.         if k == 1:
  68.             x1 = a + coef1 * (b - a)
  69.             f1 = func.subs(t, x1)
  70.         else:
  71.             x2 = a + coef2 * (b - a)
  72.             f2 = func.subs(t, x2)
  73.         i += 1
  74.  
  75.  
  76. def gradient_descent(func):
  77.     # v-начальная точка
  78.     v = (0, 4)
  79.     eps1 = 10 ** (-10)
  80.     eps2 = 10 ** (-10)
  81.     i = 0
  82.     # нахождение градиента и подстановка v
  83.     gradient = ((diff(func, x)).subs({x: v[0], y: v[1]}), (diff(func, y)).subs({x: v[0], y: v[1]}))
  84.     norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
  85.     while norma_grad > eps1:
  86.         # expand раскрывает скобки
  87.         phi = expand(func.subs({x: v[0] - gradient[0] * t, y: v[1] - gradient[1] * t}))
  88.         # условие безусловного экстремума, нахождение t
  89.         t_res = golden_ratio(phi)
  90.         # находим следующее приближение
  91.         x_next = v[0] - gradient[0] * t_res
  92.         y_next = v[1] - gradient[1] * t_res
  93.         v_next = (x_next, y_next)
  94.         n1 = ((v_next[0] - v[0]) ** 2 + (v_next[1] - v[1]) ** 2) ** 0.5
  95.         n2 = abs(func.subs({x: v_next[0], y: v_next[1]}) - func.subs({x: v[0], y: v[1]}))
  96.         if n1 > eps2 and n2 > eps2:
  97.             v = v_next
  98.             gradient = ((diff(func, x)).subs({x: v[0], y: v[1]}), (diff(func, y)).subs({x: v[0], y: v[1]}))
  99.             norma_grad = (gradient[0] ** 2 + gradient[1] ** 2) ** 0.5
  100.             i = i + 1
  101.  
  102.         else:
  103.             break
  104.     #print('min F=', "%.5f" % func.subs({x: v_next[0], y: v_next[1]}), 'в точке', v_next)
  105.     return v_next
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement