Hyperiso 1.0.3
Modular flavour-physics calculations, Wilson coefficients and statistical inference
Loading...
Searching...
No Matches
diffcalc.cpp
Go to the documentation of this file.
1#include "diffcalc.h"
2
3std::vector<double> gradient(const RealValuedForm& f, const std::vector<double>& x, const std::vector<double>& scales) {
4 ScaledForm f_scaled(f, x, scales);
5 std::vector<double> g = gradient(f_scaled, std::vector<double>(x.size(), 0.0));
6
7 for (size_t i = 0; i < g.size(); i++)
8 g[i] /= f_scaled.s[i];
9
10 return g;
11}
12
13std::vector<double> gradient(const ScaledForm &f, const std::vector<double> &t) {
14 std::vector<double> grad = std::vector(t.size(), 0.0);
15
16 double eps = std::numeric_limits<double>::epsilon();
17 double h = std::cbrt(eps);
18 for (size_t i = 0; i < t.size(); i++) {
19 auto t_p = std::vector(t);
20 auto t_m = std::vector(t);
21 t_p[i] += h;
22 t_m[i] -= h;
23 grad[i] = (f(t_p) - f(t_m)) / (2 * h);
24 }
25
26 return grad;
27}
28
29RealMatrix hessian(const RealValuedForm& f, const std::vector<double>& x, const std::vector<double>& scales) {
30 ScaledForm f_scaled(f, x, scales);
31 RealMatrix H = hessian(f_scaled, std::vector<double>(x.size(), 0.0));
32
33 for (size_t i = 0; i < H.rows(); i++)
34 for (size_t j = 0; j < H.cols(); j++)
35 H.at(i, j) /= (f_scaled.s[i] * f_scaled.s[j]);
36
37 return H;
38}
39
40RealMatrix hessian(const ScaledForm& f, const std::vector<double>& t) {
41 size_t dim = t.size();
42 RealMatrix H (dim, dim);
43
44 double eps = std::numeric_limits<double>::epsilon();
45 double h = std::pow(eps, 0.25);
46 const double ft = f(t);
47 std::vector<double> t_shift;
48 std::vector<std::pair<int, int>> signs = {{1, 1}, {1, -1}, {-1, 1}, {-1, -1}};
49 for (size_t i = 0; i < dim; i++) {
50 double Hii = 0;
51 for (int sign : {-1, 1}) {
52 t_shift = t;
53 t_shift[i] += sign * h;
54 // for (double t : t_shift) std::cout << t << " ";
55 // std::cout << std::endl;
56 Hii += f(t_shift);
57 }
58 Hii = (Hii - 2 * ft) / std::pow(h, 2);
59
60 if (!std::isfinite(Hii))
61 throw std::runtime_error("Invalid value found in hessian");
62
63 H.at(i, i) = Hii;
64
65 for (size_t j = i + 1; j < dim; j++) {
66 double Hij = 0;
67 for (auto& ss : signs) {
68 t_shift = t;
69 t_shift[i] += ss.first * h;
70 t_shift[j] += ss.second * h;
71 // for (double t : t_shift) std::cout << t << " ";
72 // std::cout << std::endl;
73 // std::cout << f(t_shift) << std::endl;
74 Hij += ss.first * ss.second * f(t_shift);
75 }
76
77 Hij /= 4 * h * h;
78
79 if (!std::isfinite(Hij))
80 throw std::runtime_error("Invalid value found in hessian");
81
82 H.at(i, j) = Hij;
83 H.at(j, i) = Hij;
84 }
85 }
86
87 return 0.5 * (H + H.transpose());
88}
89
90RealMatrix inverse_hessian(const RealValuedForm& f, const std::vector<double>& x, const std::vector<double>& scales) {
91 ScaledForm f_scaled(f, x, scales);
92 RealMatrix H = hessian(f_scaled, std::vector<double>(x.size(), 0.0));
93 RealMatrix inv_H = H.inv();
94
95 for (size_t i = 0; i < inv_H.rows(); i++)
96 for (size_t j = 0; j < inv_H.cols(); j++)
97 inv_H.at(i, j) *= f_scaled.s[i] * f_scaled.s[j];
98
99 return inv_H;
100}
std::size_t rows() const
Returns the number of rows.
Definition Matrix.cpp:601
double & at(size_t i, size_t j)
Returns a mutable reference to element (i,j) with bounds checking.
Definition Matrix.cpp:587
std::size_t cols() const
Returns the number of columns.
Definition Matrix.cpp:605
std::vector< double > gradient(const RealValuedForm &f, const std::vector< double > &x, const std::vector< double > &scales)
Definition diffcalc.cpp:3
RealMatrix hessian(const RealValuedForm &f, const std::vector< double > &x, const std::vector< double > &scales)
Definition diffcalc.cpp:29
RealMatrix inverse_hessian(const RealValuedForm &f, const std::vector< double > &x, const std::vector< double > &scales)
Definition diffcalc.cpp:90
constexpr double g
std::function< double(std::vector< double >)> RealValuedForm
Definition functions.h:11
double f(double x)
Wilson special function f depending on x.
std::vector< double > s
Definition functions.h:17