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
|