Метод покоординатного спуска

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import math
x0 = (10,10)
def F(x='',y=''):
k = 4
#f = lambda x,y: 100*(y-x**2)**2 + (1-x)**2 # Rozenbrok
f = lambda x,y: x**4 + 2*k*x**3 - k**2*x**2 - 2*k**3*x + y**4 - y**2*(2*k**2 + 2*k) + 2*k**4 + k**3 + k**2
if not x == '' and not y == '':
return f(x,y)
elif x == '':
return lambda x: f(x,y)
elif y == '':
return lambda y: f(x,y)
else:
return False
def gF(x,y):
return ((F(x+1,y)-F(x,y))/1,(F(x,y+1)-F(x,y))/1)
def min_func(f,point,step):
while True:
if f(point) < f(point+step):
break
point += step
return point
def search_min_of_func(f,point,step):
if f(point+step) < f(point-step):
return min_func(f,point,step)
elif f(point+step) == f(point-step):
if f(point+step) > f(point):
return point
else:
return min_func(f,point,step)
else:
return min_func(f,point,step*(-1))
x1 = [x0[0],x0[1]]
step = 0.0001
while True:
y = search_min_of_func(F(x=x1[0]),x1[1],step)
x = search_min_of_func(F(y=y),x1[0],step)
print x,y
if math.sqrt((x1[0]-x)**2+(x1[1]-y)**2) < 0.00000001:
print x,y
print F(x,y)
break
x1[0] = x
x1[1] = y