Метод покоординатного спуска и метод градиентного спуска с фиксированным шагом

 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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
-module(lab1).
-import(math, [pow/2]).
-export([start/2]).
f(X,Y) -> K = 4, pow(X,4) + 2*K*pow(X,3) - K*K*X*X - 2*pow(K,3)*X + pow(Y,4) - Y*Y*(2*K*K + 2*K) + 2*pow(K,4) + K*K*K + K*K.
f({x,X}) -> fun(Y) -> f(X,Y) end;
f({y,Y}) -> fun(X) -> f(X,Y) end.
f() -> fun(X,Y) -> f(X,Y) end.
gf(X,Y) -> K = 4, [4*pow(X,3) + 2*K*pow(X,2) - 2*K*K*X - 2*pow(K,3),4*pow(Y,3) - 4*K*K*Y - 4*K*Y].
mps_search(F,Point,Step) ->
This = F(Point),
Next = F(Point+Step),
if
This > Next -> mps_search(F,Point+Step,Step);
true -> Point
end.
mps(F,Point,Step) ->
C = F(Point),
L = F(Point-Step),
R = F(Point+Step),
if
L < R -> mps_search(F,Point,Step*(-1));
L > R -> mps_search(F,Point,Step);
L == R andalso C > R -> mps_search(F,Point,Step);
L == R andalso C < R -> Point
end.
result({startpoint,X,Y}) ->
New_x = mps(f({y,Y}),X,0.0001),
New_y = mps(f({x,New_x}),Y,0.0001),
Sqrt = math:sqrt(pow(X-New_x,2)+pow(Y-New_y,2)),
if
Sqrt < 0.00000001 ->
io:format("x = ~w, y = ~w, F = ~w~n",[New_x,New_y,f(New_x,New_y)]);
true ->
io:format("x = ~w, y = ~w, F = ~w~n",[New_x,New_y,f(New_x,New_y)]),
result({startpoint,New_x,New_y})
end.
gs(F,X,Y,Alfa,Step,Alfa_first,Prev_x,Prev_y) ->
This = F(X,Y),
Next = F(X+Step*math:cos(Alfa),Y+Step*math:sin(Alfa)),
if
This > Next -> gs(F,X+Step*math:cos(Alfa),Y+Step*math:sin(Alfa),Alfa,Step,Alfa_first,X,Y);
true ->
if
[Prev_x,Prev_y] == [X,Y] ->
G1 = abs(Alfa)-math:pi(),
G2 = abs(Alfa_first),
if
G1 > G2 -> [X,Y];
true -> gs(F,X,Y,Alfa+math:pi()/2,Step,Alfa_first,X,Y)
end;
true -> [X,Y]
end
end.
get_alfa(X,Y) ->
if
(X > 0 andalso Y > 0) orelse (X > 0 andalso Y < 0) -> math:atan(Y/X);
true -> math:atan(Y/X) + math:pi()
end.
result_gs({startpoint,X,Y}) ->
[Gx,Gy] = lists:map(fun(A) -> -1*A end,gf(X,Y)),
Alfa = get_alfa(Gx,Gy),
[New_x,New_y] = gs(f(),X,Y,Alfa,0.0001,Alfa,X,Y),
Sqrt = math:sqrt(pow(New_x-X,2)+pow(New_y-Y,2)),
if
Sqrt < 0.000001 ->
io:format("x = ~w, y = ~w, F = ~w~n",[New_x,New_y,f(New_x,New_y)]);
true ->
io:format("x = ~w, y = ~w, F = ~w~n",[New_x,New_y,f(New_x,New_y)]),
result_gs({startpoint,New_x,New_y})
end.
start(X,Y) ->
io:format("**************MGS****************~n",[]),
result_gs({startpoint,X,Y}),
io:format("**************MPS****************~n",[]),
result({startpoint,X,Y}).