Line data Source code
1 0 : // Distributed under the MIT License.
2 : // See LICENSE.txt for details.
3 :
4 : #pragma once
5 :
6 : #include <deque>
7 : #include <vector>
8 :
9 : #include "DataStructures/DataVector.hpp"
10 :
11 : namespace intrp {
12 :
13 : /*!
14 : * \brief Predicts the zero crossing of a function.
15 : *
16 : * Fits a linear function to a set of y_values at different x_values
17 : * and uses the fit to predict what x_value the y_value zero will be crossed.
18 : *
19 : * predicted_zero_crossing treats x=0 in a special way: All of the
20 : * x_values must be non-positive; one of the x_values is typically (but
21 : * is not required to be) zero. In typical usage, x is time, and x=0
22 : * is the current time, and we are interested in whether the function
23 : * crosses zero in the past or in the future. If it cannot be
24 : * determined (within the error bars of the fit) whether the zero
25 : * crossing occurs for x < 0 versus x > 0, then we return zero.
26 : * Otherwise we return the best-fit x for when the function crosses
27 : * zero.
28 : *
29 : * \details We fit to a straight line: y = intercept + slope*x.
30 : * So our best guess is that the function will cross zero at
31 : * x_best_fit = -intercept/slope.
32 : *
33 : * However, the data are assumed to be noisy. The fit gives us error
34 : * bars for the slope and the intercept. Given the error bars, we can
35 : * compute four limiting crossing values x0, x1, x2, and x3 by using
36 : * the maximum and minimum possible values of slope and intercept.
37 : * For example, if we assume slope<0 and intercept>0, then the
38 : * earliest possible crossing consistent with the error bars is
39 : * x3=(-intercept+delta_intercept)/(slope-delta_slope) and the latest
40 : * possible crossing consistent with the error bars is
41 : * x0=(-intercept-delta_intercept)/(slope+delta_slope).
42 : *
43 : * We compute all four crossing values and demand that all of them
44 : * are either at x>0 (i.e. in the future if x is time) or at x<0
45 : * (i.e. in the past if x is time). Otherwise we conclude that we
46 : * cannot determine even the sign of the crossing value, so we return
47 : * zero.
48 : */
49 1 : double predicted_zero_crossing_value(const std::vector<double>& x_values,
50 : const std::vector<double>& y_values);
51 :
52 : /*!
53 : * \brief Predicts the zero crossing of multiple functions.
54 : *
55 : * For the ith element of the DataVector inside y_values, calls
56 : * predicted_zero_crossing_value(x_values,y_values[:][i]), where we
57 : * have used python-like notation.
58 : */
59 1 : DataVector predicted_zero_crossing_value(
60 : const std::deque<double>& x_values, const std::deque<DataVector>& y_values);
61 :
62 : } // namespace intrp
|