-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmin2D.cpp
90 lines (73 loc) · 3.26 KB
/
min2D.cpp
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
84
85
86
87
88
89
90
#include "vect.h"
#include <iostream>
#include <math.h>
double f(vect<double, double> r) { // ôóíêöèÿ ìèíèìóì êîòîðîé èùåì
double x = r.x;
double y = r.y;
return ((x * y - (cos(x)/ sin(x))) * (x * y - 1.0 / tan(x)) + sin(x * y) * sin(x * y));
}
double f1D(vect<double, double> r0, double lambda, vect<double, double> grad) { // ôóíêöèÿ íà ëèíèè ãðàäèåíòà
double x = r0.x + lambda * grad.x;
double y = r0.y + lambda * grad.y;
return ((x * y - 1.0 / tan(x)) * (x * y - 1.0 / tan(x)) + sin(x * y) * sin(x * y));
}
double derivative( // ïîèñê ïåðâîé ïðîèçâîäíîé ïî ëÿìáäà
double (*func)(vect<double, double>, double, vect<double, double>),
vect<double, double> r,
double lambda, vect<double,
double> grad)
{
double const delta = 0.0002;
return ((func( r,lambda + delta, grad) - func(r, lambda - delta, grad)) / (2 * delta));
}
double secondDerivative( // âòîðàÿ ïðîèçâîäíàÿ ïî ëÿìáäà
double (*func)(vect<double, double>, double, vect<double, double>),
vect<double, double> r,
double lambda,
vect<double, double> grad)
{
double const delta = 0.0002;
return ( ( func(r, lambda + delta, grad) + func(r, lambda - delta, grad) - 2.0*func(r, lambda, grad)) / (delta * delta) );
}
vect<double, double> gradFunc(double (*func)(vect<double, double>), vect<double, double> r) { // ïîèñê ãðàäèåíòà ôóíêöèè â òî÷êå
double const delta = 0.0002;
double x = (f({ r.x + delta,r.y }) - f({ r.x - delta,r.y })) / (2 * delta);
double y = (f({ r.x ,r.y + delta }) - f({ r.x ,r.y - delta })) / (2 * delta);
return { x, y };
}
double parabolaMin(double (*func)(vect<double, double>, double, vect<double, double>), vect<double, double> r, double prev_lambda, vect<double, double> grad) {
double scnd_derv = secondDerivative(func, r, prev_lambda, grad);
return (prev_lambda - derivative(func,r,prev_lambda,grad)/(scnd_derv*sgn(scnd_derv)));
}
vect<double, double> min2D(vect<double, double> r0) {
double const h = 0.14; // à åñòü ëîãèêà âûáîðà h?
vect<double, double> prev_r = r0; // ìåòîäîì ïðèñòàëüíîãî âãëÿäûâàíèÿ íàäî âûáèðàòü ïî ðàçíûå ñòîðîíû îò 0, íàïðèìåð (1,1); (-1,-1)
vect<double, double> r_1 = { 0,0 };
vect<double, double> r_2 = { 0,0 };
double prev_lambda = 0;
double lambda = 0;
vect<double, double> grad = gradFunc(f,prev_r)/ modulVect(gradFunc(f, prev_r));
do
{
prev_lambda = lambda;
lambda = parabolaMin(f1D, prev_r, prev_lambda, grad);
} while (f1D(prev_r,prev_lambda, grad) > f1D(prev_r, lambda, grad));
r_2 = prev_r + prev_lambda * grad;
// îáîæàþ àëãîðèòìû òàêèå, êñòàòè, èíòåðåñíî ñêîëüêî ÿ áóäó ýòî ôèêñèòü è èñêàòü áàãè?))) (áàãîâ íå áûëî, åñëè âàì èíòåðåñíî)
prev_r = 4*h * prev_r;
do
{
r_1 = r_2;
prev_lambda = 0;
lambda = 0;
grad = gradFunc(f, prev_r) / modulVect(gradFunc(f, prev_r));
do
{
prev_lambda = lambda;
lambda = parabolaMin(f1D, prev_r, prev_lambda, grad);
} while (f1D(prev_r, prev_lambda, grad) > f1D(prev_r, lambda, grad));
r_2 = prev_r + prev_lambda * grad;
prev_r = r_2 + h * (r_2 - r_1) * sgn(f(r_1) - f(r_2));
} while (f(r_1) > f(r_2));
return(r_1);
}