Loading [MathJax]/extensions/tex2jax.js
BSMPT 3.0.7
BSMPT - Beyond the Standard Model Phase Transitions : A C++ package for the computation of the EWPT in BSM models
All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends Pages
spline.h
1/*
2 * spline.h
3 *
4 * simple cubic spline interpolation library without external
5 * dependencies
6 *
7 * ---------------------------------------------------------------------
8 * Copyright (C) 2011, 2014, 2016, 2021 Tino Kluge (ttk448 at gmail.com)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 * ---------------------------------------------------------------------
23 *
24 */
25
26#ifndef TK_SPLINE_H
27#define TK_SPLINE_H
28
29#include <algorithm>
30#include <cassert>
31#include <cmath>
32#include <cstdio>
33#include <vector>
34
35namespace tk
36{
37
38// spline interpolation
39class spline
40{
41public:
42 // spline types
43 enum spline_type
44 {
45 linear = 10, // linear interpolation
46 cspline = 30, // cubic splines (classical C^2)
47 cspline_hermite = 31 // cubic hermite splines (local, only C^1)
48 };
49
50 // boundary condition type for the spline end-points
51 enum bd_type
52 {
53 first_deriv = 1,
54 second_deriv = 2,
55 not_a_knot = 3
56 };
57
58protected:
59 std::vector<double> m_x, m_y; // x,y coordinates of points
60 // interpolation parameters
61 // f(x) = a_i + b_i*(x-x_i) + c_i*(x-x_i)^2 + d_i*(x-x_i)^3
62 // where a_i = y_i, or else it won't go through grid points
63 std::vector<double> m_b, m_c, m_d; // spline coefficients
64 double m_c0; // for left extrapolation
65 spline_type m_type;
66 bd_type m_left, m_right;
67 double m_left_value, m_right_value;
68 bool m_made_monotonic;
69 void set_coeffs_from_b(); // calculate c_i, d_i from b_i
70 size_t find_closest(double x) const; // closest idx so that m_x[idx]<=x
71
72public:
73 // default constructor: set boundary condition to be zero curvature
74 // at both ends, i.e. natural splines
75 spline()
76 : m_type(cspline)
77 , m_left(second_deriv)
78 , m_right(second_deriv)
79 , m_left_value(0.0)
80 , m_right_value(0.0)
81 , m_made_monotonic(false)
82 {
83 ;
84 }
85 spline(const std::vector<double> &X,
86 const std::vector<double> &Y,
87 spline_type type = cspline,
88 bool make_monotonic = false,
89 bd_type left = second_deriv,
90 double left_value = 0.0,
91 bd_type right = second_deriv,
92 double right_value = 0.0)
93 : m_type(type)
94 , m_left(left)
95 , m_right(right)
96 , m_left_value(left_value)
97 , m_right_value(right_value)
98 , m_made_monotonic(false) // false correct here: make_monotonic() sets it
99 {
100 this->set_points(X, Y, m_type);
101 if (make_monotonic)
102 {
103 this->make_monotonic();
104 }
105 }
106
107 // modify boundary conditions: if called it must be before set_points()
108 void set_boundary(bd_type left,
109 double left_value,
110 bd_type right,
111 double right_value);
112
113 // set all data points (cubic_spline=false means linear interpolation)
114 void set_points(const std::vector<double> &x,
115 const std::vector<double> &y,
116 spline_type type = cspline);
117
118 // adjust coefficients so that the spline becomes piecewise monotonic
119 // where possible
120 // this is done by adjusting slopes at grid points by a non-negative
121 // factor and this will break C^2
122 // this can also break boundary conditions if adjustments need to
123 // be made at the boundary points
124 // returns false if no adjustments have been made, true otherwise
125 bool make_monotonic();
126
127 // evaluates the spline at point x
128 double operator()(double x) const;
129 double deriv(int order, double x) const;
130
131 // solves for all x so that: spline(x) = y
132 std::vector<double> solve(double y, bool ignore_extrapolation = true) const;
133
134 // returns the input data points
135 std::vector<double> get_x() const { return m_x; }
136 std::vector<double> get_y() const { return m_y; }
137 double get_x_min() const
138 {
139 assert(!m_x.empty());
140 return m_x.front();
141 }
142 double get_x_max() const
143 {
144 assert(!m_x.empty());
145 return m_x.back();
146 }
147};
148
149namespace internal
150{
151
152// band matrix solver
154{
155private:
156 std::vector<std::vector<double>> m_upper; // upper band
157 std::vector<std::vector<double>> m_lower; // lower band
158public:
159 band_matrix(){}; // constructor
160 band_matrix(int dim, int n_u, int n_l); // constructor
161 ~band_matrix(){}; // destructor
162 void resize(int dim, int n_u, int n_l); // init with dim,n_u,n_l
163 int dim() const; // matrix dimension
164 int num_upper() const { return (int)m_upper.size() - 1; }
165 int num_lower() const { return (int)m_lower.size() - 1; }
166 // access operator
167 double &operator()(int i, int j); // write
168 double operator()(int i, int j) const; // read
169 // we can store an additional diagonal (in m_lower)
170 double &saved_diag(int i);
171 double saved_diag(int i) const;
172 void lu_decompose();
173 std::vector<double> r_solve(const std::vector<double> &b) const;
174 std::vector<double> l_solve(const std::vector<double> &b) const;
175 std::vector<double> lu_solve(const std::vector<double> &b,
176 bool is_lu_decomposed = false);
177};
178
179double get_eps();
180
181// solutions for a + b*x = 0
182std::vector<double> solve_linear(double a, double b);
183
184// solutions for a + b*x + c*x^2 = 0
185std::vector<double>
186solve_quadratic(double a, double b, double c, int newton_iter = 0);
187
188// solutions for the cubic equation: a + b*x +c*x^2 + d*x^3 = 0=
189std::vector<double>
190solve_cubic(double a, double b, double c, double d, int newton_iter = 0);
191
192} // namespace internal
193
194} // namespace tk
195
196#endif /* TK_SPLINE_H */
Definition spline.h:154
Definition spline.h:40