Line data Source code
1 0 : // Distributed under the MIT License. 2 : // See LICENSE.txt for details. 3 : 4 : #pragma once 5 : 6 : #include <cstddef> 7 : #include <deque> 8 : #include <optional> 9 : 10 : #include "DataStructures/DataVector.hpp" 11 : 12 : /// \cond 13 : namespace PUP { 14 : class er; 15 : } // namespace PUP 16 : /// \endcond 17 : 18 : namespace intrp { 19 : 20 : /// \ingroup NumericalAlgorithmsGroup 21 : /// \brief A class that predicts when a function crosses zero 22 1 : class ZeroCrossingPredictor { 23 : public: 24 : /// Uses at most max_size times for the fit; throws away old 25 : /// times as new times are added. 26 : /// The is_valid function returns false until min_size times 27 : /// have been added. min_size must be at least 3. 28 1 : ZeroCrossingPredictor(size_t min_size, size_t max_size); 29 : 30 0 : ZeroCrossingPredictor() = default; 31 : 32 : /// Adds a data point at time t to the ZeroCrossingPredictor. 33 1 : void add(double t, DataVector data_at_time_t); 34 : 35 : /// For each component of the data, returns the time, relative to 36 : /// current_time, that a linear fit to the given component of the 37 : /// data crosses zero. The length of the return value is the same 38 : /// as the length of `data_at_time_t` in the `add` function. 39 : /// 40 : /// The zero-crossing time that is computed has error bars 41 : /// associated with it. If the error bars are large enough that it 42 : /// is not clear whether the zero-crossing time is positive or 43 : /// negative, then zero is returned instead of the best-fit 44 : /// zero-crossing time. 45 1 : DataVector zero_crossing_time(double current_time) const; 46 : 47 : /// The minimum positive value over the DataVector returned 48 : /// by zero_crossing_time. If there is no minimum positive value (all are 49 : /// negative), returns `std::nullopt`. Also returns `std::nullopt` if 50 : /// is_valid() is false. 51 1 : std::optional<double> min_positive_zero_crossing_time( 52 : double current_time) const; 53 : 54 : /// Returns whether we have enough data to call zero_crossing_time. 55 1 : bool is_valid() const; 56 : 57 : /// Clears the internal arrays. Used to reset if there is a 58 : /// discontinuous change in the data that should not be fit over. 59 1 : void clear(); 60 : 61 : // NOLINTNEXTLINE(google-runtime-references) 62 0 : void pup(PUP::er& p); 63 : 64 0 : friend bool operator==(const ZeroCrossingPredictor&, // NOLINT 65 : const ZeroCrossingPredictor&); // NOLINT 66 : 67 : private: 68 0 : size_t min_size_{3}; 69 0 : size_t max_size_{3}; 70 0 : std::deque<double> times_{}; 71 0 : std::deque<DataVector> data_{}; 72 : }; 73 : 74 0 : bool operator!=(const ZeroCrossingPredictor&, const ZeroCrossingPredictor&); 75 : 76 : } // namespace intrp