Phyth v0.1.0
A dimensional safe C++ header-only mechanics and electromagnetics simulation library.
Loading...
Searching...
No Matches
TimeHistory.hpp
Go to the documentation of this file.
1#ifndef PHYTH_TIME_HISTORY_HPP
2#define PHYTH_TIME_HISTORY_HPP
3
5#include "QuantityFuncs.hpp"
7
8#include <vector>
9#include <cmath>
10
11namespace Phyth {
34 template<typename T>
36 public:
37 using ValueType = T;
38
47 void Register(T value) {
48 history_.push_back(value);
49 }
50
66 const Scalar tick = time / Config::dt;
67
68 const auto index = Utils::floor(tick).To<long long>();
69
70 if (index < 0 || index >= static_cast<long long>(history_.size())) {
71 throw std::out_of_range("TimeHistory::GetValueByTime: time out of range");
72 }
73
74 ValueType result = history_[index];
75
76 const Scalar frac = tick - Scalar(static_cast<double>(index));
77
78 // If there is a fractional part and we have a next sample, interpolate
79 if (frac > Config::epsilon) {
80 if (static_cast<size_t>(index + 1) < history_.size()) {
81 result += (history_[index + 1] - result) * frac;
82 }
83 }
84 return result;
85 }
86
105 if (history_.empty()) {
106 throw std::out_of_range("TimeHistory::GetValueByOffset: history is empty");
107 }
108
109 if (offset < 0_s) {
110 throw std::out_of_range("TimeHistory::GetValueByOffset: offset cannot be negative");
111 }
112
113 const Quantity<Second> time = static_cast<double>(history_.size()) * Config::dt - offset;
114 if (time < 0_s) {
115 throw std::out_of_range("TimeHistory::GetValueByOffset: offset exceeds history range");
116 }
117
118 return GetValueByTime(time);
119 }
120
122 [[nodiscard]] size_t GetSize() const noexcept { return history_.size(); }
123
125 [[nodiscard]] bool IsEmpty() const noexcept { return history_.empty(); }
126
127 protected:
128 std::vector<ValueType> history_;
129 };
130}
131
132#endif // PHYTH_TIME_HISTORY_HPP
Time-based history with linear interpolation.
size_t GetSize() const noexcept
Get the number of stored samples.
ValueType GetValueByTime(const Quantity< Second > time) const
Get the value at the specified time (linear interpolation)
bool IsEmpty() const noexcept
Check if the history is empty.
std::vector< ValueType > history_
void Register(T value)
Append a value to the history.
ValueType GetValueByOffset(const Quantity< Second > offset) const
Get the value at a certain time offset before the current time.
double epsilon
Definition Config.hpp:13
Quantity< UnitT > floor(Quantity< UnitT > x)
Floor of a quantity (largest integer <= x)
Quantity< ScalarUnit > Scalar
Definition Quantities.hpp:9
constexpr bool is_unit_v
Definition Unit.hpp:79
Physical quantity with a value and a compile-time unit.
Definition Quantity.hpp:27
constexpr auto To() const
Extract the numeric value as a different type.
Definition Quantity.hpp:77