-
Notifications
You must be signed in to change notification settings - Fork 0
/
approximationOfRoot.cpp
137 lines (125 loc) · 8.6 KB
/
approximationOfRoot.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
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#include <math.h>
#include "vect.h"
#include <iostream>
double differenceOfAproximation( // ñàìà íàøà ôóíêöèÿ
vect<double,double>* real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double,double,double> parametrs,
vect3D<double, double, double> prev_parametrs)
{
double result = 0;
for (int i = 0; i < length; i++)
{
double Q = (1 + parametrs.b1 * real_point[i].x);
double P = (parametrs.a0 + parametrs.a1 * real_point[i].x);
double prev_Q = (1 + prev_parametrs.b1 * real_point[i].x);
result += ((real_point[i].y * Q - P) / prev_Q) * ((real_point[i].y * Q - P) / prev_Q);
}
return result;
}
double differenceOfAproximation1D( // îäíîìåðíîå âûðàæåíèå äëÿ íàøåé ôóíêöèè
vect<double, double> * real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double, double, double> parametrs,
vect3D<double, double, double> prev_parametrs,
vect3D<double, double, double> grad,
double lambda) // òî÷êà
{
return (differenceOfAproximation(real_point, length, parametrs + lambda * grad, prev_parametrs));
}
vect3D<double, double, double> gradFunc(
double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>),
vect<double, double>* real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double, double, double> parametrs, // òî÷êà â êîòîðîé èùåòñÿ ãðàäèåíò
vect3D<double, double, double> prev_parametrs
)
{
const double delta = 0.0002;
double x = (p_func(real_point, length, parametrs + delta * vect3D<double, double, double>{1, 0, 0}, prev_parametrs) - p_func(real_point, length, parametrs - delta * vect3D<double, double, double>{1, 0, 0}, prev_parametrs)) / (2 * delta);
double y = (p_func(real_point, length, parametrs + delta * vect3D<double, double, double>{0, 1, 0}, prev_parametrs) - p_func(real_point, length, parametrs - delta * vect3D<double, double, double>{0, 1, 0}, prev_parametrs)) / (2 * delta);
double z = (p_func(real_point, length, parametrs + delta * vect3D<double, double, double>{0, 0, 1}, prev_parametrs) - p_func(real_point, length, parametrs - delta * vect3D<double, double, double>{0, 0, 1}, prev_parametrs)) / (2 * delta);
return{x,y,z};
}
double derivative1D(
double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),
vect<double, double>* real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double, double, double> parametrs,
vect3D<double, double, double> prev_parametrs,
vect3D<double, double, double> grad,
double lambda) // òî÷êà â êîòîðîé èùåì ïðîèçâîäíóþ
{
const double delta = 0.0002;
return ((p_func(real_point, length, parametrs, prev_parametrs, grad, lambda + delta) - p_func(real_point, length, parametrs, prev_parametrs, grad, lambda - delta)) / (2 * delta));
}
double secondDerivative1D(
double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),
vect<double, double>* real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double, double, double> parametrs,
vect3D<double, double, double> prev_parametrs,
vect3D<double, double, double> grad,
double lambda) // òî÷êà â êîòîðîé èùåì ïðîèçâîäíóþ)
{
const double delta = 0.0002;
return ((p_func(real_point, length, parametrs, prev_parametrs, grad, lambda + delta) + p_func(real_point, length, parametrs, prev_parametrs, grad, lambda - delta) - 2 * p_func(real_point, length, parametrs, prev_parametrs, grad, lambda)) / (delta * delta));
}
double parabolaMin(
double (*p_func_frst_derv)(double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double), vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),
double (*p_func_secnd_derv)(double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double), vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),
double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),
vect<double, double>* real_point, // òî÷êè ïî êîòîðûì àïïðîêñèìèðóåì (ïåðâàÿ êîîðäèíàòà - ïàðàìåòð, âòîðàÿ - çíà÷åíèÿ êîðíÿ ïðè ýòîì ïàðàìåòðå)
int length, // äëèíà ìàññèâà real_point
vect3D<double, double, double> parametrs,
vect3D<double, double, double> prev_parametrs,
vect3D<double, double, double> grad,
double lambda,
double prev_lambda)
{
double scnd_derv = p_func_secnd_derv(p_func,real_point, length, parametrs, prev_parametrs, grad, lambda);
return(prev_lambda - p_func_frst_derv(p_func ,real_point,length,parametrs,prev_parametrs,grad,lambda) / (scnd_derv*sgn(scnd_derv)) );
}
vect3D<double, double, double> approximationOfRoot(vect<double, double>* real_point, int length) {
double (*p_diff_aprox)(vect<double, double>*, int, vect3D<double,double,double>, vect3D<double, double, double>) = differenceOfAproximation; // óêàçàòåëü íà ôóíêöèþ ðàçíîñòè àïðîêñèìàöèè è ðåàëüíûõ òî÷åê
double (*p_diff_aprox_1D)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>,double) = differenceOfAproximation1D; // óêàçàòåëü íà ôóíêöèè ðàçíîñòè àïðîêñèìàöèè è ðåàëüíûõ òî÷åê ÷åðåç ãðàäèåíò è ëÿìáäà
double (*p_frst_derv_1D)(double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double) = derivative1D;
double (*p_scnd_derv_1D)(double (*p_func)(vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double),vect<double, double>*, int, vect3D<double, double, double>, vect3D<double, double, double>, vect3D<double, double, double>, double) = secondDerivative1D;
double const h =0.0001; // à åñòü ëîãèêà âûáîðà h?
vect3D<double, double, double> prev_r = {0.2,0.2,0.2};
vect3D<double, double, double> prev_r_1 = { 0,0,0 };
vect3D<double, double, double> prev_r_2 = { 0,0,0 };
vect3D<double, double,double> r_1 = { 0,0,0 };
vect3D<double, double,double> r_2 = { 0,0,0 };
// êîä ïðÿìî êîïèðêà èç âòîðîãî çàäàíèÿ ñ ó÷¸òîì ìíîãîìåðíîñòè, ëîãèêó íå ìåíÿë!
double prev_lambda = 0;
double lambda = 0;
vect3D<double, double,double> grad = gradFunc(p_diff_aprox,real_point,length,prev_r,prev_r)/modulVect3D(gradFunc(p_diff_aprox, real_point, length, prev_r, prev_r));
do
{
prev_lambda = lambda;
lambda = parabolaMin(p_frst_derv_1D,p_scnd_derv_1D, p_diff_aprox_1D,real_point,length,r_1, prev_r,grad, lambda, prev_lambda);
} while (p_diff_aprox_1D(real_point,length,prev_r, prev_r, grad, prev_lambda) > p_diff_aprox_1D(real_point, length, prev_r,prev_r, grad, lambda));
prev_r_2 = r_2;
r_2 = prev_r + prev_lambda * grad;
prev_r = 3 * h * prev_r;
do
{
prev_r_1 = prev_r_2;
r_1 = r_2;
prev_lambda = 0;
lambda = 0;
grad = gradFunc(p_diff_aprox, real_point, length, prev_r, prev_r) / modulVect3D(gradFunc(p_diff_aprox, real_point, length, prev_r, prev_r));
do
{
prev_lambda = lambda;
lambda = parabolaMin(p_frst_derv_1D, p_scnd_derv_1D, p_diff_aprox_1D, real_point, length, r_1, prev_r, grad, lambda, prev_lambda);
} while (p_diff_aprox_1D(real_point, length, prev_r, prev_r, grad, prev_lambda) > p_diff_aprox_1D(real_point, length, prev_r, prev_r, grad, lambda));
prev_r_2 = r_2;
r_2 = prev_r + prev_lambda * grad;
prev_r = r_2 + h * (r_2 - r_1) * sgn(p_diff_aprox(real_point,length,r_1,prev_r_1) - p_diff_aprox(real_point, length, r_2, prev_r_2));
} while ((p_diff_aprox(real_point, length, r_1, prev_r_1) > p_diff_aprox(real_point, length, r_2, prev_r_2)));
// êñòàòè ctrl+c & ctrl+v èç âòîðîé çàäà÷êè, ÿ òóò ïîäóìàë ÷òî ìîäóëü âòîðîé ïðîèçâîäíîé äëÿ ìèíèìóìà ïîðàáîëû èñïîëüçóåòñÿ æå òîëüêî â îäíîìåðå, òàê ÷òî íîðìàëüíûé âàðèàíò!
std::cout << p_diff_aprox(real_point, length, r_1, prev_r_1)<< '\n';
return{ r_1};
}