-
Notifications
You must be signed in to change notification settings - Fork 1
/
corr_slide.h
120 lines (99 loc) · 5.43 KB
/
corr_slide.h
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
/*
* Author Telnov Victor, v-telnov@yandex.ru
*
*/
#ifndef CORR_SLIDE_H
#define CORR_SLIDE_H
#include <QtCore>
#include "tls.h"
struct CorrSlide {
// этот объект оптимизирует последовательный расчет
// корреляций для смежных отрезков,
// где один массив значений постояннен,
// другой сдвигается на единицу,
// и рассчитывает занчений корреляций/подобий сразу
// для нескольких отрезков разной длины.
// При расчете вектора подаются в реверсированном виде,
// что бы при сканировании от последних к первым,
// алгоритм в действительности обсчитвал от первых к последним.
// буквы обозначающие вектора данных в названиях переменных:
// вектор s (static) постоянен -
// не меняется от расчета к расчету
// вектор m (mutable) всегда смещается на один вперед.
// с учетом того, что расчитывать будет по реверсированным векторам
// то значит это будет на один назад.
// содержит длинны векторов для расчета корреляций в порядке возрастания
ArInts ar_lens;
// размерность c_lens - для наглядности
int c_lens = 0;
// вектор не изменяемых данных, устанавилвается при вызове init()
// длина его равна значению ar_lens[c_lens-1]
ArNums ar_static;
// при последнем вызове первое значение в векторе mutable
// что бы при следующем вызове это значение вычитать
double last_first_m = 0;
// считает сколько шагов сидит в расчетных узлах,
// и если превышает ХХХ то делает полный перерасчет
// для уменьшения накопления ошибки округлений
int i_step = 0;
// структуры хранящие элементы расчета
struct Calc {
int cnt = 0;
double su_s = 0;
double su_s_pow2 = 0;
double su_m = 0;
double su_m_pow2 = 0;
double div_s = 0;
double su_s_m = 0;
};
QVector<Calc> ar_calc;
QVector<Calc> ar_calc_2;
// структура, в виде которой возвращается результат расчета
struct Res {
bool fail = false; // если делитель был равен нулю
double res_koef = 0;
double res_a = 0;
double res_b = 0;
};
// типы корреляций/подобий. Те которые не корреляция, а ошибка,
// те возвращают результат как ошибка со знаком минус - что бы
// сортировать можно было так же как при использовании корреляции -
// чем больше тем лучше.
enum KindCorr {
// простая квадратичная ошибка
// sqrt( sum( (x-y)^2 ) / n )
simple_diff = 10,
// квадратичная ошибка с вычитанием средних из значений
// sqrt( sum( ( (x-sum(x)/n) - (y-sum(y)/n) )^2 ) / n )
diff_sub_mean,
// квадратичная ошибка с делением значений на среднюю - отнормированное
// sqrt( sum( (x/sum(x)/n - y/sum(y)/n)^2 ) / n )
diff_div_mean,
// квадратичная ошибка с использованием средней к вычитанию последнего значения из отрезка
// sqrt( sum( ( (x-x_last) - (y-y_last) )^2 ) / n )
diff_sub_zero,
// корреляция Пирсона
corr_Pearson,
// не используется.
without,
};
// еще вариант расчета,
enum KindDist {
// простая корреляция отрезка
simple_dist = 20,
// корреляция с увеличением веса значений более близких к прогнозируемому.
accum_dist,
};
// первый вызов - инициализируется
void init(const ArInts& ar_lens, const double* ar_s);
// а после последовательно вызываем расчет со сдвигаемым вектором mutable
void calc_next(const double* ar_m);
// и после каждого расчета calc_next можно получить множество всех доступных результатов расчетов
int count_res() const { return c_lens*2-1; }
Res get_res(KindCorr kc, int i_res);
private:
void private_calc_first(const double* ar_m);
void make_res_2();
Res get_res(KindDist kd, KindCorr kc, int i_res);
};
#endif // CORR_SLIDE_H