Advertisement
EgorYankovsky

Untitled

Apr 18th, 2023
770
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.10 KB | None | 0 0
  1. # Метод сопряженных градиентов
  2.  
  3. import numpy as np
  4. import math as mt
  5.  
  6. H = 1e-15
  7.  
  8. def Norma(_x : np.array) -> float:
  9.     return mt.sqrt(_x[0] ** 2 + _x[1] ** 2)
  10.  
  11. def Grad(_f, _x : np.array) -> np.array:
  12.     return ((_f((_x[0] + H, _x[1])) - _f((_x[0], _x[1]))) / H, (_f((_x[0], _x[1] + H)) - _f((_x[0], _x[1]))) / H)
  13.  
  14. def FindMinimum(_f, _x : np.array, _s : np.array, _lamb0 = 0.0):
  15.     h = 0
  16.     lamb = _lamb0
  17.     delt = 1e-8
  18.     if _f(_x + _lamb0 * _s) > _f(_x + (_lamb0 + delt) * _s):
  19.         lamb = _lamb0 + delt
  20.         h = delt
  21.     elif _f(_x + _lamb0 * _s) < _f(_x + (_lamb0 + delt) * _s):
  22.         lamb = _lamb0 + delt
  23.         h = -delt
  24.        
  25.     while True:
  26.         h *= 2
  27.         lamb += h
  28.         if _f(_x + (lamb - h) * _s) <= _f(_x + lamb * _s):
  29.             return np.array([min(_lamb0, lamb), max(_lamb0, lamb)])
  30.  
  31.  
  32. def DichotomyMethod(_f, _interval, _x, _s, eps = 1e-7):
  33.     _a = _interval[0]
  34.     _b = _interval[1]
  35.     _x1 = (_a + _b - 0.5 * eps) / 2
  36.     _x2 = (_a + _b + 0.5 * eps) / 2
  37.     while abs(_b - _a) > eps:
  38.         if _f(_x + _x1 * _s) <= _f(_x + _x2 * _s):
  39.             _b = _x2
  40.         else:
  41.             _a = _x1
  42.         _x1 = (_a + _b - 0.5 * eps) / 2
  43.         _x2 = (_a + _b + 0.5 * eps) / 2
  44.     return 0.5 * (_x1 + _x2)
  45.  
  46.  
  47. def FindMinLambd(_f, _x0, _s):
  48.     return DichotomyMethod(_f, FindMinimum(_f, _x0, _s), _x0, _s)
  49.  
  50.  
  51. def Method(_f, _x0 : np.array, eps = 1e-3):
  52.  
  53.     k = 0
  54.     x_curr = np.array(_x0)
  55.     maxIter = 1000
  56.     _s = np.zeros(2)
  57.  
  58.     while k < maxIter:
  59.  
  60.         # step 1
  61.         if k % 3 == 0:
  62.             _s = -1 * np.array(Grad(_f, x_curr))
  63.        
  64.         # step 2
  65.         lambd = FindMinLambd(_f, x_curr, _s)
  66.         x_next = x_curr + lambd * _s
  67.        
  68.         # step 3, 4
  69.         w = (Norma(Grad(_f, x_next))) ** 2 / (Norma(Grad(_f, x_curr))) ** 2
  70.         _s = -1 * np.array(Grad(_f, x_next)) + w * _s
  71.        
  72.         if Norma(_s) < eps:
  73.             print (str(k) + " MCG answer: ({:9e}; {:9e}), {:9e}".format(x_next[0], x_next[1], _f(x_next)))
  74.             break
  75.        
  76.         x_curr = x_next
  77.         k += 1
  78.        
  79.        
  80. # Метод крутящихся жоп
  81.  
  82. import math as mt
  83. import numpy as np
  84.  
  85. D1 = lambda t = 1, n = 2: t / (n * mt.sqrt(2)) * (mt.sqrt(n + 1) + n - 1)
  86. D2 = lambda t = 1, n = 2: t / (n * mt.sqrt(2) * (mt.sqrt(n + 1) - 1))
  87.  
  88. def SortByAscending(_f, _x1 : np.array, _x2 : np.array, _x3 : np.array):
  89.     fMax = max(_f(_x1), _f(_x2), _f(_x3))
  90.     fMin = min(_f(_x1), _f(_x2), _f(_x3))
  91.  
  92.     xl, xs, xh = np.array([]), np.array([]), np.array([])
  93.     arr = [_x1, _x2, _x3]
  94.    
  95.     for vector in arr:
  96.         if _f(vector) == fMin:
  97.             xl = vector
  98.         elif _f(vector) == fMax:
  99.             xh = vector
  100.         else:
  101.             xs = vector
  102.    
  103.     return xl, xs, xh
  104.  
  105.  
  106. # Отражение
  107. def Reflection(_xMass : np.array, _xh : np.array, _alpha : float) -> np.array:
  108.     return _xMass + _alpha * (_xMass - _xh)
  109.  
  110.  
  111. # Растяжение
  112. def Stretch(_xMass : np.array, _xRefl : np.array, _gamma : float) -> np.array:
  113.     return _xMass + _gamma * (_xRefl - _xMass)
  114.  
  115. # Сжатие
  116. def Compression(_xMass : np.array, _xh : np.array, _beta : float) -> np.array:
  117.     return _xMass + _beta * (_xh - _xMass)
  118.  
  119. # Редукция
  120. def Reduction(_xl : np.array, _x1 : np.array, _x2 : np.array, _x3 : np.array):
  121.     return np.array(_xl + 0.5 * (_x1 - _xl)), np.array(_xl + 0.5 * (_x2 - _xl)), np.array(_xl + 0.5 * (_x3 - _xl))
  122.  
  123.  
  124. # 0 < alpha
  125. # 0 < beta < 1
  126. # 0 < gamma
  127. def Method(f, _x0 : np.array, eps = 1e-3, alph = 1.0, beta = 0.5, gamm = 2.5):
  128.  
  129.     # step 1
  130.     k = 0
  131.     x1 = _x0
  132.     x2 = np.array([D1(), D2()])
  133.     x3 = np.array([D2(), D1()])
  134.     f_count = 0
  135.  
  136.     while True:
  137.        
  138.         # step 2
  139.  
  140.         x1, x2, x3 = SortByAscending(f, x1, x2, x3)
  141.         xh = np.array(x3)
  142.         xl = np.array(x1)
  143.         xs = np.array(x2)
  144.         xl1 = np.zeros(2)
  145.  
  146.         # step 3
  147.         xMass = 0.5 * np.array((xl + xs)) # x_{n + 2}
  148.         fxh, fxs, fxl, fxmass = f(xh), f(xs), f(xl), f(xMass)
  149.  
  150.         # step 4
  151.         delt = mt.sqrt(((fxh - fxmass) ** 2 + (fxs - fxmass) ** 2 + (fxl - fxmass) ** 2) / 3.0)
  152.         if delt <= eps:
  153.             print (str(k) + ' DPM answer: ({:8e}; {:8e}), f = {:8e}'.format(xl[0], xl[1], f(xl)))
  154.             break
  155.  
  156.         # step 5
  157.         xRefl = np.array(Reflection(xMass, xh, alph)) # x_{n + 3}
  158.         fxrefl = f(xRefl)
  159.         xStrt = np.array([]) # x_{n + 4}
  160.         xComp = np.array([]) # x_{n + 5}
  161.    
  162.         # step 6
  163.         if fxrefl <= fxl:
  164.             xStrt = Stretch(xMass, xRefl, gamm)
  165.             fxstrt = f(xStrt)
  166.             if fxstrt < fxl:
  167.                 xh = xStrt
  168.                 x3 = xh
  169.             else:
  170.                 xh = xRefl
  171.                 x3 = xh
  172.         elif fxs < fxrefl and fxrefl <= fxh:
  173.             xComp = Compression(xMass, xh, beta)
  174.             xh = xComp
  175.             x3 = xh
  176.         elif fxl < fxrefl and fxrefl <= fxs:
  177.             xh = xRefl
  178.             x3 = xh
  179.         elif fxrefl > fxh:
  180.             x1, x2, x3 = Reduction(xl, x1, x2, x3)
  181.  
  182.         k += 1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement