forked from gymrek-lab/HipSTR
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmathops.cpp
106 lines (89 loc) · 2.83 KB
/
mathops.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
#include <algorithm>
#include <assert.h>
#include <math.h>
#include "mathops.h"
#include "fastonebigheader.h"
const double LOG_ONE_HALF = log(0.5);
const double TOLERANCE = 1e-10;
const double LOG_E_BASE_10 = 0.4342944819;
double INT_LOGS[10000];
void precompute_integer_logs(){
INT_LOGS[0] = -1000;
for (unsigned int i = 1; i < 10000; i++)
INT_LOGS[i] = log(i);
}
double int_log(int val){ return INT_LOGS[val]; }
double sum(const double* begin, const double* end){
double total = 0.0;
for (const double* iter = begin; iter != end; iter++)
total += *iter;
return total;
}
double sum(const std::vector<double>& vals){
double total = 0.0;
for (auto iter = vals.begin(); iter != vals.end(); iter++)
total += *iter;
return total;
}
int sum(const std::vector<bool>& vals){
int total = 0;
for (auto iter = vals.begin(); iter != vals.end(); iter++)
total += *iter;
return total;
}
double log_sum_exp(const double* begin, const double* end){
double max_val = *std::max_element(begin, end);
double total = 0.0;
for (const double* iter = begin; iter != end; iter++)
total += exp(*iter - max_val);
return max_val + log(total);
}
double log_sum_exp(double log_v1, double log_v2){
if (log_v1 > log_v2)
return log_v1 + log(1 + exp(log_v2-log_v1));
else
return log_v2 + log(1 + exp(log_v1-log_v2));
}
double log_sum_exp(double log_v1, double log_v2, double log_v3){
double max_val = std::max(std::max(log_v1, log_v2), log_v3);
return max_val + log(exp(log_v1-max_val) + exp(log_v2-max_val) + exp(log_v3-max_val));
}
double log_sum_exp(const std::vector<double>& log_vals){
double max_val = *std::max_element(log_vals.begin(), log_vals.end());
double total = 0;
for (auto iter = log_vals.begin(); iter != log_vals.end(); iter++)
total += exp(*iter - max_val);
return max_val + log(total);
}
void update_streaming_log_sum_exp(double log_val, double& max_val, double& total){
if (log_val <= max_val)
total += exp(log_val - max_val);
else {
total *= exp(max_val-log_val);
total += 1.0;
max_val = log_val;
}
}
double finish_streaming_log_sum_exp(double max_val, double total){
return max_val + log(total);
}
double fast_log_sum_exp(double log_v1, double log_v2){
if (log_v1 > log_v2){
double diff = log_v2-log_v1;
return diff < LOG_THRESH ? log_v1 : log_v1 + fastlog(1 + fastexp(diff));
}
else {
double diff = log_v1-log_v2;
return diff < LOG_THRESH ? log_v2 : log_v2 + fastlog(1 + fastexp(diff));
}
}
double fast_log_sum_exp(const std::vector<double>& log_vals){
double max_val = *std::max_element(log_vals.begin(), log_vals.end());
double total = 0;
for (auto iter = log_vals.begin(); iter != log_vals.end(); iter++){
double diff = *iter - max_val;
if (diff > LOG_THRESH)
total += fasterexp(diff);
}
return max_val + fasterlog(total);
}