Advertisement
overwater

Untitled

Mar 9th, 2016
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 10.67 KB | None | 0 0
  1. import numpy as np
  2.  
  3.  
  4. def f1(x):
  5.     return -5 * x ** 5 + 4 * x ** 4 - 12 * x ** 3 + 11 * x ** 2 - 2 * x + 1
  6.  
  7.  
  8. def f_1(x):
  9.     return -25 * x ** 4 + 16 * x ** 3 - 36 * x ** 2 + 22 * x - 2
  10.  
  11.  
  12. def o1(x):
  13.     return f1(x), f_1(x)
  14.  
  15.  
  16. def f2(x):
  17.     return -np.log(x - 2) ** 2 + np.log(10 - x) ** 2 - x ** 0.2
  18.  
  19.  
  20. def f_2(x):
  21.     return -0.2 / x ** 0.8 - 2 * np.log(10 - x) / (10 - x) - 2 * np.log(x - 2) / (x - 2)
  22.  
  23.  
  24. def o2(x):
  25.     return f2(x), f_2(x)
  26.  
  27.  
  28. def f3(x):
  29.     return -3 * x * np.sin(0.75 * x) + np.exp(-2 * x)
  30.  
  31.  
  32. def f_3(x):
  33.     return -2 * np.exp(-2 * x) - 3*np.sin(x * 0.75) - 9./4 * x * np.cos(x * 0.75)
  34.  
  35.  
  36. def o3(x):
  37.     return f3(x), f_3(x)
  38.  
  39.  
  40. def f4(x):
  41.     return np.exp(3 * x) + 5 * np.exp(-2 * x)
  42.  
  43.  
  44. def f_4(x):
  45.     return 3 * np.exp(3 * x) - 10 * np.exp(-2 * x)
  46.  
  47.  
  48. def o4(x):
  49.     return f4(x), f_4(x)
  50.  
  51.  
  52. def f5(x):
  53.     return 0.2 * x * np.log(x) + (x - 2.3) ** 2
  54.  
  55.  
  56. def f_5(x):
  57.     return 0.2 * np.log(x) + 0.2 + 2 * (x - 2.3)
  58.  
  59.  
  60. def o5(x):
  61.     return f5(x), f_5(x)
  62.  
  63.  
  64. def min_golden(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
  65.     hist = {'x': [], 'f': [], 'n_evals': []}
  66.     K = (5 ** 0.5 - 1) / 2
  67.     I = np.zeros(max_iter + 2)
  68.     I[0] = b - a
  69.     I[1] = K * I[0]
  70.     x_2, x_1 = a + I[1], b - I[1]
  71.     f_1, f_2 = func(x_1), func(x_2)
  72.     hist['n_evals'].append(2)
  73.     for i in range(1, max_iter + 1):
  74.         I[i + 1] = K * I[i]
  75.         if f_1 >= f_2:
  76.             if disp:
  77.                 print("{0} iteration, interval's length = {1}, function's min = {2}".format(*(i, I[i], f_2)))
  78.             hist['x'].append(x_2)
  79.             hist['f'].append(f_2)
  80.             a, x_1 = x_1, x_2
  81.             x_2 = a + I[i + 1]
  82.             f_1, f_2 = f_2, func(x_2)
  83.             hist['n_evals'].append(hist['n_evals'][-1] + 1)
  84.         else:
  85.             if disp:
  86.                 print("{0} iteration, interval's length = {1}, function's min = {2}".format(*(i, I[i], f_1)))
  87.             hist['x'].append(x_1)
  88.             hist['f'].append(f_1)
  89.             x_2, b = x_1, x_2
  90.             x_1 = b - I[i + 1]
  91.             f_1, f_2 = func(x_1), f_1
  92.             hist['n_evals'].append(hist['n_evals'][-1] + 1)
  93.         if I[i + 1] < tol:
  94.             return get_result(hist, 0, trace)
  95.     return get_result(hist, 1, trace)
  96.  
  97.  
  98. def min_parabolic(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
  99.     hist = {'x': [], 'f': [], 'n_evals': []}
  100.     x1, x2, x3 = a, (a + b) / 2., b
  101.     f1, f2, f3 = func(x1), func(x2), func(x3)
  102.     hist['n_evals'].append(3)
  103.     I = np.zeros(max_iter + 2)
  104.     I[0] = x3 - x1
  105.     for i in range(1, max_iter + 1):
  106.         num, den = get_min_parabolas(f1, f2, f3, x1, x2, x3)
  107.         if abs(den) > 0:
  108.             u = x2 - num / den
  109.         else:
  110.             return get_result(hist, 0, trace)
  111.         f_u = func(u)
  112.         hist['n_evals'].append(hist['n_evals'][-1] + 1)
  113.         if f2 <= f_u:
  114.             if x2 < u:
  115.                 x3, f3 = u, f_u
  116.             else:
  117.                 x1, f1 = u, f_u
  118.             hist['x'].append(x2)
  119.             hist['f'].append(f2)
  120.         else:
  121.             if x2 < u:
  122.                 x1, x2 = x2, u
  123.                 f1, f2 = f2, f_u
  124.             else:
  125.                 x2, f2, x3, f3 = u, f_u, x2, f2
  126.             hist['x'].append(u)
  127.             hist['f'].append(f_u)
  128.         I[i] = x3 - x1
  129.         if disp:
  130.             print("{0} iteration, interval's length = {1}, function's min = {2}".format(*(i, I[i], hist['f'][-1])))
  131.         if I[i] < tol:
  132.             return get_result(hist, 0, trace)
  133.     return get_result(hist, 1, trace)
  134.  
  135.  
  136. def get_min_parabolas(f1, f2, f3, x1, x2, x3):
  137.     num = (x2 - x1) ** 2 * (f2 - f3) - (x2 - x3) ** 2 * (f2 - f1)
  138.     den = 2 * (x2 - x1) * (f2 - f3) - 2 * (x2 - x3) * (f2 - f1)
  139.  
  140.     return num, den
  141.  
  142.  
  143. def check_for_inequal(v, x, w, tol):
  144.     return abs(v - x) > tol and abs(x - w) > tol and abs(v - w) > tol
  145.  
  146.  
  147. def min_brent(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
  148.     hist = {'x': [], 'f': [], 'n_evals': []}
  149.     a, c = a, b
  150.     K = (3 - 5 ** 0.5) / 2
  151.     x = w = v = a + K * (c - a)
  152.     fx = fw = fv = func(x)
  153.     hist['n_evals'].append(1)
  154.     d = e = c - a
  155.     I = np.zeros(max_iter + 2)
  156.     I[0] = c - a
  157.     u = 0
  158.     for i in range(max_iter):
  159.         g, e = e, d
  160.         t = tol * abs(x) + tol / 10.
  161.         if abs(x - (a + c) / 2) + (c - a) / 2 <= 2 * tol:
  162.             return get_result(hist, 0, trace)
  163.         parabolic_flag = True
  164.         num, den = get_min_parabolas(fv, fx, fw, v, x, w)
  165.         if abs(den) > 0 and check_for_inequal(v, x, w, tol) and check_for_inequal(fx, fv, fw, tol)\
  166.                 and a <= x + num / den <= c and abs(num / den) < g / 2.:
  167.             u = x - num / den
  168.             if u - a < 2 * t or c - u < 2 * t:
  169.                 u = x - np.sign(x - (a + c) / 2) * t
  170.         else:
  171.             parabolic_flag = False
  172.         if not parabolic_flag:
  173.             if x < (a + c) / 2:
  174.                 u = x + K * (c - x)
  175.                 e = c - x
  176.             else:
  177.                 u = x - K * (x - a)
  178.                 e = x - a
  179.         if abs(x - u) < t * 10 ** -5:
  180.             u = x + np.sign(u - x) * t
  181.         d = abs(u - x)
  182.         fu = func(u)
  183.         hist['n_evals'].append(hist['n_evals'][-1] + 1)
  184.         if fu <= fx:
  185.             if u >= x:
  186.                 a = x
  187.             else:
  188.                 c = x
  189.             v, w, x, fv, fw, fx = w, x, u, fw, fx, fu
  190.         else:
  191.             if u >= x:
  192.                 c = u
  193.             else:
  194.                 a = u
  195.             if fu <= fw or abs(x - w) <= 10 ** -10:
  196.                 v, w, fv, fw = w, u, fw, fu
  197.             elif fu <= fv or abs(v - x) <= 10 ** -10 or abs(v - w) <= 10 ** -10:
  198.                 v, fv = u, fu
  199.         hist['x'].append(x)
  200.         hist['f'].append(fx)
  201.         if disp:
  202.             if parabolic_flag:
  203.                 print("{0} iteration, interval's length = {1}, function's min = {2}, parabolic".format(*(i + 1, I[i], hist['f'][-1])))
  204.             else:
  205.                 print("{0} iteration, interval's length = {1}, function's min = {2}, golden".format(*(i + 1, I[i], hist['f'][-1])))
  206.         I[i + 1] = c - a
  207.     return get_result(hist, 1, trace)
  208.  
  209.  
  210. def get_min_parabolas_der(f_1, f_2, x1, x2):
  211.     a = (f_1 - f_2) / 2. / (x1 - x2)
  212.     b = (f_1 * x2 - f_2 * x1) / (x2 - x1)
  213.     return -b / 2. / a
  214.  
  215.  
  216. def min_brent_der(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
  217.     hist = {'x': [], 'f': [], 'n_evals': []}
  218.     a, c = a, b
  219.     x = w = v = (a + c) / 2
  220.     fx, f_x = func(x)
  221.     fw, fv, f_w, f_v = fx, fx, f_x, f_x
  222.     hist['n_evals'].append(1)
  223.     d = e = c - a
  224.     I = np.zeros(max_iter + 2)
  225.     I[0] = c - a
  226.     for i in range(1, max_iter + 1):
  227.         g, e, = e, d
  228.         if abs(x - (a + c) / 2) + (c - a) / 2 <= 2 * (tol * abs(x) + tol / 10.):
  229.             return get_result(hist, 0, trace)
  230.         flag1 = flag2 = False
  231.         if abs(x - w) > tol and abs(f_x - f_w) > tol:
  232.             u1 = get_min_parabolas_der(f_x, f_w, x, w)
  233.             if a <= u1 <= c and (u1 - x) * f_x <= 0 and abs(u1 - x) < g / 2.:
  234.                 flag1 = True
  235.         if abs(x - v) > tol and abs(f_x - f_v) > tol:
  236.             u2 = get_min_parabolas_der(f_x, f_v, x, v)
  237.             if a <= u2 <= c and (u2 - x) * f_x <= 0 and abs(u2 - x) < g / 2.:
  238.                 flag2 = True
  239.         if flag1 or flag2:
  240.             if flag1 and flag2:
  241.                 if abs(u1 - x) < abs(u2 - x):
  242.                     u = u1
  243.                 else:
  244.                     u = u2
  245.             else:
  246.                 if flag1:
  247.                     u = u1
  248.                 else:
  249.                     u = u2
  250.         else:
  251.             if f_x > 0:
  252.                 u, e = (a + x) / 2., x - a
  253.             else:
  254.                 u, e = (x + c) / 2., c - x
  255.         if abs(u - x) < tol * 10 ** -5:
  256.             u = x + np.sign(u - x) * tol
  257.         d = abs(x - u)
  258.         fu, f_u = func(u)
  259.         hist['n_evals'].append(hist['n_evals'][-1] + 1)
  260.         if fu <= fx:
  261.             if u >= x:
  262.                 a = x
  263.             else:
  264.                 c = x
  265.             v, w, x, fv, fw, fx, f_v, f_w, f_x = w, x, u, fw, fx, fu, f_w, f_x, f_u
  266.         else:
  267.             if u >= x:
  268.                 c = u
  269.             else:
  270.                 a = u
  271.             if fu <= fw or abs(w - x) < tol * 10 ** -5:
  272.                 v, w, fv, fw, f_v, f_w = w, u, fw, fu, f_w, f_u
  273.             elif fu <= fv or abs(v - x) < tol * 10 ** -5 or abs(v - w) < tol * 10 ** -5:
  274.                 v, fv, f_v = u, fu, f_u
  275.         hist['x'].append(x)
  276.         hist['f'].append(fx)
  277.         if disp:
  278.             if flag1 or flag2:
  279.                 print("{0} iteration, interval's length = {1}, function's min = {2}, parabolic".format(*(i, I[i - 1], hist['f'][-1])))
  280.             else:
  281.                 print("{0} iteration, interval's length = {1}, function's min = {2}, bisection".format(*(i, I[i - 1], hist['f'][-1])))
  282.         I[i] = c - a
  283.     return get_result(hist, 1, trace)
  284.  
  285.  
  286. def get_min_cubic_der(f1, f2, f_1, f_2, x1, x2):
  287.     z = 3 * (f1 - f2) / (x2 - x1) + f_1 + f_2
  288.     if x1 < x2:
  289.         w = (z ** 2 - f_1 * f_2) ** 0.5
  290.     else:
  291.         w = -(z ** 2 - f_1 * f_2) ** 0.5
  292.     M = (f_2 + w - z) / (f_2 - f_1 + 2 * w)
  293.     if M < 0:
  294.         return x2
  295.     elif M > 1:
  296.         return x1
  297.     else:
  298.         return x2 - M * (x2 - x1)
  299.  
  300.  
  301. def min_cubic(func, a, b, tol=1e-5, max_iter=500, disp=False, trace=False):
  302.     hist = {'x': [], 'f': [], 'n_evals': []}
  303.     x1, x2 = a, b
  304.     f1, f_1 = func(x1)
  305.     f2, f_2 = func(x2)
  306.     hist['n_evals'].append(3)
  307.     I = np.zeros(max_iter + 2)
  308.     I[0] = x2 - x1
  309.     for i in range(1, max_iter + 1):
  310.         if I[i - 1] < tol:
  311.             return get_result(hist, 0, trace)
  312.         u = get_min_cubic_der(f1, f2, f_1, f_2, x1, x2)
  313.         fu, f_u = func(u)
  314.         hist['n_evals'].append(hist['n_evals'][-1] + 1)
  315.         if f_u > 0:
  316.             x2, f2, f_2 = u, fu, f_u
  317.         else:
  318.             x1, f1, f_1 = u, fu, f_u
  319.         if f1 < f2:
  320.             hist['x'].append(x1)
  321.             hist['f'].append(f1)
  322.         else:
  323.             hist['x'].append(x2)
  324.             hist['f'].append(f2)
  325.         if disp:
  326.             print("{0} iteration, interval's length = {1}, function's min = {2}".format(*(i, I[i - 1], hist['f'][-1])))
  327.         I[i] = x2 - x1
  328.         if abs(f_u) < tol:
  329.             return get_result(hist, 0, trace)
  330.     return get_result(hist, 1, trace)
  331.  
  332.  
  333. def get_result(hist, status, trace):
  334.     if trace:
  335.         return hist['x'][-1], hist['f'][-1], status, {'x': np.array(hist['x']),
  336.                                                       'f': np.array(hist['f']),
  337.                                                       'n_evals': np.array(hist['n_evals'][1:])}
  338.     else:
  339.         return hist['x'][-1], hist['f'][-1], status
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement