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